1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.Windows
10 {
11 public nothrow Color DefaultToolTipWindowColor()
12 {
13 return Color.FloralWhite();
14 }
15
16 public nothrow Color DefaultToolButtonTransparentColor()
17 {
18 return Color.DefaultBitmapTransparent();
19 }
20
21 public nothrow int DefaultToolButtonHeight()
22 {
23 return 38;
24 }
25
26 public nothrow ToolBar.Style DefaultToolBarStyle()
27 {
28 return ToolBar.Style.regular;
29 }
30
31 public nothrow Padding DefaultToolBarPadding()
32 {
33 return Padding(0, 0, 0, 0);
34 }
35
36 public nothrow Padding DefaultToolButtonPadding()
37 {
38 return Padding(0, 0, 0, 0);
39 }
40
41 public nothrow Color DefaultToolBarDarkColor()
42 {
43 return Color(100u, 100u, 100u);
44 }
45
46 public nothrow Color DefaultToolBarLightColor()
47 {
48 return Color.White();
49 }
50
51 public nothrow Color DefaultToolBarMediumLightColor()
52 {
53 return Color(227u, 227u, 227u);
54 }
55
56 public nothrow Color DefaultToolBarMediumDarkColor()
57 {
58 return Color(160u, 160u, 160u);
59 }
60
61 public nothrow Color DefaultToolBarDisabledColor()
62 {
63 return Color(204u, 204u, 207u);
64 }
65
66 public nothrow Color DefaultToolBarToolButtonSeparatorColor1()
67 {
68 return Color(204u, 206u, 219u);
69 }
70
71 public nothrow Color DefaultToolBarToolButtonSeparatorColor2()
72 {
73 return Color(245u, 245u, 245u);
74 }
75
76 public nothrow ControlCreateParams& ToolBarControlCreateParams(ControlCreateParams& controlCreateParams,
77 const Padding& padding,
78 const Padding& buttonPadding,
79 int toolButtonHeight)
80 {
81 return controlCreateParams.SetWindowClassName("System.Windows.ToolBar").SetLocation(Point(padding.left, padding.top)).
82 SetSize(Size(0, toolButtonHeight + padding.Vertical() + buttonPadding.Vertical())).SetDock(Dock.top);
83 }
84
85 public nothrow ControlCreateParams& ToolBarControlCreateParams(ControlCreateParams& controlCreateParams)
86 {
87 return ToolBarControlCreateParams(controlCreateParams, DefaultToolBarPadding(), DefaultToolButtonPadding(), DefaultToolButtonHeight());
88 }
89
90 public class ToolBarCreateParams
91 {
92 public nothrow ToolBarCreateParams(ControlCreateParams& controlCreateParams_) :
93 controlCreateParams(controlCreateParams_),
94 toolTipWindowColor(DefaultToolTipWindowColor()),
95 toolButtonTransparentColor(DefaultToolButtonTransparentColor()),
96 toolButtonHeight(DefaultToolButtonHeight()),
97 style(DefaultToolBarStyle()),
98 padding(DefaultToolBarPadding()),
99 buttonPadding(DefaultToolButtonPadding()),
100 darkColor(DefaultToolBarDarkColor()),
101 lightColor(DefaultToolBarLightColor()),
102 mediumLightColor(DefaultToolBarMediumLightColor()),
103 mediumDarkColor(DefaultToolBarMediumDarkColor()),
104 disabledColor(DefaultToolBarDisabledColor()),
105 toolButtonSeparatorColor1(DefaultToolBarToolButtonSeparatorColor1()),
106 toolButtonSeparatorColor2(DefaultToolBarToolButtonSeparatorColor2())
107 {
108 }
109 public nothrow ToolBarCreateParams& Defaults()
110 {
111 return *this;
112 }
113 public nothrow ToolBarCreateParams& SetToolTipWindowColor(const Color& toolTipWindowColor_)
114 {
115 toolTipWindowColor = toolTipWindowColor_;
116 return *this;
117 }
118 public nothrow ToolBarCreateParams& SetToolButtonTransparentColor(const Color& toolButtonTransparentColor_)
119 {
120 toolButtonTransparentColor = toolButtonTransparentColor_;
121 return *this;
122 }
123 public nothrow ToolBarCreateParams& SetToolButtonHeight(int toolButtonHeight_)
124 {
125 toolButtonHeight = toolButtonHeight_;
126 return *this;
127 }
128 public nothrow ToolBarCreateParams& SetStyle(ToolBar.Style style_)
129 {
130 style = style_;
131 return *this;
132 }
133 public nothrow ToolBarCreateParams& SetPadding(const Padding& padding_)
134 {
135 padding = padding_;
136 return *this;
137 }
138 public nothrow ToolBarCreateParams& SetButtonPadding(const Padding& buttonPadding_)
139 {
140 buttonPadding = buttonPadding_;
141 return *this;
142 }
143 public nothrow ToolBarCreateParams& SetDarkColor(const Color& darkColor_)
144 {
145 darkColor = darkColor_;
146 return *this;
147 }
148 public nothrow ToolBarCreateParams& SetLightColor(const Color& lightColor_)
149 {
150 lightColor = lightColor_;
151 return *this;
152 }
153 public nothrow ToolBarCreateParams& SetMediumLightColor(const Color& mediumLightColor_)
154 {
155 mediumLightColor = mediumLightColor_;
156 return *this;
157 }
158 public nothrow ToolBarCreateParams& SetMediumDarkColor(const Color& mediumDarkColor_)
159 {
160 mediumDarkColor = mediumDarkColor_;
161 return *this;
162 }
163 public nothrow ToolBarCreateParams& SetDisabledColor(const Color& disabledColor_)
164 {
165 disabledColor = disabledColor_;
166 return *this;
167 }
168 public nothrow ToolBarCreateParams& SetToolButtonSeparatorColor1(const Color& toolButtonSeparatorColor1_)
169 {
170 toolButtonSeparatorColor1 = toolButtonSeparatorColor1_;
171 return *this;
172 }
173 public nothrow ToolBarCreateParams& SetToolButtonSeperatorColor2(const Color& toolButtonSeparatorColor2_)
174 {
175 toolButtonSeparatorColor2 = toolButtonSeparatorColor2_;
176 return *this;
177 }
178 public ControlCreateParams& controlCreateParams;
179 public Color toolTipWindowColor;
180 public Color toolButtonTransparentColor;
181 public int toolButtonHeight;
182 public ToolBar.Style style;
183 public Padding padding;
184 public Padding buttonPadding;
185 public Color darkColor;
186 public Color lightColor;
187 public Color mediumLightColor;
188 public Color mediumDarkColor;
189 public Color disabledColor;
190 public Color toolButtonSeparatorColor1;
191 public Color toolButtonSeparatorColor2;
192 }
193
194 public class ToolBar : Control
195 {
196 private enum Flags : sbyte
197 {
198 none = 0, toolTipWindowAdded = 1 << 0, toolTipWindowVisible = 1 << 1
199 }
200 public enum Style
201 {
202 regular = 0, radioButtonGroup = 1
203 }
204 public ToolBar(const Color& backgroundColor, const Color& toolTipWindowColor, const Color& toolButtonTransparentColor_, const Point& location,
205 const Size& size, Dock dock, Anchors anchors,
206 int toolButtonHeight_, Style style_, const Padding& padding_, const Padding& buttonPadding_) :
207 base("System.Windows.ToolBar", DefaultWindowClassStyle(), DefaultChildWindowStyle(), DefaultExtendedWindowStyle(),
208 backgroundColor, "toolBar", location, size, dock, anchors), flags(Flags.none), toolButtonTransparentColor(toolButtonTransparentColor_),
209 toolButtonHeight(toolButtonHeight_), darkColor(Color(100u, 100u, 100u)), lightColor(Color.White()), mediumLightColor(227u, 227u, 227u),
210 mediumDarkColor(160u, 160u, 160u), disabledColor(Color(204u, 204u, 207u)),
211 toolButtonSeparatorColor1(204u, 206u, 219u), toolButtonSeparatorColor2(245u, 245u, 245u), mouseInToolButton(null), mouseDownToolButton(null),
212 pressedStateToolButton(null), style(style_), toolTipWindow(new ToolTip(toolTipWindowColor)), padding(padding_), buttonPadding(buttonPadding_),
213 toolButtons(this), centerFormat(StringAlignment.center, StringAlignment.center)
214 {
215 SetMouseHoverMs(DefaultMouseHoverMs());
216 }
217 public ToolBar(int toolButtonHeight, const Color& toolTipWindowColor, const Color& toolButtonTransparentColor, Style style,
218 const Padding& padding, const Padding& buttonPadding) :
219 this(DefaultControlBackgroundColor(), toolTipWindowColor, toolButtonTransparentColor, Point(padding.left, padding.top),
220 Size(0, toolButtonHeight + padding.Vertical() + buttonPadding.Vertical()), Dock.top, Anchors.none, toolButtonHeight, style,
221 padding, buttonPadding)
222 {
223 }
224 public ToolBar(Style style) : this(38, Color.FloralWhite(), Color.DefaultBitmapTransparent(), style, DefaultPadding(), DefaultButtonPadding())
225 {
226 }
227 public ToolBar() : this(Style.regular)
228 {
229 }
230 public ToolBar(ToolBarCreateParams& createParams) :
231 base(createParams.controlCreateParams),
232 flags(Flags.none), toolButtonTransparentColor(createParams.toolButtonTransparentColor),
233 toolButtonHeight(createParams.toolButtonHeight),
234 darkColor(createParams.darkColor),
235 lightColor(createParams.lightColor),
236 mediumLightColor(createParams.mediumLightColor),
237 mediumDarkColor(createParams.mediumDarkColor),
238 disabledColor(createParams.disabledColor),
239 toolButtonSeparatorColor1(createParams.toolButtonSeparatorColor1),
240 toolButtonSeparatorColor2(createParams.toolButtonSeparatorColor2),
241 mouseInToolButton(null), mouseDownToolButton(null), pressedStateToolButton(null),
242 style(createParams.style), toolTipWindow(new ToolTip(createParams.toolTipWindowColor)),
243 padding(createParams.padding),
244 buttonPadding(createParams.buttonPadding),
245 toolButtons(this),
246 centerFormat(StringAlignment.center, StringAlignment.center)
247 {
248 SetMouseHoverMs(DefaultMouseHoverMs());
249 }
250 public void SetTextToolButtonFont(const Font& textToolButtonFont_)
251 {
252 textToolButtonFont = textToolButtonFont_;
253 }
254 public inline nothrow const Font& GetTextToolButtonFont() const
255 {
256 return textToolButtonFont;
257 }
258 public inline nothrow const StringFormat& CenterFormat() const
259 {
260 return centerFormat;
261 }
262 public inline nothrow const int ToolButtonHeight() const
263 {
264 return toolButtonHeight;
265 }
266 public nothrow Padding DefaultPadding() const
267 {
268 return Padding(0, 0, 0, 0);
269 }
270 public nothrow Padding DefaultButtonPadding()
271 {
272 return Padding(0, 0, 0, 0);
273 }
274 public nothrow const Padding& GetPadding() const
275 {
276 return padding;
277 }
278 public nothrow const Padding& GetButtonPadding()
279 {
280 return buttonPadding;
281 }
282 public nothrow void SetButtonPadding(const Padding& buttonPadding_)
283 {
284 buttonPadding = buttonPadding_;
285 }
286 public ~ToolBar()
287 {
288 if (toolTipWindow != null && ToolTipWindowAdded())
289 {
290 ResetToolTipWindowAdded();
291 Window* window = GetWindow();
292 if (window != null)
293 {
294 window->RemoveChild(toolTipWindow);
295 toolTipWindow = null;
296 }
297 }
298 }
299 public inline nothrow Style GetStyle() const
300 {
301 return style;
302 }
303 public inline nothrow const Color& DarkColor() const
304 {
305 return darkColor;
306 }
307 public nothrow void SetDarkColor(const Color& darkColor_)
308 {
309 darkColor = darkColor_;
310 }
311 public inline nothrow const Color& LightColor() const
312 {
313 return lightColor;
314 }
315 public nothrow void SetLightColor(const Color& lightColor_)
316 {
317 lightColor = lightColor_;
318 }
319 public inline nothrow const Color& MediumLightColor() const
320 {
321 return mediumLightColor;
322 }
323 public nothrow void SetMediumLightColor(const Color& mediumLightColor_)
324 {
325 mediumLightColor = mediumLightColor_;
326 }
327 public inline nothrow const Color& MediumDarkColor() const
328 {
329 return mediumDarkColor;
330 }
331 public nothrow void SetMediumDarkColor(const Color& mediumDarkColor_)
332 {
333 mediumDarkColor = mediumDarkColor_;
334 }
335 public inline nothrow const Color& DisabledColor() const
336 {
337 return disabledColor;
338 }
339 public nothrow void SetDisabledColor(const Color& disabledColor_)
340 {
341 disabledColor = disabledColor_;
342 }
343 public inline nothrow const Color& ToolButtonSeparatorColor1() const
344 {
345 return toolButtonSeparatorColor1;
346 }
347 public nothrow void SetToolButtonSeparatorColor1(const Color& toolButtonSeparatorColor1_)
348 {
349 toolButtonSeparatorColor1 = toolButtonSeparatorColor1_;
350 }
351 public inline nothrow const Color& ToolButtonSeparatorColor2() const
352 {
353 return toolButtonSeparatorColor2;
354 }
355 public nothrow void SetToolButtonSeparatorColor2(const Color& toolButtonSeparatorColor2_)
356 {
357 toolButtonSeparatorColor2 = toolButtonSeparatorColor2_;
358 }
359 public void AddToolButton(ToolButtonBase* toolButton)
360 {
361 toolButton->SetToolBar(this);
362 toolButtons.AddChild(toolButton);
363 if (toolButton is ToolButton*)
364 {
365 ToolButton* tb = cast<ToolButton*>(toolButton);
366 tb->SetTransparentColor(toolButtonTransparentColor);
367 SetToolButtonBitmaps(tb);
368 if (style == Style.radioButtonGroup)
369 {
370 if (pressedStateToolButton == null)
371 {
372 SetPressedStateToolButton(tb);
373 }
374 }
375 }
376 }
377 public nothrow ToolButton* GetToolButton(int toolButtonIndex) const
378 {
379 Component* component = toolButtons.FirstChild();
380 int index = 0;
381 while (component != null)
382 {
383 if (component is ToolButton*)
384 {
385 if (index == toolButtonIndex) return cast<ToolButton*>(component);
386 ++index;
387 }
388 component = component->NextSibling();
389 }
390 return null;
391 }
392 public inline nothrow ToolButton* PressedStateToolButton() const
393 {
394 if (style == Style.radioButtonGroup)
395 {
396 return pressedStateToolButton;
397 }
398 else
399 {
400 return null;
401 }
402 }
403 public void SetPressedStateToolButton(ToolButton* newPressedStateToolButton)
404 {
405 if (style == Style.radioButtonGroup)
406 {
407 if (pressedStateToolButton != newPressedStateToolButton)
408 {
409 if (pressedStateToolButton != null)
410 {
411 pressedStateToolButton->SetState(ToolButton.State.normal);
412 }
413 pressedStateToolButton = newPressedStateToolButton;
414 if (pressedStateToolButton != null)
415 {
416 pressedStateToolButton->SetState(ToolButton.State.pressed);
417 }
418 }
419 }
420 }
421 public nothrow void ResetPressedStateToolButton()
422 {
423 if (style == Style.radioButtonGroup)
424 {
425 pressedStateToolButton = null;
426 }
427 }
428 protected override void OnPaint(PaintEventArgs& args)
429 {
430 if (!ToolTipWindowAdded())
431 {
432 SetToolTipWindowAdded();
433 Window* window = GetWindow();
434 if (window != null)
435 {
436 window->AddChild(toolTipWindow);
437 }
438 }
439 args.graphics.Clear(BackgroundColor());
440 Point origin(padding.left, padding.top);
441 Component* component = toolButtons.FirstChild();
442 while (component != null)
443 {
444 if (component is ToolButtonBase*)
445 {
446 ToolButtonBase* toolButton = cast<ToolButtonBase*>(component);
447 Size toolButtonSize = toolButton->GetSize();
448 Point toolButtonLocation = origin;
449 toolButtonLocation.Offset(buttonPadding.left, buttonPadding.top + (toolButtonHeight - toolButtonSize.h) / 2);
450 toolButton->SetLocation(toolButtonLocation);
451 toolButton->Draw(args.graphics, origin);
452 origin.x = origin.x + toolButtonSize.w + buttonPadding.Horizontal();
453 }
454 component = component->NextSibling();
455 }
456 base->OnPaint(args);
457 }
458 protected override void OnMouseEnter()
459 {
460 base->OnMouseEnter();
461 mouseInToolButton = null;
462 mouseDownToolButton = null;
463 }
464 protected override void OnMouseLeave()
465 {
466 base->OnMouseLeave();
467 if (mouseInToolButton != null)
468 {
469 mouseInToolButton->MouseLeaveInternal();
470 }
471 mouseInToolButton = null;
472 mouseDownToolButton = null;
473 HideToolTipWindow();
474 }
475 protected override void OnMouseMove(MouseEventArgs& args)
476 {
477 base->OnMouseMove(args);
478 ToolButton* toolButton = GetToolButtonAt(args.location);
479 if (toolButton != null)
480 {
481 if (mouseInToolButton != toolButton)
482 {
483 if (mouseInToolButton != null)
484 {
485 mouseInToolButton->MouseLeaveInternal();
486 mouseInToolButton = null;
487 }
488 mouseInToolButton = toolButton;
489 mouseInToolButton->MouseEnterInternal();
490 }
491 toolButton->MouseMoveInternal(args);
492 }
493 }
494 protected override void OnMouseHover(MouseEventArgs& args)
495 {
496 base->OnMouseHover(args);
497 ToolButton* toolButton = GetToolButtonAt(args.location);
498 if (toolButton != null)
499 {
500 toolButton->MouseHoverInternal();
501 }
502 }
503 protected override void OnMouseDown(MouseEventArgs& args)
504 {
505 base->OnMouseDown(args);
506 HideToolTipWindow();
507 if (style == Style.regular)
508 {
509 ToolButton* toolButton = GetToolButtonAt(args.location);
510 if (toolButton != null)
511 {
512 if (toolButton->GetState() == ToolButton.State.normal)
513 {
514 if (args.buttons == MouseButtons.lbutton)
515 {
516 mouseDownToolButton = toolButton;
517 }
518 toolButton->MouseDownInternal(args);
519 if (args.buttons == MouseButtons.lbutton)
520 {
521 toolButton->SetState(ToolButton.State.pressed);
522 }
523 }
524 else
525 {
526 return;
527 }
528 }
529 WinSetCapture(Handle());
530 }
531 else if (style == Style.radioButtonGroup)
532 {
533 ToolButton* toolButton = GetToolButtonAt(args.location);
534 if (toolButton != null)
535 {
536 if (args.buttons == MouseButtons.lbutton)
537 {
538 SetPressedStateToolButton(toolButton);
539 toolButton->DoClick();
540 }
541 }
542 }
543 }
544 protected override void OnMouseUp(MouseEventArgs& args)
545 {
546 base->OnMouseUp(args);
547 if (style == Style.regular)
548 {
549 ToolButton* toolButton = GetToolButtonAt(args.location);
550 if (toolButton != null)
551 {
552 if (toolButton->GetState() == ToolButton.State.pressed)
553 {
554 toolButton->MouseUpInternal(args);
555 if (args.buttons == MouseButtons.lbutton)
556 {
557 if (toolButton == mouseDownToolButton)
558 {
559 toolButton->DoClick();
560 }
561 }
562 }
563 }
564 if (mouseDownToolButton != null && mouseDownToolButton->GetStyle() == ToolButton.Style.automatic)
565 {
566 mouseDownToolButton->SetState(ToolButton.State.normal);
567 }
568 mouseDownToolButton = null;
569 WinReleaseCapture();
570 }
571 }
572 internal void ShowToolTipWindow(ToolButton* toolButton)
573 {
574 if (toolTipWindow == null || !ToolTipWindowAdded()) return;
575 if (ToolTipWindowVisible()) toolTipWindow->Hide();
576 ResetToolTipWindowVisible();
577 Point loc = toolButton->Location();
578 Size size = toolButton->GetSize();
579 toolTipWindow->SetText(toolButton->GetToolTip());
580 toolTipWindow->MeasureExtent();
581 Point pt(loc.x, loc.y + size.h + 8);
582 pt = ClientToScreen(pt);
583 Window* window = GetWindow();
584 if (window != null)
585 {
586 pt = window->ScreenToClient(pt);
587 Size sz = toolTipWindow->GetSize();
588 Point wloc = window->Location();
589 Size wsz = window->GetSize();
590 if (pt.y + sz.h > wloc.y + wsz.h)
591 {
592 pt.y = wloc.y + wsz.h - sz.h;
593 }
594 if (pt.x + sz.w > wloc.x + wsz.w)
595 {
596 pt.x = wloc.x + wsz.w - sz.w;
597 }
598 toolTipWindow->SetLocation(pt);
599 toolTipWindow->BringToFront();
600 toolTipWindow->Show();
601 toolTipWindow->Invalidate();
602 SetToolTipWindowVisible();
603 }
604 }
605 internal void HideToolTipWindow()
606 {
607 if (toolTipWindow == null || !ToolTipWindowAdded() || !ToolTipWindowVisible()) return;
608 toolTipWindow->Hide();
609 ResetToolTipWindowVisible();
610 }
611 internal SolidBrush* GetOrInsertSolidBrush(const Color& color)
612 {
613 HashMap<Color, SolidBrush*>.ConstIterator it = textBrushMap.CFind(color);
614 if (it != textBrushMap.CEnd())
615 {
616 return it->second;
617 }
618 else
619 {
620 UniquePtr<SolidBrush> brushPtr(new SolidBrush(color));
621 SolidBrush* brush = brushPtr.Get();
622 textBrushMap[color] = brushPtr.Get();
623 textBrushes.Add(Rvalue(brushPtr));
624 return brush;
625 }
626 }
627 private void SetToolButtonBitmaps(ToolButton* toolButton)
628 {
629 Pair<Bitmap*, Bitmap*> toolBitmapPair = GetOrCreateBitmaps(toolButton->ToolBitmapName());
630 toolButton->SetToolBitmaps(toolBitmapPair.first, toolBitmapPair.second);
631 }
632 private Pair<Bitmap*, Bitmap*> GetOrCreateBitmaps(const string& bitmapName)
633 {
634 Pair<Bitmap*, Bitmap*> bitmapPair;
635 if (bitmapName.IsEmpty()) return bitmapPair;
636 try
637 {
638 HashMap<string, Pair<Bitmap*, Bitmap*>>.ConstIterator it = bitmapMap.CFind(bitmapName);
639 if (it != bitmapMap.CEnd())
640 {
641 return it->second;
642 }
643 UniquePtr<Bitmap> bitmapPtr(new Bitmap(Bitmap.FromResource(bitmapName)));
644 Bitmap* bitmap = bitmapPtr.Get();
645 UniquePtr<Bitmap> disabledBitmapPtr(new Bitmap(bitmap->ToGrayBitmap()));
646 Bitmap* disabledBitmap = disabledBitmapPtr.Get();
647 bitmapPair = MakePair(bitmap, disabledBitmap);
648 bitmapMap[bitmapName] = bitmapPair;
649 bitmaps.Add(Rvalue(bitmapPtr));
650 bitmaps.Add(Rvalue(disabledBitmapPtr));
651 return bitmapPair;
652 }
653 catch (const Exception& ex)
654 {
655 throw Exception("could not load bitmap '" + bitmapName + "': " + ex.Message());
656 }
657 return bitmapPair;
658 }
659 private nothrow ToolButton* GetToolButtonAt(const Point& location) const
660 {
661 Size size = GetSize();
662 if (location.y >= 0 && location.y < size.h && location.x >= 0 && location.x < size.w)
663 {
664 Component* component = toolButtons.FirstChild();
665 while (component != null)
666 {
667 if (component is ToolButton*)
668 {
669 ToolButton* toolButton = cast<ToolButton*>(component);
670 if (location.x >= toolButton->Location().x && location.x <= toolButton->Location().x + toolButton->GetSize().w)
671 {
672 return toolButton;
673 }
674 }
675 component = component->NextSibling();
676 }
677 }
678 return null;
679 }
680 private inline nothrow bool ToolTipWindowAdded() const
681 {
682 return (flags & Flags.toolTipWindowAdded) != Flags.none;
683 }
684 private inline nothrow void SetToolTipWindowAdded()
685 {
686 flags = cast<Flags>(flags | Flags.toolTipWindowAdded);
687 }
688 private inline nothrow void ResetToolTipWindowAdded()
689 {
690 flags = cast<Flags>(flags & ~Flags.toolTipWindowAdded);
691 }
692 private inline nothrow bool ToolTipWindowVisible() const
693 {
694 return (flags & Flags.toolTipWindowVisible) != Flags.none;
695 }
696 private inline nothrow void SetToolTipWindowVisible()
697 {
698 flags = cast<Flags>(flags | Flags.toolTipWindowVisible);
699 }
700 private inline nothrow void ResetToolTipWindowVisible()
701 {
702 flags = cast<Flags>(flags & ~Flags.toolTipWindowVisible);
703 }
704 private Flags flags;
705 private Container toolButtons;
706 private Color toolButtonTransparentColor;
707 private int toolButtonHeight;
708 private List<UniquePtr<Bitmap>> bitmaps;
709 private HashMap<string, Pair<Bitmap*, Bitmap*>> bitmapMap;
710 private Color darkColor;
711 private Color lightColor;
712 private Color mediumLightColor;
713 private Color mediumDarkColor;
714 private Color disabledColor;
715 private Color toolButtonSeparatorColor1;
716 private Color toolButtonSeparatorColor2;
717 private ToolButton* mouseInToolButton;
718 private ToolButton* mouseDownToolButton;
719 private ToolButton* pressedStateToolButton;
720 private Style style;
721 private ToolTip* toolTipWindow;
722 private Padding padding;
723 private Padding buttonPadding;
724 private Font textToolButtonFont;
725 private StringFormat centerFormat;
726 private HashMap<Color, SolidBrush*> textBrushMap;
727 private List<UniquePtr<SolidBrush>> textBrushes;
728 }
729
730 public abstract class ToolButtonBase : Component
731 {
732 public nothrow ToolButtonBase() : location(), size()
733 {
734 }
735 public virtual nothrow void SetToolBar(ToolBar* toolBar_)
736 {
737 toolBar = toolBar_;
738 }
739 public inline nothrow ToolBar* GetToolBar() const
740 {
741 return toolBar;
742 }
743 public abstract void Draw(Graphics& graphics, const Point& origin);
744 public inline nothrow const Point& Location() const
745 {
746 return location;
747 }
748 public inline nothrow void SetLocation(const Point& location_)
749 {
750 location = location_;
751 }
752 public inline nothrow const Size& GetSize() const
753 {
754 return size;
755 }
756 public inline nothrow void SetSize(const Size& size_)
757 {
758 size = size_;
759 }
760 private ToolBar* toolBar;
761 private Point location;
762 private Size size;
763 }
764
765 public class ToolButtonSeparator : ToolButtonBase
766 {
767 public nothrow ToolButtonSeparator() : base()
768 {
769 }
770 public override nothrow void SetToolBar(ToolBar* toolBar)
771 {
772 base->SetToolBar(toolBar);
773 SetSize(Size(2, toolBar->ToolButtonHeight() - 4));
774 }
775 public override void Draw(Graphics& graphics, const Point& origin)
776 {
777 ToolBar* toolBar = GetToolBar();
778 Point location = Location();
779 Size size = GetSize();
780 Point firstLineStart(origin.x, origin.y);
781 Point firstLineEnd(firstLineStart.x, firstLineStart.y + size.h);
782 Pen firstLinePen(toolBar->ToolButtonSeparatorColor1());
783 graphics.DrawLineChecked(firstLinePen, firstLineStart, firstLineEnd);
784 Point secondLineStart(origin.x + 1, origin.y + location.y);
785 Point secondLineEnd(secondLineStart.x, secondLineStart.y + size.h);
786 Pen secondLinePen(toolBar->ToolButtonSeparatorColor2());
787 graphics.DrawLineChecked(secondLinePen, secondLineStart, secondLineEnd);
788 }
789 }
790
791 public class ClickGuard
792 {
793 public nothrow ClickGuard(ToolButton* toolButton_) : toolButton(toolButton_)
794 {
795 }
796 public ~ClickGuard()
797 {
798 if (toolButton->GetStyle() == ToolButton.Style.automatic)
799 {
800 toolButton->SetState(ToolButton.State.normal);
801 }
802 }
803 private ToolButton* toolButton;
804 }
805
806 public class ToolButton : ToolButtonBase
807 {
808 public enum State : sbyte
809 {
810 normal = 0, pressed = 1, disabled = 2
811 }
812 public enum Style : sbyte
813 {
814 automatic, manual
815 }
816 public nothrow ToolButton(const string& toolBitmapName_, Style style_) :
817 base(), state(State.normal), toolBitmapName(toolBitmapName_), toolBitmap(null), transparentColor(Color.DefaultBitmapTransparent()), padding(DefaultPadding()),
818 style(style_)
819 {
820 }
821 public nothrow ToolButton(const string& toolBitmapName) : this(toolBitmapName, Style.automatic)
822 {
823 }
824 public virtual default ~ToolButton();
825 public inline nothrow Style GetStyle() const
826 {
827 return style;
828 }
829 public nothrow void Enable()
830 {
831 if (state == State.disabled)
832 {
833 SetState(State.normal);
834 }
835 }
836 public nothrow void Disable()
837 {
838 if (state == State.normal)
839 {
840 SetState(State.disabled);
841 }
842 }
843 public nothrow Padding GetPadding() const
844 {
845 return padding;
846 }
847 public void SetPadding(const Padding& padding_)
848 {
849 padding = padding_;
850 }
851 protected nothrow Padding DefaultPadding()
852 {
853 return Padding(3, 3, 3, 3);
854 }
855 public inline nothrow State GetState() const
856 {
857 return state;
858 }
859 public void SetState(State state_)
860 {
861 ToolBar* toolBar = GetToolBar();
862 if (state != state_)
863 {
864 if (state_ == State.pressed)
865 {
866 if (toolBar->GetStyle() == ToolBar.Style.radioButtonGroup)
867 {
868 if (toolBar->PressedStateToolButton() != this)
869 {
870 toolBar->SetPressedStateToolButton(this);
871 }
872 }
873 }
874 else if (state_ == State.normal)
875 {
876 if (toolBar->GetStyle() == ToolBar.Style.radioButtonGroup)
877 {
878 if (toolBar->PressedStateToolButton() == this)
879 {
880 toolBar->ResetPressedStateToolButton();
881 }
882 }
883 }
884 state = state_;
885 Invalidate();
886 }
887 }
888 public nothrow void SetToolTip(const string& toolTip_)
889 {
890 if (toolTip != toolTip_)
891 {
892 toolTip = toolTip_;
893 Invalidate();
894 }
895 }
896 public inline nothrow const string& GetToolTip() const
897 {
898 return toolTip;
899 }
900 public nothrow void SetTransparentColor(const Color& transparentColor_)
901 {
902 transparentColor = transparentColor_;
903 }
904 internal void MouseEnterInternal()
905 {
906 OnMouseEnter();
907 }
908 internal void MouseHoverInternal()
909 {
910 ToolBar* toolBar = GetToolBar();
911 if (!toolTip.IsEmpty() && toolBar != null)
912 {
913 toolBar->ShowToolTipWindow(this);
914 }
915 }
916 protected virtual void OnMouseEnter()
917 {
918 mouseEnterEvent.Fire();
919 }
920 public nothrow Event<MouseEnterEventHandler>& MouseEnterEvent() const
921 {
922 return mouseEnterEvent;
923 }
924 internal void MouseLeaveInternal()
925 {
926 OnMouseLeave();
927 ToolBar* toolBar = GetToolBar();
928 if (!toolTip.IsEmpty() && toolBar != null)
929 {
930 toolBar->HideToolTipWindow();
931 }
932 }
933 protected virtual void OnMouseLeave()
934 {
935 mouseLeaveEvent.Fire();
936 }
937 public nothrow Event<MouseLeaveEventHandler>& MouseLeaveEvent() const
938 {
939 return mouseLeaveEvent;
940 }
941 internal void MouseMoveInternal(MouseEventArgs& args)
942 {
943 OnMouseMove(args);
944 }
945 protected virtual void OnMouseMove(MouseEventArgs& args)
946 {
947 mouseMoveEvent.Fire(args);
948 }
949 public nothrow Event<MouseEventHandler, MouseEventArgs>& MouseMoveEvent() const
950 {
951 return mouseMoveEvent;
952 }
953 internal void MouseDownInternal(MouseEventArgs& args)
954 {
955 OnMouseDown(args);
956 }
957 protected virtual void OnMouseDown(MouseEventArgs& args)
958 {
959 mouseDownEvent.Fire(args);
960 }
961 public nothrow Event<MouseEventHandler, MouseEventArgs>& MouseDownEvent() const
962 {
963 return mouseDownEvent;
964 }
965 internal void MouseUpInternal(MouseEventArgs& args)
966 {
967 OnMouseUp(args);
968 }
969 protected virtual void OnMouseUp(MouseEventArgs& args)
970 {
971 mouseUpEvent.Fire(args);
972 }
973 public nothrow Event<MouseEventHandler, MouseEventArgs>& MouseUpEvent() const
974 {
975 return mouseUpEvent;
976 }
977 internal void DoClick()
978 {
979 OnClick();
980 }
981 protected virtual void OnClick()
982 {
983 ClickGuard guard(this);
984 clickEvent.Fire();
985 }
986 public nothrow Event<ClickEventHandler>& ClickEvent() const
987 {
988 return clickEvent;
989 }
990 public override void Draw(Graphics& graphics, const Point& location)
991 {
992 switch (state)
993 {
994 case State.normal:
995 case State.disabled:
996 {
997 DrawNormalOrDisabled(graphics, location);
998 break;
999 }
1000 case State.pressed:
1001 {
1002 DrawPressed(graphics, location);
1003 break;
1004 }
1005 }
1006 }
1007 private void DrawNormalOrDisabled(Graphics& graphics, const Point& location)
1008 {
1009 ToolBar* toolBar = GetToolBar();
1010 Pen darkPen(toolBar->DarkColor(), 1.0f);
1011 Size size = GetSize();
1012 Rect rect(location, size);
1013 rect.size.w = rect.size.w - 1;
1014 rect.size.h = rect.size.h - 1;
1015 graphics.DrawRectangleChecked(darkPen, rect);
1016 Point startRightInnerDarkLoc = location;
1017 startRightInnerDarkLoc.x = startRightInnerDarkLoc.x + size.w - 2;
1018 Point endRightInnerDarkLoc = location;
1019 endRightInnerDarkLoc.x = endRightInnerDarkLoc.x + size.w - 2;
1020 endRightInnerDarkLoc.y = endRightInnerDarkLoc.y + size.h - 1;
1021 graphics.DrawLineChecked(darkPen, startRightInnerDarkLoc, endRightInnerDarkLoc);
1022 Point startBottomInnerDarkLoc = location;
1023 startBottomInnerDarkLoc.x = startBottomInnerDarkLoc.x + 1;
1024 startBottomInnerDarkLoc.y = startBottomInnerDarkLoc.y + size.h - 2;
1025 Point endBottomInnerDarkLoc = location;
1026 endBottomInnerDarkLoc.x = endBottomInnerDarkLoc.x + size.w - 2;
1027 endBottomInnerDarkLoc.y = endBottomInnerDarkLoc.y + size.h - 2;
1028 graphics.DrawLineChecked(darkPen, startBottomInnerDarkLoc, endBottomInnerDarkLoc);
1029 Pen lightPen(toolBar->LightColor(), 1.0f);
1030 Point startTopOuterLightLoc = location;
1031 startTopOuterLightLoc.x = startTopOuterLightLoc.x + 1;
1032 startTopOuterLightLoc.y = startTopOuterLightLoc.y + 1;
1033 Point endTopOuterLightLoc = location;
1034 endTopOuterLightLoc.x = endTopOuterLightLoc.x + size.w - 3;
1035 endTopOuterLightLoc.y = endTopOuterLightLoc.y + 1;
1036 graphics.DrawLineChecked(lightPen, startTopOuterLightLoc, endTopOuterLightLoc);
1037 Point startLeftOuterLightLoc = location;
1038 startLeftOuterLightLoc.x = startLeftOuterLightLoc.x + 1;
1039 startLeftOuterLightLoc.y = startLeftOuterLightLoc.y + 1;
1040 Point endLeftOuterLightLoc = location;
1041 endLeftOuterLightLoc.x = endLeftOuterLightLoc.x + 1;
1042 endLeftOuterLightLoc.y = endLeftOuterLightLoc.y + size.h - 3;
1043 graphics.DrawLineChecked(lightPen, startLeftOuterLightLoc, endLeftOuterLightLoc);
1044 Pen mediumLightPen(toolBar->MediumLightColor(), 1.0f);
1045 Point startTopInnerLightLoc = location;
1046 startTopInnerLightLoc.x = startTopInnerLightLoc.x + 2;
1047 startTopInnerLightLoc.y = startTopInnerLightLoc.y + 2;
1048 Point endTopInnerLightLoc = location;
1049 endTopInnerLightLoc.x = endTopInnerLightLoc.x + size.w - 4;
1050 endTopInnerLightLoc.y = endTopInnerLightLoc.y + 2;
1051 graphics.DrawLineChecked(mediumLightPen, startTopInnerLightLoc, endTopInnerLightLoc);
1052 Point startLeftInnerLightLoc = location;
1053 startLeftInnerLightLoc.x = startLeftInnerLightLoc.x + 2;
1054 startLeftInnerLightLoc.y = startLeftInnerLightLoc.y + 2;
1055 Point endLeftInnerLightLoc = location;
1056 endLeftInnerLightLoc.x = endLeftInnerLightLoc.x + 2;
1057 endLeftInnerLightLoc.y = endLeftInnerLightLoc.y + size.h - 4;
1058 graphics.DrawLineChecked(mediumLightPen, startLeftInnerLightLoc, endLeftInnerLightLoc);
1059 Pen mediumDarkPen(toolBar->MediumDarkColor(), 1.0f);
1060 Point startRightInnerMediumDarkLoc = location;
1061 startRightInnerMediumDarkLoc.x = startRightInnerMediumDarkLoc.x + size.w - 3;
1062 startRightInnerMediumDarkLoc.y = startRightInnerMediumDarkLoc.y + 2;
1063 Point endRightInnerMediumDarkLoc = location;
1064 endRightInnerMediumDarkLoc.x = endRightInnerMediumDarkLoc.x + size.w - 3;
1065 endRightInnerMediumDarkLoc.y = endRightInnerMediumDarkLoc.y + size.h - 3;
1066 graphics.DrawLineChecked(mediumDarkPen, startRightInnerMediumDarkLoc, endRightInnerMediumDarkLoc);
1067 Point startBottomInnerMediumDarkLoc = location;
1068 startBottomInnerMediumDarkLoc.x = startBottomInnerMediumDarkLoc.x + 2;
1069 startBottomInnerMediumDarkLoc.y = startBottomInnerMediumDarkLoc.y + size.h - 3;
1070 Point endBottomInnerMediumDarkLoc = location;
1071 endBottomInnerMediumDarkLoc.x = endBottomInnerMediumDarkLoc.x + size.w - 3;
1072 endBottomInnerMediumDarkLoc.y = endBottomInnerMediumDarkLoc.y + size.h - 3;
1073 graphics.DrawLineChecked(mediumDarkPen, startBottomInnerMediumDarkLoc, endBottomInnerMediumDarkLoc);
1074 DrawContent(graphics, location);
1075 }
1076 private void DrawPressed(Graphics& graphics, const Point& location)
1077 {
1078 ToolBar* toolBar = GetToolBar();
1079 Pen darkPen(toolBar->DarkColor(), 1.0f);
1080 Size size = GetSize();
1081 Rect rect(location, size);
1082 rect.size.w = rect.size.w - 1;
1083 rect.size.h = rect.size.h - 1;
1084 graphics.DrawRectangleChecked(darkPen, rect);
1085
1086 Point startTopInnerDarkLoc = location;
1087 startTopInnerDarkLoc.x = startTopInnerDarkLoc.x + 1;
1088 startTopInnerDarkLoc.y = startTopInnerDarkLoc.y + 1;
1089 Point endTopInnerDarkLoc = location;
1090 endTopInnerDarkLoc.x = endTopInnerDarkLoc.x + size.w - 2;
1091 endTopInnerDarkLoc.y = endTopInnerDarkLoc.y + 1;
1092 graphics.DrawLineChecked(darkPen, startTopInnerDarkLoc, endTopInnerDarkLoc);
1093
1094 Point startLeftInnerDarkLoc = location;
1095 startLeftInnerDarkLoc.x = startLeftInnerDarkLoc.x + 1;
1096 startLeftInnerDarkLoc.y = startLeftInnerDarkLoc.y + 2;
1097 Point endLeftInnerDarkLoc = location;
1098 endLeftInnerDarkLoc.x = endLeftInnerDarkLoc.x + 1;
1099 endLeftInnerDarkLoc.y = endLeftInnerDarkLoc.y + size.h - 2;
1100 graphics.DrawLineChecked(darkPen, startLeftInnerDarkLoc, endLeftInnerDarkLoc);
1101
1102 Pen mediumDarkPen(toolBar->MediumDarkColor(), 1.0f);
1103 Point startTopInnerMediumDarkLoc = location;
1104 startTopInnerMediumDarkLoc.x = startTopInnerMediumDarkLoc.x + 2;
1105 startTopInnerMediumDarkLoc.y = startTopInnerMediumDarkLoc.y + 2;
1106 Point endTopInnerMediumDarkLoc = location;
1107 endTopInnerMediumDarkLoc.x = endTopInnerMediumDarkLoc.x + size.w - 2;
1108 endTopInnerMediumDarkLoc.y = endTopInnerMediumDarkLoc.y + 2;
1109 graphics.DrawLineChecked(mediumDarkPen, startTopInnerMediumDarkLoc, endTopInnerMediumDarkLoc);
1110
1111 Point startLeftInnerMediumDarkLoc = location;
1112 startLeftInnerMediumDarkLoc.x = startLeftInnerMediumDarkLoc.x + 2;
1113 startLeftInnerMediumDarkLoc.y = startLeftInnerMediumDarkLoc.y + 2;
1114 Point endLeftInnerMediumDarkLoc = location;
1115 endLeftInnerMediumDarkLoc.x = endLeftInnerMediumDarkLoc.x + 2;
1116 endLeftInnerMediumDarkLoc.y = endLeftInnerMediumDarkLoc.y + size.h - 2;
1117 graphics.DrawLineChecked(mediumDarkPen, startLeftInnerMediumDarkLoc, endLeftInnerMediumDarkLoc);
1118
1119 DrawContent(graphics, Point(location.x + 1, location.y + 1));
1120 }
1121 protected virtual void DrawContent(Graphics& graphics, const Point& location)
1122 {
1123 DrawToolBitmap(graphics, location);
1124 }
1125 private void DrawToolBitmap(Graphics& graphics, const Point& location)
1126 {
1127 if (toolBitmap == null) return;
1128 Point bitmapLocation(location);
1129 bitmapLocation.x = bitmapLocation.x + padding.left;
1130 bitmapLocation.y = bitmapLocation.y + padding.top;
1131 Rect r(bitmapLocation, toolBitmapSize);
1132 ImageAttributes attributes;
1133 attributes.SetColorKey(transparentColor, transparentColor, ColorAdjustType.default_);
1134 if (state == State.normal || state == State.pressed)
1135 {
1136 graphics.DrawImageChecked(*toolBitmap, r, 0, 0, toolBitmapSize.w, toolBitmapSize.h, Unit.pixel, attributes);
1137 }
1138 else if (state == State.disabled)
1139 {
1140 graphics.DrawImageChecked(*disabledToolBitmap, r, 0, 0, toolBitmapSize.w, toolBitmapSize.h, Unit.pixel, attributes);
1141 }
1142 }
1143 public inline nothrow const string& ToolBitmapName() const
1144 {
1145 return toolBitmapName;
1146 }
1147 internal nothrow void SetToolBitmaps(Bitmap* toolBitmap_, Bitmap* disabledToolBitmap_)
1148 {
1149 toolBitmap = toolBitmap_;
1150 disabledToolBitmap = disabledToolBitmap_;
1151 if (toolBitmap != null && disabledToolBitmap != null)
1152 {
1153 toolBitmapSize = Size(cast<int>(toolBitmap->GetWidth()), cast<int>(toolBitmap->GetHeight()));
1154 SetSize(Size(padding.Horizontal() + toolBitmapSize.w, padding.Vertical() + toolBitmapSize.h));
1155 }
1156 }
1157 private nothrow void Invalidate()
1158 {
1159 ToolBar* toolBar = GetToolBar();
1160 if (toolBar != null)
1161 {
1162 toolBar->Invalidate();
1163 }
1164 }
1165 private State state;
1166 private Style style;
1167 private string toolBitmapName;
1168 private Bitmap* toolBitmap;
1169 private Bitmap* disabledToolBitmap;
1170 private Color transparentColor;
1171 private Size toolBitmapSize;
1172 private string toolTip;
1173 private Padding padding;
1174 private Event<MouseEnterEventHandler> mouseEnterEvent;
1175 private Event<MouseLeaveEventHandler> mouseLeaveEvent;
1176 private Event<MouseEventHandler, MouseEventArgs> mouseMoveEvent;
1177 private Event<MouseEventHandler, MouseEventArgs> mouseDownEvent;
1178 private Event<MouseEventHandler, MouseEventArgs> mouseUpEvent;
1179 private Event<ClickEventHandler> clickEvent;
1180 }
1181
1182 public class TextToolButton : ToolButton
1183 {
1184 public nothrow TextToolButton(const string& text_, const Size& size, const Color& textColor_, ToolButton.Style style) :
1185 base("", style), text(text_), textColor(textColor_)
1186 {
1187 SetSize(size);
1188 }
1189 public nothrow TextToolButton(const string& text) : this(text, Size(12, 12), Color.Black(), ToolButton.Style.automatic)
1190 {
1191 }
1192 protected override nothrow void SetToolBar(ToolBar* toolBar)
1193 {
1194 base->SetToolBar(toolBar);
1195 Padding padding = GetPadding();
1196 Size size = GetSize();
1197 SetSize(Size(padding.Horizontal() + size.w, padding.Vertical() + size.h));
1198 normalBrush = toolBar->GetOrInsertSolidBrush(textColor);
1199 disabledBrush = toolBar->GetOrInsertSolidBrush(textColor.ToGray());
1200 }
1201 protected override void DrawContent(Graphics& graphics, const Point& location)
1202 {
1203 DrawText(graphics, location);
1204 }
1205 private void DrawText(Graphics& graphics, const Point& location)
1206 {
1207 TextRenderingHint prevRenderingHint = graphics.GetTextRenderingHint();
1208 graphics.SetTextRenderingHintChecked(TextRenderingHint.clearTypeGridFit);
1209 ToolBar* toolBar = GetToolBar();
1210 Brush* brush = normalBrush;
1211 if (GetState() == State.disabled)
1212 {
1213 brush = disabledBrush;
1214 }
1215 Size size = GetSize();
1216 RectF r(PointF(location.x, location.y), SizeF(size.w, size.h));
1217 graphics.DrawStringChecked(text, toolBar->GetTextToolButtonFont(), r, toolBar->CenterFormat(), *brush);
1218 graphics.SetTextRenderingHintChecked(prevRenderingHint);
1219 }
1220 private string text;
1221 private Color textColor;
1222 private SolidBrush* normalBrush;
1223 private SolidBrush* disabledBrush;
1224 }
1225 }