1 #ifdef BUILDING_ECERE_COM
2 namespace gui::controls;
7 public import static "ecere"
13 public class RepButton : Button
20 property Seconds delay { set { timer2.delay = value; } }
21 property Seconds delay0 { set { timer.delay = value; } }
23 bool OnKeyHit(Key key, unichar ch)
28 bool OnKeyDown(Key key, unichar ch)
32 NotifyPushed(master, this, 0,0, key.modifiers);
38 bool OnKeyUp(Key key, unichar ch)
42 NotifyReleased(master, this, 0,0, key.modifiers);
48 bool NotifyPushed(RepButton button, int x, int y, Modifiers mods)
50 button.pressing = true;
51 button.NotifyClicked(this, button, x, y, mods);
56 bool NotifyMouseLeave(RepButton button, Modifiers mods)
63 bool NotifyReleased(RepButton button, int x, int y, Modifiers mods)
65 button.pressing = false;
66 button.NotifyMouseLeave(this, button, mods);
70 bool NotifyMouseOver(RepButton button, int x, int y, Modifiers mods)
73 button.timer2.Start();
85 timer2.DelayExpired(this);
94 NotifyClicked(master, this, 0, 0, 0);
100 static define stackerScrolling = 16;
102 public enum FlipStackerSpringMode { none, previous, next };
104 public class FlipStacker : Window
108 FlipStackerSpringMode spring;
111 public class Stacker : Window
115 property ScrollDirection direction { set { direction = value; } get { return direction; } };
116 property int gap { set { gap = value; } get { return gap; } };
117 property bool reverse { set { reverse = value; } get { return reverse; } };
119 property bool scrollable
123 if(value != scrollable)
126 // how to recall these?
127 //GetDecorationsSize(...);
128 //SetWindowArea(...);
129 OnResize(clientSize.w, clientSize.h);
132 get { return scrollable; }
135 property Array<Window> controls { get { return controls; } };
138 ScrollDirection direction;
141 Array<Window> controls { };
145 this, visible = false, bevelOver = true, nonClient = true, keyRepeat = true, opacity = 0;
147 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
149 if(direction == horizontal)
151 scroll.x -= stackerScrolling;
152 if(scroll.x == 0) { left.disabled = true; left.OnLeftButtonUp(-1,0,0); }
156 scroll.y -= stackerScrolling;
157 if(scroll.y == 0) { left.disabled = true; left.OnLeftButtonUp(-1,0,0); }
159 right.disabled = false;
160 size = size; // TRIGGER SCROLLING UPDATE (Currently required since we aren't using Window scrollbars)
166 this, visible = false, bevelOver = true, nonClient = true, keyRepeat = true, opacity = 0;
168 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
170 if(direction == horizontal)
172 scroll.x += stackerScrolling;
173 if(scroll.x + clientSize.w >= scrollArea.w) { right.disabled = true; right.OnLeftButtonUp(-1,0,0); }
177 scroll.y += stackerScrolling;
178 if(scroll.y + clientSize.h >= scrollArea.h) { right.disabled = true; right.OnLeftButtonUp(-1,0,0); }
180 left.disabled = false;
181 size = size; // TRIGGER SCROLLING UPDATE (Currently required since we aren't using Window scrollbars)
186 void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h)
188 Window::GetDecorationsSize(w, h);
191 if(direction == vertical) *h += left.size.w + right.size.w + 8; else *w += left.size.h + right.size.h + 8;
195 void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
197 Window::SetWindowArea(x, y, w, h, cw, ch);
200 if(direction == vertical) *y += left.size.w + 4; else *x += left.size.h + 4;
211 OnResize(clientSize.w, clientSize.h);
213 if(direction == vertical)
215 left.bitmap = { "<:ecere>elements/arrowTop.png" };
216 left.anchor = { top = 2, left = 2, right = 2 };
218 right.bitmap = { "<:ecere>elements/arrowBottom.png" };
219 right.anchor = { bottom = 2, left = 2, right = 2 };
223 left.bitmap = { "<:ecere>elements/arrowLeft.png" };
224 left.anchor = { left = 2, top = 2, bottom = 2 };
226 right.bitmap = { "<:ecere>elements/arrowRight.png" };
227 right.anchor = { right = 2, top = 2, bottom = 2 };
233 direction = vertical;
235 void OnResize(int width, int height)
240 Array<Window> oldControls = controls;
241 Array<Window> orderedControls;
242 Array<Window> controlsDirA { };
243 Array<Window> controlsDirB { };
248 // TOFIX: this needs to maintain an order and allow for dynamically adding
249 // children. inserting in the order should also be possible.
252 for(child = firstChild; child; child = child.next)
254 if(child.nonClient/* || !child.visible*/ /*|| !child.created*/) continue;
263 for(child = firstChild; child; child = child.next)
265 if(child.nonClient/* || !child.visible*/ /*|| !child.created*/) continue;
266 if(!controls.Find(child))
281 orderedControls = { };
282 for(c = controls.count-1; c >= 0; c--)
285 orderedControls.Add(child);
290 orderedControls = controls;
292 for(child : orderedControls)
294 if(!child.visible) continue;
295 if(direction == vertical)
298 child.anchor.bottom = y;
300 child.anchor.top = y;
301 y += child.size.h + gap;
306 child.anchor.right = y;
308 child.anchor.left = y;
309 y += child.size.w + gap;
314 orderedControls.Free();
315 delete orderedControls;
322 Window previousChild = 0;
323 FlipStackerSpringMode spring = none;
326 for(c = controls.count-1; c >= 0; c--)
329 if(child._class == class(FlipStacker) || eClass_IsDerived(child._class, class(FlipStacker)))
331 FlipStacker flip = (FlipStacker)child;
332 spring = flip.spring;
335 previousChild = child;
336 controlsDirA.Add(child);
342 for(c = 0; c < limit; c++)
345 if(child._class != class(FlipStacker) && !eClass_IsDerived(child._class, class(FlipStacker)))
347 controlsDirB.Add(child);
355 for(c = 0; c < controls.count; c++)
358 if(child._class == class(FlipStacker) || eClass_IsDerived(child._class, class(FlipStacker)))
360 FlipStacker flip = (FlipStacker)child;
361 spring = flip.spring;
364 previousChild = child;
365 controlsDirA.Add(child);
368 if(c < controls.count)
371 for(c = controls.count-1; c > limit; c--)
374 if(child._class != class(FlipStacker) && !eClass_IsDerived(child._class, class(FlipStacker)))
376 controlsDirB.Add(child);
384 for(child : controlsDirA)
386 if(!child.visible) continue;
387 if(direction == vertical)
390 child.anchor.bottom = y;
392 child.anchor.top = y;
393 y += child.size.h + gap;
398 child.anchor.right = y;
400 child.anchor.left = y;
401 y += child.size.w + gap;
405 for(child : controlsDirB)
407 if(!child.visible) continue;
408 if(direction == vertical)
411 child.anchor.top = y;
413 child.anchor.bottom = y;
414 y += child.size.h + gap;
419 child.anchor.left = y;
421 child.anchor.right = y;
422 y += child.size.w + gap;
425 if(spring == previous && previousChild)
428 previousChild.anchor.left = y;
430 previousChild.anchor.right = y;
439 if(scrollable && y > ((direction == horizontal) ? width : height))
441 scrollArea = (direction == horizontal) ? { y, 0 } : { 0, y };
443 right.visible = true;
447 left.visible = false;
448 right.visible = false;
449 scrollArea = { 0, 0 };
452 // FOR WHEN SCROLLING OCCURED
453 for(child : controls)
454 child.anchor = child.anchor;
458 if(direction == horizontal)
460 left.disabled = (scroll.x == 0);
461 right.disabled = (scroll.x + clientSize.w >= scrollArea.w);
465 left.disabled = (scroll.y == 0);
466 right.disabled = (scroll.y + clientSize.h >= scrollArea.h);
468 if(left.disabled && left.buttonState == down) left.OnLeftButtonUp(-1,0,0);
469 if(right.disabled && right.buttonState == down) right.OnLeftButtonUp(-1,0,0);
474 public void DestroyChildren()
478 for(child = firstChild; child; child = next)
480 next = child ? child.next : null;
490 public void MakeControlVisible(Window control)
492 if(direction == horizontal)
495 if(control.position.x - stackerScrolling < scroll.x)
497 x = control.position.x;
498 if(clientSize.w > control.size.w)
499 x -=(clientSize.w - control.size.w - stackerScrolling) / 2;
500 scroll.x = Max(x, 0);
503 else if(control.position.x + control.size.w + stackerScrolling > scroll.x + clientSize.w)
505 x = control.position.x;
506 if(clientSize.w > control.size.w)
507 x -=(clientSize.w - control.size.w + stackerScrolling) / 2;
508 scroll.x = Max(x, 0);
515 if(control.position.y - stackerScrolling < scroll.y)
517 y = control.position.y;
518 if(clientSize.h > control.size.h)
519 y -=(clientSize.h - control.size.h - stackerScrolling) / 2;
520 scroll.y = Max(y, 0);
523 else if(control.position.y + control.size.h + stackerScrolling > scroll.y + clientSize.h)
525 y = control.position.y;
526 if(clientSize.h > control.size.h)
527 y -=(clientSize.h - control.size.h + stackerScrolling) / 2;
528 scroll.y = Max(y, 0);