1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.Windows
10 {
11 public nothrow Color DefaultToolTipTextColor()
12 {
13 return Color.Black();
14 }
15
16 public nothrow Color DefaultToolTipFrameColor()
17 {
18 return Color.Black();
19 }
20
21 public nothrow string DefaultToolTipFontFamilyName()
22 {
23 return "Segoe UI";
24 }
25
26 public nothrow float DefaultToolTipFontSize()
27 {
28 return 9.0f;
29 }
30
31 public nothrow ControlCreateParams& ToolTipControlCreateParams(ControlCreateParams& controlCreateParams)
32 {
33 return controlCreateParams.SetWindowClassName("System.Windows.ToolTip").SetWindowStyle(HiddenChildWindowStyle()).
34 SetWindowClassBackgroundColor(SystemColor.COLOR_WINDOW).SetBackgroundColor(Color.FloralWhite()).SetSize(Size(0, 0));
35 }
36
37 public class ToolTipCreateParams
38 {
39 public nothrow ToolTipCreateParams(ControlCreateParams& controlCreateParams_) :
40 controlCreateParams(controlCreateParams_),
41 textColor(DefaultToolTipTextColor()),
42 frameColor(DefaultToolTipFrameColor()),
43 fontFamilyName(DefaultToolTipFontFamilyName()),
44 fontSize(DefaultToolTipFontSize())
45 {
46 }
47 public nothrow ToolTipCreateParams& Defaults()
48 {
49 return *this;
50 }
51 public nothrow ToolTipCreateParams& SetTextColor(const Color& textColor_)
52 {
53 textColor = textColor_;
54 return *this;
55 }
56 public nothrow ToolTipCreateParams& SetFrameColor(const Color& frameColor_)
57 {
58 frameColor = frameColor_;
59 return *this;
60 }
61 public nothrow ToolTipCreateParams& SetFontFamilyName(const string& fontFamilyName_)
62 {
63 fontFamilyName = fontFamilyName_;
64 return *this;
65 }
66 public nothrow ToolTipCreateParams& SetFontSize(float fontSize_)
67 {
68 fontSize = fontSize_;
69 return *this;
70 }
71 public ControlCreateParams& controlCreateParams;
72 public Color textColor;
73 public Color frameColor;
74 public string fontFamilyName;
75 public float fontSize;
76 }
77
78 public class ToolTip : Control
79 {
80 private enum Flags : sbyte
81 {
82 none = 0, changed = 1 << 0
83 }
84 public ToolTip(const Color& backgroundColor, const Color& textColor, const Color& frameColor, const string& text_, const Point& location_,
85 const Font& font_) :
86 base("System.Windows.ToolTip", DefaultWindowClassStyle(), HiddenChildWindowStyle(), DefaultExtendedWindowStyle(), backgroundColor,
87 text_, location_, Size(0, 0), Dock.none, Anchors.none), framePen(frameColor), font(font_), textBrush(textColor),
88 format(StringAlignment.near, StringAlignment.near), textHeight(0)
89 {
90 SetChanged();
91 }
92 public ToolTip(const Color& backgroundColor) :
93 this(backgroundColor, Color.Black(), Color.Black(), "", Point(0, 0), Font(FontFamily("Segoe UI"), 9.0f))
94 {
95 }
96 public ToolTip() : this(Color.FloralWhite())
97 {
98 }
99 public ToolTip(ToolTipCreateParams& createParams) :
100 base(createParams.controlCreateParams),
101 framePen(createParams.frameColor),
102 font(FontFamily(createParams.fontFamilyName), createParams.fontSize),
103 textBrush(createParams.textColor),
104 format(StringAlignment.near, StringAlignment.near), textHeight(0)
105 {
106 SetChanged();
107 }
108 public void SetTextColor(const Color& textColor)
109 {
110 textBrush = SolidBrush(textColor);
111 Invalidate();
112 }
113 public void SetFrameColor(const Color& frameColor)
114 {
115 framePen = Pen(frameColor);
116 Invalidate();
117 }
118 public void SetFont(const Font& font_)
119 {
120 font = font_;
121 SetChanged();
122 Invalidate();
123 }
124 public void MeasureExtent()
125 {
126 Graphics graphics = Graphics.FromWindowHandle(Handle());
127 Measure(graphics);
128 }
129 protected override void OnTextChanged()
130 {
131 base->OnTextChanged();
132 lines = SplitIntoLines(Text());
133 SetChanged();
134 Invalidate();
135 }
136 protected override void OnPaint(PaintEventArgs& args)
137 {
138 if (Changed())
139 {
140 ResetChanged();
141 Measure(args.graphics);
142 }
143 Rect r(Point(), GetSize());
144 r.size.w = r.size.w - 1;
145 r.size.h = r.size.h - 1;
146 args.graphics.Clear(BackgroundColor());
147 args.graphics.DrawRectangleChecked(framePen, r);
148 PointF pt(1, 1);
149 for (const string& line : lines)
150 {
151 args.graphics.DrawStringChecked(line, font, pt, textBrush);
152 pt.y = pt.y + textHeight;
153 }
154 base->OnPaint(args);
155 }
156 private void Measure(Graphics& graphics)
157 {
158 Size size;
159 for (const string& line : lines)
160 {
161 RectF textRect = graphics.MeasureStringChecked(line, font, PointF(0, 0), format);
162 textHeight = Max(textHeight, cast<int>(textRect.size.h));
163 size.w = Max(size.w, cast<int>(textRect.size.w));
164 }
165 size.h = cast<int>(lines.Count()) * textHeight;
166 size.w = size.w + 1;
167 size.h = size.h + 1;
168 SetSize(size);
169 }
170 private inline nothrow bool Changed() const
171 {
172 return (flags & Flags.changed) != Flags.none;
173 }
174 private inline nothrow void SetChanged()
175 {
176 flags = cast<Flags>(flags | Flags.changed);
177 }
178 private inline nothrow void ResetChanged()
179 {
180 flags = cast<Flags>(flags & ~Flags.changed);
181 }
182 private Flags flags;
183 private Pen framePen;
184 private Font font;
185 private SolidBrush textBrush;
186 private StringFormat format;
187 private List<string> lines;
188 private int textHeight;
189 }
190
191 public nothrow List<string> SplitIntoLines(const string& text)
192 {
193 List<string> lines;
194 string line;
195 int state = 0;
196 for (char c : text)
197 {
198 switch (state)
199 {
200 case 0:
201 {
202 switch (c)
203 {
204 case '\n':
205 {
206 lines.Add(line);
207 line.Clear();
208 break;
209 }
210 case '\r':
211 {
212 state = 1;
213 break;
214 }
215 default:
216 {
217 line.Append(c);
218 break;
219 }
220 }
221 break;
222 }
223 case 1:
224 {
225 switch (c)
226 {
227 case '\n':
228 {
229 lines.Add(line);
230 line.Clear();
231 state = 0;
232 break;
233 }
234 }
235 break;
236 }
237 }
238 }
239 if (!line.IsEmpty())
240 {
241 lines.Add(line);
242 }
243 return lines;
244 }
245 }