Remove legacy code

This commit is contained in:
Allan Odgaard
2012-09-15 15:11:41 +02:00
parent 84104c8d9b
commit 2d2e329cd8
5 changed files with 0 additions and 871 deletions

View File

@@ -1,22 +0,0 @@
#include "box.h"
struct OakResizeInfo
{
int width, height;
enum { kTopLeft, kTopRight, kBottomLeft, kBottomRight } corner;
enum { kWidth, kHeight } adjustable;
};
@interface OakLayoutView : NSView
{
box_t* box;
std::map<NSView*, box_t*> views;
std::multimap<NSView*, OakResizeInfo> resize_info;
}
- (void)addView:(NSView*)aView;
- (void)addView:(NSView*)aView atEdge:(NSRectEdge)anEdge ofView:(NSView*)otherView;
- (void)removeView:(NSView*)aView;
- (void)setLocked:(BOOL)flag forView:(NSView*)aView;
- (void)addResizeInfo:(OakResizeInfo)info forView:(NSView*)aView;
- (void)removeResizeInfoForView:(NSView*)aView;
@end

View File

@@ -1,342 +0,0 @@
#import "OakLayoutView.h"
#import <oak/CocoaSTL.h>
#import <oak/debug.h>
OAK_DEBUG_VAR(OakLayoutView);
enum edge_t { kLeftEdge, kTopEdge, kRightEdge, kBottomEdge };
struct OakResizeHandle
{
box_t* box;
edge_t edge;
int distance;
explicit operator bool () const { return box; }
};
static void add_cursors (box_t* box, NSView* view)
{
if(!box || box->children().empty())
return;
std::vector<box_t*> const& children = box->children();
for(size_t i = 0; i < children.size() - 1; ++i)
{
rect_t prev = children[i]->bounds(), next = children[i+1]->bounds();
rect_t r = box->horizontal() ? rect_t(prev.x1 - 2, next.x0 + 2, prev.y0, prev.y1) : rect_t(prev.x0, prev.x1, prev.y1 - 2, next.y0 + 2);
[view addCursorRect:NSMakeRect(r.x0, r.y0, r.width(), r.height()) cursor:box->horizontal() ? [NSCursor resizeLeftRightCursor] : [NSCursor resizeUpDownCursor]];
}
iterate(child, children)
add_cursors(*child, view);
}
static void draw_thumbs (box_t* box, NSView* view)
{
if(!box || box->children().empty())
return;
std::vector<box_t*> const& children = box->children();
for(size_t i = 0; i < children.size() - 1; ++i)
{
rect_t prev = children[i]->bounds(), next = children[i+1]->bounds();
rect_t r = box->horizontal() ? rect_t(prev.x1, next.x0, prev.y0, prev.y1) : rect_t(prev.x0, prev.x1, prev.y1, next.y0);
NSRectFill(NSMakeRect(r.x0, r.y0, r.width(), r.height()));
}
iterate(child, children)
draw_thumbs(*child, view);
}
static OakResizeHandle find_resize_info (box_t* box, int x, int y)
{
if(!box || box->children().empty())
return (OakResizeHandle){ NULL };
std::vector<box_t*> const& children = box->children();
for(ssize_t i = 0; i < children.size() - 1; ++i)
{
rect_t prev = children[i]->bounds(), next = children[i+1]->bounds();
rect_t r = box->horizontal() ? rect_t(prev.x1 - 2, next.x0 + 2, prev.y0, prev.y1) : rect_t(prev.x0, prev.x1, prev.y1 - 2, next.y0 + 2);
if(r.contains(x, y))
return (OakResizeHandle){ children[i], box->horizontal() ? kRightEdge : kBottomEdge, box->horizontal() ? prev.x1 - x : prev.y1 - y };
}
iterate(child, children)
{
if(OakResizeHandle res = find_resize_info(*child, x, y))
return res;
}
return (OakResizeHandle){ NULL };
}
static bool horizontal_edge (NSRectEdge edge)
{
return edge == NSMinXEdge || edge == NSMaxXEdge;
}
static box_t* add_box (box_t* newBox, box_t* container, NSRectEdge edge, box_t const* otherBox)
{
if(!container)
return newBox;
if(otherBox && otherBox != container)
{
std::vector<box_t*>& children = container->children();
iterate(child, children)
*child = add_box(newBox, *child, edge, otherBox);
return container;
}
else
{
if(container->children().empty() || container->horizontal() != horizontal_edge(edge))
{
box_t* wrapper = new box_t(horizontal_edge(edge) ? 0 : container->width(), horizontal_edge(edge) ? container->height() : 0, 0, 0, false, horizontal_edge(edge));
wrapper->push_back(container);
container = wrapper;
}
rect_t r = container->bounds();
switch(edge)
{
case NSMinXEdge: r.x0 += newBox->width() + kViewSpacing; newBox->set_height(container->height()); break;
case NSMinYEdge: r.y0 += newBox->height() + kViewSpacing; newBox->set_width(container->width()); break;
case NSMaxXEdge: r.x1 -= newBox->width() + kViewSpacing; newBox->set_height(container->height()); break;
case NSMaxYEdge: r.y1 -= newBox->height() + kViewSpacing; newBox->set_width(container->width()); break;
}
container->set_size(r);
if(edge == NSMinXEdge || edge == NSMinYEdge)
container->push_front(newBox);
else container->push_back(newBox);
container->freeze_layout();
}
return container;
}
@implementation OakLayoutView
- (void)repositionSubviews
{
for(NSView* view in [self subviews])
{
std::map<NSView*, box_t*>::const_iterator it = views.find(view);
ASSERT(it != views.end());
[view setFrame:NSMakeRect(it->second->x0(), it->second->y0(), it->second->width(), it->second->height())];
}
}
- (void)setLocked:(BOOL)flag forView:(NSView*)aView
{
std::map<NSView*, box_t*>::iterator it = views.find(aView);
ASSERT(it != views.end());
it->second->set_locked(flag);
}
- (void)addView:(NSView*)aView atEdge:(NSRectEdge)anEdge ofView:(NSView*)otherView
{
std::map<NSView*, box_t*>::const_iterator it = views.find(otherView);
box_t const* otherBox = it != views.end() ? it->second : NULL;
box_t* newBox = new box_t(NSWidth(aView.frame), NSHeight(aView.frame));
box = add_box(newBox, box, anEdge, otherBox);
box->set_size(rect_t(0, NSWidth(self.frame), 0, NSHeight(self.frame)));
box->freeze_layout();
views.insert(std::make_pair(aView, newBox));
[self addSubview:aView];
[self repositionSubviews];
[[self window] invalidateCursorRectsForView:self];
// [self setNeedsDisplay:YES];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidResize:) name:NSViewFrameDidChangeNotification object:aView];
}
- (void)removeView:(NSView*)aView
{
std::map<NSView*, box_t*>::iterator it = views.find(aView);
ASSERT(it != views.end());
box = box->erase(it->second);
box->freeze_layout();
views.erase(it);
[self removeResizeInfoForView:aView];
[aView removeFromSuperview];
[self repositionSubviews];
[[self window] invalidateCursorRectsForView:self];
}
- (void)resetCursorRects
{
add_cursors(box, self);
iterate(pair, resize_info)
{
NSRect r = pair->first.frame;
int x0, y0;
switch(pair->second.corner)
{
case OakResizeInfo::kTopLeft: x0 = NSMinX(r); y0 = NSMinY(r); break;
case OakResizeInfo::kTopRight: x0 = NSMaxX(r); y0 = NSMinY(r); break;
case OakResizeInfo::kBottomLeft: x0 = NSMinX(r); y0 = NSMaxY(r); break;
case OakResizeInfo::kBottomRight: x0 = NSMaxX(r); y0 = NSMaxY(r); break;
}
int x1 = x0 + pair->second.width;
int y1 = y0 + pair->second.height;
rect_t rect(std::min(x0, x1), std::max(x0, x1), std::min(y0, y1), std::max(y0, y1));
[self addCursorRect:NSMakeRect(rect.x0, rect.y0, rect.width(), rect.height()) cursor:pair->second.adjustable == OakResizeInfo::kWidth ? [NSCursor resizeLeftRightCursor] : [NSCursor resizeUpDownCursor]];
}
}
- (void)resizeSubviewsWithOldSize:(NSSize)oldSize
{
int w = std::max<int>(NSWidth(self.frame), box->min_width());
int h = std::max<int>(NSHeight(self.frame), box->min_height());
box->set_size(rect_t(0, w, 0, h));
[self repositionSubviews];
}
- (BOOL)isFlipped
{
return YES;
}
- (BOOL)isOpaque
{
return YES;
}
- (void)drawRect:(NSRect)aRect
{
[[NSColor lightGrayColor] set];
draw_thumbs(box, self);
}
- (OakResizeHandle)findResizeHandle:(NSPoint)pos
{
int x = (int)round(pos.x), y = (int)round(pos.y);
if(OakResizeHandle res = find_resize_info(box, x, y))
return res;
iterate(pair, resize_info)
{
NSRect r = pair->first.frame;
int x0, y0;
edge_t edge = kLeftEdge; // avoid compiler warning
switch(pair->second.corner)
{
case OakResizeInfo::kTopLeft: x0 = NSMinX(r); y0 = NSMinY(r); edge = pair->second.adjustable == OakResizeInfo::kWidth ? kLeftEdge : kTopEdge; break;
case OakResizeInfo::kTopRight: x0 = NSMaxX(r); y0 = NSMinY(r); edge = pair->second.adjustable == OakResizeInfo::kWidth ? kRightEdge : kTopEdge; break;
case OakResizeInfo::kBottomLeft: x0 = NSMinX(r); y0 = NSMaxY(r); edge = pair->second.adjustable == OakResizeInfo::kWidth ? kLeftEdge : kBottomEdge; break;
case OakResizeInfo::kBottomRight: x0 = NSMaxX(r); y0 = NSMaxY(r); edge = pair->second.adjustable == OakResizeInfo::kWidth ? kRightEdge : kBottomEdge; break;
}
int x1 = x0 + pair->second.width;
int y1 = y0 + pair->second.height;
if(rect_t(std::min(x0, x1), std::max(x0, x1), std::min(y0, y1), std::max(y0, y1)).contains(x, y))
{
int distance = 0;
switch(edge)
{
case kLeftEdge: distance = x - std::min(x0, x1); break;
case kRightEdge: distance = std::max(x0, x1) - x; break;
case kTopEdge: distance = y - std::min(y0, y1); break;
case kBottomEdge: distance = std::max(y0, y1) - y; break;
}
return (OakResizeHandle){ views[pair->first], edge, distance };
}
}
return (OakResizeHandle){ NULL };
}
- (void)mouseDown:(NSEvent*)anEvent
{
NSPoint pos = [self convertPoint:[anEvent locationInWindow] fromView:nil];
D(DBF_OakLayoutView, bug("%.0f, %.0f\n", pos.x, pos.y););
if(OakResizeHandle handle = [self findResizeHandle:pos])
{
box_t* clicked = handle.box;
edge_t edge = handle.edge;
int distance = handle.distance;
box->freeze_layout();
D(DBF_OakLayoutView, bug("start resize tracking of box %s\n", to_s(clicked->bounds()).c_str()););
while((anEvent = [[self window] nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES]) && [anEvent type] != NSLeftMouseUp)
{
rect_t bounds = clicked->bounds();
pos = [self convertPoint:[anEvent locationInWindow] fromView:nil];
switch(edge)
{
case kLeftEdge: bounds.x0 = pos.x - distance; break;
case kRightEdge: bounds.x1 = pos.x + distance; break;
case kTopEdge: bounds.y0 = pos.y - distance; break;
case kBottomEdge: bounds.y1 = pos.y + distance; break;
}
box->resize(clicked, bounds);
box->freeze_layout();
[self repositionSubviews];
[[self window] invalidateCursorRectsForView:self];
[self setNeedsDisplay:YES];
}
D(DBF_OakLayoutView, bug("stop resize tracking\n"););
[[self window] discardEventsMatchingMask:NSAnyEventMask beforeEvent:anEvent];
}
else
{
return [super mouseDown:anEvent];
}
}
- (void)addView:(NSView*)aView
{
[self addView:aView atEdge:NSMaxYEdge ofView:nil];
}
- (void)addResizeInfo:(OakResizeInfo)info forView:(NSView*)aView
{
resize_info.insert(std::make_pair(aView, info));
}
- (void)removeResizeInfoForView:(NSView*)aView
{
resize_info.erase(resize_info.lower_bound(aView), resize_info.upper_bound(aView));
}
- (void)performClose:(id)sender
{
NSView* view = (NSView*)[[self window] firstResponder];
if(![view isKindOfClass:[NSView class]])
return;
while(view && [view superview] != self)
view = [view superview];
if(view)
[NSApp sendAction:@selector(performCloseSplit:) to:nil from:view];
else [[self nextResponder] tryToPerform:_cmd with:sender];
}
- (NSView*)hitTest:(NSPoint)aPoint
{
D(DBF_OakLayoutView, bug("%s\n", [NSStringFromPoint(aPoint) UTF8String]););
if([self findResizeHandle:[self convertPoint:aPoint fromView:[self superview]]])
{
D(DBF_OakLayoutView, bug("found resize handle\n"););
return self;
}
D(DBF_OakLayoutView, bug("call super\n"););
ASSERT([super respondsToSelector:@selector(hitTest:)]);
return [super hitTest:aPoint];
}
@end

