1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Windows;
9 using System.Windows.API;
10
11 namespace System.Windows
12 {
13 public nothrow System.Windows.Color DefaultIconListViewTextColor()
14 {
15 return System.Windows.Color.Black();
16 }
17
18 public nothrow System.Windows.Color DefaultIconListViewIconSelectedColor()
19 {
20 return System.Windows.Color(64u, 96u, 156u, 210u);
21 }
22
23 public nothrow Padding DefaultIconListViewIconPadding()
24 {
25 return Padding(8, 8, 8, 8);
26 }
27
28 public nothrow Padding DefaultIconListViewTextPadding()
29 {
30 return Padding(4, 4, 4, 4);
31 }
32
33 public nothrow Padding DefaultIconListViewInternalPadding()
34 {
35 return Padding(4, 4, 4, 4);
36 }
37
38 public nothrow string DefaultIconListViewFontFamilyName()
39 {
40 return "Segoe UI";
41 }
42
43 public nothrow float DefaultIconListViewFontSize()
44 {
45 return 9.0f;
46 }
47
48 public class delegate void IconListViewSelectedIndexChangedEventHandler();
49 public class delegate void IconListViewIconDoubleClickedEventHandler();
50
51 public class IconListViewItem : Component
52 {
53 public enum Flags : sbyte
54 {
55 none = 0, selected = 1 << 0
56 }
57 public nothrow IconListViewItem(const string& iconName_, const string& itemName_) : index(-1), iconName(iconName_), itemName(itemName_), location(), size()
58 {
59 }
60 public void Measure(Graphics& graphics, const Padding& iconPadding, const Padding& textPadding, const Font& font)
61 {
62 iconSize = Size(cast<int>(bitmap->GetWidth()), cast<int>(bitmap->GetHeight()));
63 PointF origin;
64 StringFormat format(StringAlignment.near, StringAlignment.near);
65 RectF textRect = graphics.MeasureStringChecked(itemName, font, origin, format);
66 textSize = textRect.size;
67 size.w = Max(cast<int>(iconSize.w + iconPadding.Horizontal()), cast<int>(textSize.w + textPadding.Horizontal()));
68 size.h = cast<int>(iconSize.h + iconPadding.Vertical() + textSize.h + textPadding.Vertical());
69 }
70 public void SetLocations(const Point& loc, const Padding& iconPadding, const Padding& textPadding)
71 {
72 location = loc;
73 if (textSize.w > iconSize.w)
74 {
75 iconLocation = Point(cast<int>(location.x + iconPadding.left + ((textSize.w + textPadding.Horizontal()) - (iconSize.w + iconPadding.Horizontal())) / 2), location.y + iconPadding.top);
76 textLocation = PointF(location.x + textPadding.left, location.y + (size.h - textSize.h - textPadding.Vertical()) + textPadding.top);
77 }
78 else
79 {
80 iconLocation = Point(location.x + iconPadding.left, location.y + iconPadding.top);
81 textLocation = PointF(location.x + textPadding.left + ((iconSize.w + iconPadding.Horizontal()) - (textSize.w + textPadding.Horizontal())) / 2, location.y + (size.h - textSize.h - textPadding.Vertical()) + textPadding.top);
82 }
83 }
84 public void Draw(Graphics& graphics, IconListView& iconListView)
85 {
86 if (IsSelected())
87 {
88 SolidBrush& selectedBrush = iconListView.GetSelectedBrush();
89 RectF rect(PointF(location.x, location.y), SizeF(size.w, size.h));
90 graphics.FillRectangleChecked(selectedBrush, rect);
91 }
92 Rect r(iconLocation, iconSize);
93 graphics.DrawImageChecked(*bitmap, r, 0, 0, iconSize.w, iconSize.h, Unit.pixel, iconListView.GetImageAttributes());
94 RectF textRect(textLocation, textSize);
95 graphics.DrawStringChecked(itemName, iconListView.GetFont(), textRect, iconListView.GetStringFormat(), iconListView.GetTextBrush());
96 }
97 public nothrow void SetSelected()
98 {
99 flags = cast<Flags>(flags | Flags.selected);
100 }
101 public nothrow void ResetSelected()
102 {
103 flags = cast<Flags>(flags & ~Flags.selected);
104 }
105 public nothrow bool IsSelected() const
106 {
107 return (flags & Flags.selected) != Flags.none;
108 }
109 private Flags flags;
110 public int index;
111 public string iconName;
112 public string itemName;
113 public Point location;
114 public Size size;
115 public Point iconLocation;
116 public Size iconSize;
117 public PointF textLocation;
118 public SizeF textSize;
119 public Bitmap* bitmap;
120 }
121
122 public nothrow ControlCreateParams& IconListViewControlCreateParams(ControlCreateParams& controlCreateParams)
123 {
124 controlCreateParams.SetWindowClassName("System.Windows.IconListView");
125 controlCreateParams.SetWindowClassStyle(DoubleClickWindowClassStyle());
126 controlCreateParams.SetWindowClassBackgroundColor(SystemColor.COLOR_WINDOW);
127 controlCreateParams.SetBackgroundColor(Color.White());
128 return controlCreateParams;
129 }
130
131 public class IconListViewCreateParams
132 {
133 public nothrow IconListViewCreateParams(ControlCreateParams& controlCreateParams_) :
134 controlCreateParams(controlCreateParams_),
135 fontFamilyName(DefaultIconListViewFontFamilyName()),
136 fontSize(DefaultIconListViewFontSize()),
137 textColor(DefaultIconListViewTextColor()),
138 iconSelectedColor(DefaultIconListViewIconSelectedColor()),
139 bitmapTransparentColor(System.Windows.Color.DefaultBitmapTransparent()),
140 iconPadding(DefaultIconListViewIconPadding()),
141 textPadding(DefaultIconListViewTextPadding()),
142 internalPadding(DefaultIconListViewInternalPadding())
143 {
144 }
145 public IconListViewCreateParams& SetFontFamilyName(const string& fontFamilyName_)
146 {
147 fontFamilyName = fontFamilyName_;
148 return *this;
149 }
150 public IconListViewCreateParams& SetFontSize(float fontSize_)
151 {
152 fontSize = fontSize_;
153 return *this;
154 }
155 public IconListViewCreateParams& SetTextColor(const Color& textColor_)
156 {
157 textColor = textColor_;
158 return *this;
159 }
160 public IconListViewCreateParams& SetIconSelectedColor(const Color& iconSelectedColor_)
161 {
162 iconSelectedColor = iconSelectedColor_;
163 return *this;
164 }
165 public IconListViewCreateParams& SetIconPadding(const Padding& iconPadding_)
166 {
167 iconPadding = iconPadding_;
168 return *this;
169 }
170 public IconListViewCreateParams& SetTextPadding(const Padding& textPadding_)
171 {
172 textPadding = textPadding_;
173 return *this;
174 }
175 public IconListViewCreateParams& SetInternalPadding(const Padding& internalPadding_)
176 {
177 internalPadding = internalPadding_;
178 return *this;
179 }
180 public ControlCreateParams& controlCreateParams;
181 public string fontFamilyName;
182 public float fontSize;
183 public Color textColor;
184 public Color iconSelectedColor;
185 public Color bitmapTransparentColor;
186 public Padding iconPadding;
187 public Padding textPadding;
188 public Padding internalPadding;
189 }
190
191 public class IconListView : Control
192 {
193 private enum Flags : sbyte
194 {
195 none = 0, changed = 1 << 0
196 }
197
198 public IconListView(const System.Windows.Color& backgroundColor, const Point& location, const Size& size, Dock dock, Anchors anchors) :
199 base("System.Windows.IconListView", DoubleClickWindowClassStyle(), DefaultChildWindowStyle(), DefaultExtendedWindowStyle(),
200 backgroundColor, "iconListView", location, size, dock, anchors), items(this), numberOfItems(0),
201 fontFamily(DefaultIconListViewFontFamilyName()),
202 fontSize(DefaultIconListViewFontSize()),
203 font(fontFamily, fontSize),
204 bitmapTransparentColor(System.Windows.Color.DefaultBitmapTransparent()),
205 iconSelectedColor(DefaultIconListViewIconSelectedColor()),
206 textColor(DefaultIconListViewTextColor()),
207 iconPadding(DefaultIconListViewIconPadding()),
208 textPadding(DefaultIconListViewTextPadding()),
209 internalPadding(DefaultIconListViewInternalPadding()),
210 imageAttributes(), stringFormat(StringAlignment.center, StringAlignment.center), selectedItem(null)
211 {
212 imageAttributes.SetColorKeyChecked(bitmapTransparentColor, bitmapTransparentColor, ColorAdjustType.default_);
213 SetChanged();
214 }
215 public IconListView(const Point& location, const Size& size, Dock dock, Anchors anchors) :
216 this(System.Windows.Color.White(), location, size, dock, anchors)
217 {
218 }
219 public IconListView(IconListViewCreateParams& createParams) :
220 base(createParams.controlCreateParams),
221 items(this), numberOfItems(0),
222 fontFamily(createParams.fontFamilyName),
223 fontSize(createParams.fontSize),
224 font(fontFamily, fontSize),
225 bitmapTransparentColor(createParams.bitmapTransparentColor),
226 iconSelectedColor(createParams.iconSelectedColor),
227 textColor(createParams.textColor),
228 iconPadding(createParams.iconPadding),
229 textPadding(createParams.textPadding),
230 internalPadding(createParams.internalPadding),
231 imageAttributes(), stringFormat(StringAlignment.center, StringAlignment.center), selectedItem(null)
232 {
233 imageAttributes.SetColorKeyChecked(bitmapTransparentColor, bitmapTransparentColor, ColorAdjustType.default_);
234 SetChanged();
235 }
236 public void AddItem(const string& iconName, const string& itemName)
237 {
238 UniquePtr<IconListViewItem> item(new IconListViewItem(iconName, itemName));
239 item->index = numberOfItems;
240 item->bitmap = GetOrInsertBitmap(iconName);
241 items.AddChild(item.Release());
242 ++numberOfItems;
243 SetChanged();
244 Invalidate();
245 }
246 protected override void OnMouseDown(MouseEventArgs& args)
247 {
248 if (selectedItem != null)
249 {
250 selectedItem->ResetSelected();
251 }
252 Point loc = args.location;
253 Component* component = items.FirstChild();
254 while (component != null)
255 {
256 if (component is IconListViewItem*)
257 {
258 IconListViewItem* item = cast<IconListViewItem*>(component);
259 Rect rect(item->location, item->size);
260 if (rect.Contains(loc))
261 {
262 item->SetSelected();
263 selectedItem = item;
264 OnSelectedIndexChanged();
265 break;
266 }
267 }
268 component = component->NextSibling();
269 }
270 Invalidate();
271 }
272 protected override void OnMouseDoubleClick(MouseEventArgs& args)
273 {
274 Point loc = args.location;
275 Component* component = items.FirstChild();
276 while (component != null)
277 {
278 if (component is IconListViewItem*)
279 {
280 IconListViewItem* item = cast<IconListViewItem*>(component);
281 Rect rect(item->location, item->size);
282 if (rect.Contains(loc))
283 {
284 item->SetSelected();
285 selectedItem = item;
286 OnDoubleClicked();
287 break;
288 }
289 }
290 component = component->NextSibling();
291 }
292 Invalidate();
293 }
294 public nothrow void SetBitmapTransparentColor(const System.Windows.Color& bitmapTransparentColor_)
295 {
296 bitmapTransparentColor = bitmapTransparentColor_;
297 imageAttributes.SetColorKeyChecked(bitmapTransparentColor, bitmapTransparentColor, ColorAdjustType.default_);
298 }
299 public nothrow void SetIconSelectedColor(const System.Windows.Color& iconSelectedColor_)
300 {
301 iconSelectedColor = iconSelectedColor_;
302 }
303 public nothrow void SetTextColor(const System.Windows.Color& textColor_)
304 {
305 textColor = textColor_;
306 }
307 public nothrow void SetIconPadding(const Padding& iconPadding_)
308 {
309 iconPadding = iconPadding_;
310 }
311 public nothrow void SetTextPadding(const Padding& textPadding_)
312 {
313 textPadding = textPadding_;
314 }
315 public nothrow void SetInternalPadding(const Padding& internalPadding_)
316 {
317 internalPadding = internalPadding_;
318 }
319 public void SetFont(const Font& font_)
320 {
321 font = font_;
322 SetChanged();
323 }
324 internal nothrow const Font& GetFont() const
325 {
326 return font;
327 }
328 internal nothrow const StringFormat& GetStringFormat() const
329 {
330 return stringFormat;
331 }
332 public nothrow Event<IconListViewSelectedIndexChangedEventHandler>& SelectedIndexChangedEvent()
333 {
334 return selectedIndexChangedEvent;
335 }
336 public nothrow Event<IconListViewIconDoubleClickedEventHandler>& IconDoubleClickedEvent()
337 {
338 return iconDoubleClickedEvent;
339 }
340 protected virtual void OnSelectedIndexChanged()
341 {
342 selectedIndexChangedEvent.Fire();
343 }
344 protected virtual void OnDoubleClicked()
345 {
346 iconDoubleClickedEvent.Fire();
347 }
348 public nothrow int GetSelectedIndex() const
349 {
350 if (selectedItem != null)
351 {
352 return selectedItem->index;
353 }
354 else
355 {
356 return -1;
357 }
358 }
359 protected override void OnPaint(PaintEventArgs& args)
360 {
361 try
362 {
363 if (Changed())
364 {
365 ResetChanged();
366 Measure(args.graphics);
367 }
368 args.graphics.Clear(BackgroundColor());
369 Component* component = items.FirstChild();
370 while (component != null)
371 {
372 if (component is IconListViewItem*)
373 {
374 IconListViewItem* item = cast<IconListViewItem*>(component);
375 item->Draw(args.graphics, *this);
376 }
377 component = component->NextSibling();
378 }
379 }
380 catch (const Exception& ex)
381 {
382 MessageBox.Show(ex.Message());
383 }
384 base->OnPaint(args);
385 }
386 private void Measure(Graphics& graphics)
387 {
388 Point loc(internalPadding.left, internalPadding.top);
389 Size size;
390 Component* component = items.FirstChild();
391 while (component != null)
392 {
393 if (component is IconListViewItem*)
394 {
395 IconListViewItem* item = cast<IconListViewItem*>(component);
396 item->Measure(graphics, iconPadding, textPadding, font);
397 item->SetLocations(loc, iconPadding, textPadding);
398 loc.x = loc.x + item->size.w;
399 size.w = size.w + item->size.w;
400 size.h = Max(size.h, item->size.h);
401 }
402 component = component->NextSibling();
403 }
404 size.w = size.w + internalPadding.Horizontal();
405 size.h = size.h + internalPadding.Vertical();
406 SetSize(size);
407 }
408 internal ImageAttributes& GetImageAttributes()
409 {
410 return imageAttributes;
411 }
412 internal SolidBrush& GetTextBrush()
413 {
414 return *GetOrInsertSolidBrush(textColor);
415 }
416 internal SolidBrush& GetSelectedBrush()
417 {
418 return *GetOrInsertSolidBrush(iconSelectedColor);
419 }
420 private Bitmap* GetOrInsertBitmap(const string& bitmapName)
421 {
422 try
423 {
424 HashMap<string, Bitmap*>.ConstIterator it = bitmapMap.CFind(bitmapName);
425 if (it != bitmapMap.CEnd())
426 {
427 return it->second;
428 }
429 UniquePtr<Bitmap> bitmapPtr(new Bitmap(Bitmap.FromResource(bitmapName)));
430 Bitmap* bitmap = bitmapPtr.Get();
431 bitmapMap[bitmapName] = bitmap;
432 bitmaps.Add(Rvalue(bitmapPtr));
433 return bitmap;
434 }
435 catch (const Exception& ex)
436 {
437 throw Exception("could not load bitmap '" + bitmapName + "': " + ex.Message());
438 }
439 return null;
440 }
441 private SolidBrush* GetOrInsertSolidBrush(const System.Windows.Color& color)
442 {
443 HashMap<System.Windows.Color, SolidBrush*>.ConstIterator it = brushMap.CFind(color);
444 if (it != brushMap.CEnd())
445 {
446 return it->second;
447 }
448 else
449 {
450 UniquePtr<SolidBrush> solidBrushPtr(new SolidBrush(color));
451 SolidBrush* solidBrush = solidBrushPtr.Get();
452 brushMap[color] = solidBrush;
453 brushes.Add(Rvalue(solidBrushPtr));
454 return solidBrush;
455 }
456 }
457 private nothrow void SetChanged()
458 {
459 flags = cast<Flags>(flags | Flags.changed);
460 }
461 private nothrow void ResetChanged()
462 {
463 flags = cast<Flags>(flags & ~Flags.changed);
464 }
465 private nothrow bool Changed() const
466 {
467 return (flags & Flags.changed) != Flags.none;
468 }
469 private Flags flags;
470 private Container items;
471 private int numberOfItems;
472 private FontFamily fontFamily;
473 private float fontSize;
474 private Font font;
475 private List<UniquePtr<Bitmap>> bitmaps;
476 private HashMap<string, Bitmap*> bitmapMap;
477 private System.Windows.Color bitmapTransparentColor;
478 private System.Windows.Color iconSelectedColor;
479 private System.Windows.Color textColor;
480 private List<UniquePtr<SolidBrush>> brushes;
481 private HashMap<System.Windows.Color, SolidBrush*> brushMap;
482 private Padding iconPadding;
483 private Padding textPadding;
484 private Padding internalPadding;
485 private ImageAttributes imageAttributes;
486 private StringFormat stringFormat;
487 private IconListViewItem* selectedItem;
488 private Event<IconListViewSelectedIndexChangedEventHandler> selectedIndexChangedEvent;
489 private Event<IconListViewIconDoubleClickedEventHandler> iconDoubleClickedEvent;
490 }
491 }