API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPButtonBar.j
Go to the documentation of this file.
1 
2 
3 
4 @implementation CPButtonBar : CPView
5 {
6  BOOL _hasResizeControl;
7  BOOL _resizeControlIsLeftAligned;
8  CPArray _buttons;
9 }
10 
11 + (id)plusButton
12 {
13  var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
14  image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
15 
16  [button setBordered:NO];
17  [button setImage:image];
18  [button setImagePosition:CPImageOnly];
19 
20  return button;
21 }
22 
23 + (id)minusButton
24 {
25  var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
26  image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
27 
28  [button setBordered:NO];
29  [button setImage:image];
30  [button setImagePosition:CPImageOnly];
31 
32  return button;
33 }
34 
35 + (id)actionPopupButton
36 {
37  var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
38  image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
39 
40  [button addItemWithTitle:nil];
41  [[button lastItem] setImage:image];
42  [button setImagePosition:CPImageOnly];
43  [button setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:"content-inset"];
44 
45  [button setPullsDown:YES];
46 
47  return button;
48 }
49 
50 + (CPString)defaultThemeClass
51 {
52  return @"button-bar";
53 }
54 
55 + (id)themeAttributes
56 {
57  return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
58  forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
59 }
60 
61 - (id)initWithFrame:(CGRect)aFrame
62 {
63  self = [super initWithFrame:aFrame];
64 
65  if (self)
66  {
67  _buttons = [];
68  [self setNeedsLayout];
69  }
70 
71  return self;
72 }
73 
74 - (void)awakeFromCib
75 {
76  var view = [self superview],
77  subview = self;
78 
79  while (view)
80  {
81  if ([view isKindOfClass:[CPSplitView class]])
82  {
83  var viewIndex = [[view subviews] indexOfObject:subview];
84  [view setButtonBar:self forDividerAtIndex:viewIndex];
85 
86  break;
87  }
88 
89  subview = view;
90  view = [view superview];
91  }
92 }
93 
94 - (void)setButtons:(CPArray)buttons
95 {
96  _buttons = [CPArray arrayWithArray:buttons];
97 
98  for (var i = 0, count = [_buttons count]; i < count; i++)
99  [_buttons[i] setBordered:YES];
100 
101  [self setNeedsLayout];
102 }
103 
104 - (CPArray)buttons
105 {
106  return [CPArray arrayWithArray:_buttons];
107 }
108 
109 - (void)setHasResizeControl:(BOOL)shouldHaveResizeControl
110 {
111  if (_hasResizeControl === shouldHaveResizeControl)
112  return;
113 
114  _hasResizeControl = !!shouldHaveResizeControl;
115  [self setNeedsLayout];
116 }
117 
118 - (BOOL)hasResizeControl
119 {
120  return _hasResizeControl;
121 }
122 
123 - (void)setResizeControlIsLeftAligned:(BOOL)shouldBeLeftAligned
124 {
125  if (_resizeControlIsLeftAligned === shouldBeLeftAligned)
126  return;
127 
128  _resizeControlIsLeftAligned = !!shouldBeLeftAligned;
129  [self setNeedsLayout];
130 }
131 
132 - (BOOL)resizeControlIsLeftAligned
133 {
134  return _resizeControlIsLeftAligned;
135 }
136 
137 - (CGRect)resizeControlFrame
138 {
139  var inset = [self currentValueForThemeAttribute:@"resize-control-inset"],
140  size = [self currentValueForThemeAttribute:@"resize-control-size"],
141  currentSize = [self bounds],
142  leftOrigin = _resizeControlIsLeftAligned ? 0 : currentSize.size.width - size.width - inset.right - inset.left;
143 
144  return CGRectMake(leftOrigin, 0, size.width + inset.left + inset.right, size.height + inset.top + inset.bottom);
145 }
146 
147 - (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
148 {
149  if (aName === "resize-control-view")
150  {
151  var inset = [self currentValueForThemeAttribute:@"resize-control-inset"],
152  size = [self currentValueForThemeAttribute:@"resize-control-size"],
153  currentSize = [self bounds];
154 
155  if (_resizeControlIsLeftAligned)
156  return CGRectMake(inset.left, inset.top, size.width, size.height);
157  else
158  return CGRectMake(currentSize.size.width - size.width - inset.right, inset.top, size.width, size.height);
159  }
160 
161  return [super rectForEphemeralSubviewNamed:aName];
162 }
163 
164 - (CPView)createEphemeralSubviewNamed:(CPString)aName
165 {
166  if (aName === "resize-control-view")
167  return [[CPView alloc] initWithFrame:CGRectMakeZero()];
168 
169  return [super createEphemeralSubviewNamed:aName];
170 }
171 
172 - (void)layoutSubviews
173 {
174  [self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
175 
176  var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
177  highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
178  disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled],
179  textColor = [self valueForThemeAttribute:@"button-text-color" inState:CPThemeStateNormal];
180 
181  var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
182  count = [buttonsNotHidden count];
183 
184  while (count--)
185  if ([buttonsNotHidden[count] isHidden])
186  [buttonsNotHidden removeObject:buttonsNotHidden[count]];
187 
188  var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
189  bounds = [self bounds],
190  height = CGRectGetHeight(bounds) - 1,
191  frameWidth = CGRectGetWidth(bounds),
192  resizeRect = _hasResizeControl ? [self rectForEphemeralSubviewNamed:"resize-control-view"] : CGRectMakeZero(),
193  resizeWidth = CGRectGetWidth(resizeRect),
194  availableWidth = frameWidth - resizeWidth - 1;
195 
196  for (var i = 0, count = [buttonsNotHidden count]; i < count; i++)
197  {
198  var button = buttonsNotHidden[i],
199  width = CGRectGetWidth([button frame]);
200 
201  if (availableWidth > width)
202  availableWidth -= width;
203  else
204  break;
205 
206  if (_resizeControlIsLeftAligned)
207  {
208  [button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)];
209  currentButtonOffset -= width - 1;
210  }
211  else
212  {
213  [button setFrame:CGRectMake(currentButtonOffset, 1, width, height)];
214  currentButtonOffset += width - 1;
215  }
216 
217  [button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered];
218  [button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered];
219  [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered];
220  [button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
221 
222  // FIXME shouldn't need this
223  [button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
224  [button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
225  [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
226 
227  [self addSubview:button];
228  }
229 
230  if (_hasResizeControl)
231  {
232  var resizeControlView = [self layoutEphemeralSubviewNamed:@"resize-control-view"
233  positioned:CPWindowAbove
235 
236  [resizeControlView setAutoresizingMask: _resizeControlIsLeftAligned ? CPViewMaxXMargin : CPViewMinXMargin];
237  [resizeControlView setBackgroundColor:[self currentValueForThemeAttribute:@"resize-control-color"]];
238  }
239 }
240 
241 - (void)setFrameSize:(CGSize)aSize
242 {
243  [super setFrameSize:aSize];
244  [self setNeedsLayout];
245 }
246 
247 @end
248 
249 var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
250  CPButtonBarResizeControlIsLeftAlignedKey = @"CPButtonBarResizeControlIsLeftAlignedKey",
251  CPButtonBarButtonsKey = @"CPButtonBarButtonsKey";
252 
253 @implementation CPButtonBar (CPCoding)
254 
255 - (void)encodeWithCoder:(CPCoder)aCoder
256 {
257  [super encodeWithCoder:aCoder];
258 
259  [aCoder encodeBool:_hasResizeControl forKey:CPButtonBarHasResizeControlKey];
260  [aCoder encodeBool:_resizeControlIsLeftAligned forKey:CPButtonBarResizeControlIsLeftAlignedKey];
261  [aCoder encodeObject:_buttons forKey:CPButtonBarButtonsKey];
262 }
263 
264 - (id)initWithCoder:(CPCoder)aCoder
265 {
266  if (self = [super initWithCoder:aCoder])
267  {
268  _buttons = [aCoder decodeObjectForKey:CPButtonBarButtonsKey] || [];
269  _hasResizeControl = [aCoder decodeBoolForKey:CPButtonBarHasResizeControlKey];
270  _resizeControlIsLeftAligned = [aCoder decodeBoolForKey:CPButtonBarResizeControlIsLeftAlignedKey];
271  }
272 
273  return self;
274 }
275 
276 @end