View File

@@ -1,353 +0,0 @@
#include "box.h"
#include <oak/debug.h>
int kViewSpacing = 1;
box_t::box_t (int width, int height, int minWidth, int minHeight, bool locked, bool horizontal) : _bounds(0, width, 0, height), _min_width(minWidth), _min_height(minHeight), _ideal_width(width), _ideal_height(height), _locked(locked), _horizontal_layout(horizontal)
{
ASSERT_LE(_min_width, _bounds.width());
ASSERT_LE(_min_height, _bounds.height());
}
void box_t::push_front (box_t* box)
{
ASSERT_LE(box->min_width(), box->width());
ASSERT_LE(box->min_height(), box->height());
rect_t bounds = _bounds;
if(_horizontal_layout)
{
bounds.move_to(_bounds.x0 - box->width() - kViewSpacing, _bounds.y0);
bounds.set_width(box->width());
bounds.set_height(std::max(height(), box->min_height()));
box->set_size(bounds);
_bounds.x0 = box->x0();
}
else
{
bounds.move_to(_bounds.x0, _bounds.y0 - box->height() - kViewSpacing);
bounds.set_width(std::max(width(), box->min_width()));
bounds.set_height(box->height());
box->set_size(bounds);
_bounds.y0 = box->y0();
}
_children.insert(_children.begin(), box);
}
void box_t::push_back (box_t* box)
{
ASSERT_LE(box->min_width(), box->width());
ASSERT_LE(box->min_height(), box->height());
rect_t bounds = _bounds;
if(_horizontal_layout)
{
bounds.move_to(_bounds.x1 + kViewSpacing, _bounds.y0);
bounds.set_width(box->width());
bounds.set_height(std::max(height(), box->min_height()));
box->set_size(bounds);
_bounds.set_width(_bounds.width() + kViewSpacing + box->width());
}
else
{
bounds.move_to(_bounds.x0, _bounds.y1 + kViewSpacing);
bounds.set_width(std::max(width(), box->min_width()));
bounds.set_height(box->height());
box->set_size(bounds);
_bounds.set_height(_bounds.height() + kViewSpacing + box->height());
}
_children.push_back(box);
}
box_t* box_t::erase (box_t* box)
{
if(box == this)
{
delete this;
return NULL;
}
if(_children.empty())
return this;
std::vector<box_t*> newChildren;
iterate(child, _children)
*child = (*child)->erase(box);
for(size_t i = 0; i < _children.size(); ++i)
{
if(_children[i] == NULL)
{
if(_horizontal_layout)
{
if(i != 0 && i+1 != _children.size())
{
rect_t left = _children[i-1]->bounds(), right = _children[i+1]->bounds();
int x = (left.x1 + right.x0) / 2;
left.x1 = x;
right.x0 = x + kViewSpacing;
_children[i-1]->set_size(left);
_children[i+1]->set_size(right);
}
else if(i != 0)
{
rect_t left = _children[i-1]->bounds();
left.x1 = _bounds.x1;
_children[i-1]->set_size(left);
}
else if(i+1 != _children.size())
{
rect_t right = _children[i+1]->bounds();
right.x0 = _bounds.x0;
_children[i+1]->set_size(right);
}
}
else
{
if(i != 0 && i+1 != _children.size())
{
rect_t left = _children[i-1]->bounds(), right = _children[i+1]->bounds();
int y = (left.y1 + right.y0) / 2;
left.y1 = y;
right.y0 = y + kViewSpacing;
_children[i-1]->set_size(left);
_children[i+1]->set_size(right);
}
else if(i != 0)
{
rect_t left = _children[i-1]->bounds();
left.y1 = _bounds.y1;
_children[i-1]->set_size(left);
}
else if(i+1 != _children.size())
{
rect_t right = _children[i+1]->bounds();
right.y0 = _bounds.y0;
_children[i+1]->set_size(right);
}
}
_children.erase(_children.begin() + i);
break;
}
}
if(_children.empty())
{
delete this;
return NULL;
}
else if(_children.size() == 1)
{
box_t* res = _children.back();
delete this;
return res;
}
return this;
}
box_t* box_t::find (int x, int y)
{
if(!_bounds.contains(x, y))
return NULL;
iterate(child, _children)
{
if(box_t* res = (*child)->find(x, y))
return res;
}
return this;
}
struct size_info_t
{
size_info_t (size_t minSize, size_t extraSize, bool locked) : size(minSize), extra_size(extraSize), locked(locked) { }
size_t size;
size_t extra_size;
bool locked;
};
static void layout (std::vector<size_info_t>& sizes, int size)
{
int idealWidth = 0;
int lockedWidth = 0;
int flexibleWidth = 0;
iterate(it, sizes)
{
idealWidth += it->extra_size;
if(it->locked)
lockedWidth += it->extra_size;
else flexibleWidth += it->extra_size;
size -= it->size;
}
if(size >= lockedWidth)
{
size -= lockedWidth;
int counter = 0;
iterate(it, sizes)
{
if(it->locked)
{
it->size += it->extra_size;
}
else
{
it->size += size * (counter + it->extra_size) / flexibleWidth - size * counter / flexibleWidth;
counter += it->extra_size;
}
}
ASSERT_EQ(counter, flexibleWidth);
}
else
{
int counter = 0;
iterate(it, sizes)
{
if(it->locked)
{
it->size += size * (counter + it->extra_size) / lockedWidth - size * counter / lockedWidth;
counter += it->extra_size;
}
}
ASSERT_EQ(counter, lockedWidth);
}
}
void box_t::set_size (rect_t const& newBounds)
{
ASSERT_GE(newBounds.width(), min_width());
ASSERT_GE(newBounds.height(), min_height());
if(_children.empty())
{
_bounds = newBounds;
return;
}
std::vector<size_info_t> sizes;
if(_horizontal_layout)
{
iterate(child, _children)
sizes.push_back(size_info_t((*child)->min_width(), (*child)->_ideal_width - (*child)->min_width(), (*child)->locked()));
layout(sizes, newBounds.width() - kViewSpacing * (_children.size() - 1));
int x = newBounds.x0;
for(size_t i = 0; i < _children.size(); ++i)
{
_children[i]->set_size(rect_t(x, x + sizes[i].size, newBounds.y0, newBounds.y1));
x += sizes[i].size + kViewSpacing;
}
}
else
{
iterate(child, _children)
sizes.push_back(size_info_t((*child)->min_height(), (*child)->_ideal_height - (*child)->min_height(), (*child)->locked()));
layout(sizes, newBounds.height() - kViewSpacing * (_children.size() - 1));
int y = newBounds.y0;
for(size_t i = 0; i < _children.size(); ++i)
{
_children[i]->set_size(rect_t(newBounds.x0, newBounds.x1, y, y + sizes[i].size));
y += sizes[i].size + kViewSpacing;
}
}
_bounds = newBounds;
}
void box_t::freeze_layout ()
{
iterate(child, _children)
(*child)->freeze_layout();
_ideal_width = width();
_ideal_height = height();
}
bool box_t::resize (box_t* box, rect_t const& newRect)
{
if(box == this)
return _bounds == newRect ? false : (set_size(newRect), true);
for(size_t i = 0; i < _children.size(); ++i)
{
rect_t oldRect = _children[i]->bounds();
if(_children[i]->resize(box, newRect))
{
rect_t newRect = _children[i]->bounds();
if(_horizontal_layout)
{
if(oldRect.height() != newRect.height())
{
iterate(child, _children)
{
rect_t bounds = (*child)->bounds();
bounds.y0 = newRect.y0;
bounds.y1 = newRect.y1;
(*child)->set_size(bounds);
}
}
else
{
if(0 < i && oldRect.x0 != newRect.x0)
{
rect_t bounds = _children[i-1]->bounds();
bounds.x1 = newRect.x0 - kViewSpacing;
_children[i-1]->set_size(bounds);
}
if(i+1 < _children.size() && oldRect.x1 != newRect.x1)
{
rect_t bounds = _children[i+1]->bounds();
bounds.x0 = newRect.x1 + kViewSpacing;
_children[i+1]->set_size(bounds);
}
}
}
else
{
if(oldRect.width() != newRect.width())
{
iterate(child, _children)
{
rect_t bounds = (*child)->bounds();
bounds.x0 = newRect.x0;
bounds.x1 = newRect.x1;
(*child)->set_size(bounds);
}
}
else
{
if(0 < i && oldRect.y0 != newRect.y0)
{
rect_t bounds = _children[i-1]->bounds();
bounds.y1 = newRect.y0 - kViewSpacing;
_children[i-1]->set_size(bounds);
}
if(i+1 < _children.size() && oldRect.y1 != newRect.y1)
{
rect_t bounds = _children[i+1]->bounds();
bounds.y0 = newRect.y1 + kViewSpacing;
_children[i+1]->set_size(bounds);
}
}
}
rect_t oldBounds = _bounds;
_bounds = rect_t(INT_MAX, INT_MIN, INT_MAX, INT_MIN);
iterate(child, _children)
{
_bounds.x0 = std::min(_bounds.x0, (*child)->x0());
_bounds.x1 = std::max(_bounds.x1, (*child)->x1());
_bounds.y0 = std::min(_bounds.y0, (*child)->y0());
_bounds.y1 = std::max(_bounds.y1, (*child)->y1());
}
return _bounds != oldBounds;
}
}
return false;
}

