forked from MacRuby/MacRuby
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimpleLayoutView.rb
More file actions
126 lines (112 loc) · 3.79 KB
/
Copy pathSimpleLayoutView.rb
File metadata and controls
126 lines (112 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
class SimpleLayoutView < NSView
attr_accessor :boxColorField
# Default separation between items, and default size of added subviews
SEPARATION = 10.0
BOXWIDTH = 80.0
BOXHEIGHT = 80.0
# Layout styles
ColumnLayout = 0
RowLayout = 1
GridLayout = 2
# By default NSColorPanel does not show an alpha (opacity) slider; enable it
def awakeFromNib
NSColorPanel.sharedColorPanel.showsAlpha = true
end
# Start off in column mode
attr_reader :layoutStyle
def initWithFrame frame
if super
@layoutStyle = ColumnLayout
end
return self
end
def setLayoutStyle style
if @layoutStyle != style
@layoutStyle = style
layout!
end
end
# This method returns a rect that is integral in base coordinates
def integralRect rect
convertRectFromBase NSIntegralRect(convertRectToBase(rect))
end
# This method simply computes the new layout, and calls setFrame: on all
# subview with their locations. Since the calls are made to the subviews'
# animators, the subview animate to their new locations.
def layout!
case @layoutStyle
when ColumnLayout
# Starting point: center bottom of view.
point = NSPoint.new(bounds.size.width / 2.0, 0.0)
subviews.each do |view|
# Centered horizontally, stacked higher.
frame = NSRect.new(NSPoint.new(point.x - BOXWIDTH / 2.0, point.y),
NSSize.new(BOXWIDTH, BOXHEIGHT))
view.animator.frame = integralRect(frame)
# Next view location; we're stacking higher.
point.y += frame.size.width + SEPARATION
end
when RowLayout
# Starting point: center left edge of view.
point = NSPoint.new(0.0, bounds.size.height / 2.0)
subviews.each do |view|
# Centered vertically, stacked left to right.
frame = NSRect.new(NSPoint.new(point.x, point.y - BOXHEIGHT / 2.0),
NSSize.new(BOXWIDTH, BOXHEIGHT))
view.animator.frame = integralRect(frame)
# Next view location.
point.x += frame.size.width + SEPARATION
end
when GridLayout
# Put the views in a roughly square grid.
viewsPerSide = Math.sqrt(subviews.size).ceil
i = 0
# Starting at the bottom left corner.
point = NSZeroPoint.dup
subviews.each do |view|
frame = NSRect.new(NSPoint.new(point.x, point.y),
NSSize.new(BOXWIDTH, BOXHEIGHT))
view.animator.frame = integralRect(frame)
# Stack them horizontally.
point.x += BOXWIDTH + SEPARATION
# And if we have enough on this row, move up to the next.
if (i += 1) % viewsPerSide == 0
point.x = 0
point.y += BOXHEIGHT + SEPARATION
end
end
end
end
# Changing frame (which is what happens when the window is resized) should
# cause relayout.
def setFrameSize frame
super
layout!
end
# Create a new view to be added/animated. Any kind of view can be added here,
# we go for simple colored box using the Leopard "custom" box type.
def viewToBeAdded
frame = NSRect.new(NSZeroPoint, NSSize.new(BOXWIDTH, BOXHEIGHT))
box = NSBox.alloc.initWithFrame frame
box.boxType = NSBoxCustom
box.borderType = NSLineBorder
box.titlePosition = NSNoTitle
box.fillColor = @boxColorField.color
return box
end
# Action methods to add/remove boxes, giving us something to animate.
# Note that we cause a relayout here; a better design is to relayout in the
# view automatically on addition/removal of subviews.
def addABox(sender)
addSubview viewToBeAdded
layout!
end
def removeLastBox(sender)
subviews.lastObject.removeFromSuperview
layout!
end
# Action method to change layout style.
def changeLayout(sender)
setLayoutStyle sender.selectedTag
end
end