View File

@@ -1,82 +0,0 @@
#ifndef BOX_H_LQ7DU4L2
#define BOX_H_LQ7DU4L2
#include <oak/oak.h>
#include <text/format.h>
struct rect_t
{
rect_t (int x0, int x1, int y0, int y1) : x0(x0), x1(x1), y0(y0), y1(y1) { }
int width () const { return x1 - x0; }
int height () const { return y1 - y0; }
void set_width (int width) { x1 = x0 + width; }
void set_height (int height) { y1 = y0 + height; }
void move_to (int x, int y) { *this = rect_t(x, x + width(), y, y + height()); }
bool contains (int x, int y) const { return oak::cap(x0, x, x1-1) == x && oak::cap(y0, y, y1-1) == y; }
bool operator== (rect_t const& rhs) const { return x0 == rhs.x0 && x1 == rhs.x1 && y0 == rhs.y0 && y1 == rhs.y1; }
bool operator!= (rect_t const& rhs) const { return x0 != rhs.x0 || x1 != rhs.x1 || y0 != rhs.y0 || y1 != rhs.y1; }
int x0, x1, y0, y1;
};
inline std::string to_s (rect_t const& r)
{
return text::format("%d, %d — %d × %d", r.x0, r.y0, r.width(), r.height());
}
extern int kViewSpacing;
struct box_t
{
box_t (int width = 0, int height = 0, int minWidth = 0, int minHeight = 0, bool locked = false, bool horizontal = true);
int x0 () const { return _bounds.x0; }
int y0 () const { return _bounds.y0; }
int x1 () const { return _bounds.x1; }
int y1 () const { return _bounds.y1; }
int width () const { return _bounds.width(); }
int height () const { return _bounds.height(); }
void set_width (int aWidth) { set_size(rect_t(x0(), x0() + aWidth, y0(), y1())); }
void set_height (int aHeight) { set_size(rect_t(x0(), x1(), y0(), y0() + aHeight)); }
rect_t const& bounds () const { return _bounds; }
bool locked () const { return _locked; }
void set_locked (bool flag) { _locked = flag; }
bool horizontal () const { return _horizontal_layout; }
std::vector<box_t*>& children () { return _children; }
std::vector<box_t*> const& children () const { return _children; }
int min_width () const
{
int res = 0;
iterate(child, _children)
res = _horizontal_layout ? res + (*child)->min_width() : std::max(res, (*child)->min_width());
return std::max(res, _min_width);
}
int min_height () const
{
int res = 0;
iterate(child, _children)
res = !_horizontal_layout ? res + (*child)->min_height() : std::max(res, (*child)->min_height());
return std::max(res, _min_height);
}
void set_size (rect_t const& newBounds);
bool resize (box_t* box, rect_t const& newRect);
void freeze_layout ();
box_t* find (int x, int y);
void push_front (box_t* box);
void push_back (box_t* box);
box_t* erase (box_t* box);
private:
rect_t _bounds;
int _min_width, _min_height;
int _ideal_width, _ideal_height;
std::vector<box_t*> _children;
bool _locked, _horizontal_layout;
};
#endif /* end of include guard: BOX_H_LQ7DU4L2 */

View File

@@ -1,72 +0,0 @@
#import <OakAppKit/OakLayoutView.h>
@interface MyLayoutView : OakLayoutView
@end
@implementation MyLayoutView
- (NSTextField*)createView:(NSString*)label
{
NSTextField* res = [[[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 200)] autorelease];
[res setEditable:NO];
[res setSelectable:NO];
// [res setBezeled:NO];
// [res setBordered:NO];
// [res setDrawsBackground:NO];
// [res setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[res setStringValue:label];
return res;
}
- (NSRectEdge)edgeOfView:(NSView*)aView containingPoint:(NSPoint)aPoint
{
NSSize size = [aView frame].size;
NSRectEdge edge = NSMinYEdge;
if(aPoint.y < size.height/4)
edge = NSMinYEdge;
else if(aPoint.y > 3*size.height/4)
edge = NSMaxYEdge;
else if(aPoint.x < size.width/4)
edge = NSMinXEdge;
else if(aPoint.x > 3*size.width/4)
edge = NSMaxXEdge;
return edge;
}
- (void)mouseDown:(NSEvent*)anEvent
{
static NSInteger i = 0;
NSPoint click = [anEvent locationInWindow];
NSUInteger flags = [anEvent modifierFlags];
if(flags & NSShiftKeyMask)
{
NSView* newView = [self createView:[NSString stringWithFormat:@"View %ld", ++i]];
NSRectEdge edge = [self edgeOfView:self containingPoint:[self convertPoint:click fromView:nil]];
[self addView:newView atEdge:edge ofView:nil];
return;
}
NSView* clickedView = [self hitTest:[[self superview] convertPoint:click fromView:nil]];
if(clickedView)
{
NSView* newView = [self createView:[NSString stringWithFormat:@"View %ld", ++i]];
NSRectEdge edge = [self edgeOfView:clickedView containingPoint:[clickedView convertPoint:click fromView:nil]];
[self addView:newView atEdge:edge ofView:clickedView];
}
}
@end
class LayoutViewTests : public CxxTest::TestSuite
{
public:
void test_layout_view ()
{
NSAutoreleasePool* pool = [NSAutoreleasePool new];
MyLayoutView* layoutView = [[[MyLayoutView alloc] initWithFrame:NSMakeRect(0, 0, 400, 60)] autorelease];
[layoutView addView:[layoutView createView:@"Root"]];
OakSetupApplicationWithView(layoutView, "layout_view");
[pool drain];
}
};