Mercurial > hg > ucis.core
annotate FBGUI/FBGUI.cs @ 30:24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Thu, 18 Apr 2013 18:48:38 +0200 |
parents | FBGUI.cs@5bfc6c68591e |
children | af27992b5972 |
rev | line source |
---|---|
23 | 1 ???using System; |
2 using System.Collections.Generic; | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
3 using System.Diagnostics; |
23 | 4 using System.Drawing; |
5 using System.Drawing.Drawing2D; | |
6 using System.Drawing.Imaging; | |
7 using System.IO; | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
8 using System.Reflection; |
23 | 9 using System.Threading; |
10 using System.Windows.Forms; | |
11 using UCIS.VNCServer; | |
12 using ThreadingTimer = System.Threading.Timer; | |
13 | |
14 namespace UCIS.FBGUI { | |
15 public interface IFBGControl { | |
16 Rectangle Bounds { get; set; } | |
17 Boolean Visible { get; set; } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
18 FBGCursor Cursor { get; } |
23 | 19 void Paint(Graphics g); |
20 void MouseMove(Point position, MouseButtons buttons); | |
21 void MouseDown(Point position, MouseButtons buttons); | |
22 void MouseUp(Point position, MouseButtons buttons); | |
23 void KeyDown(Keys key); | |
24 void KeyPress(Char keyChar); | |
25 void KeyUp(Keys key); | |
26 void LostKeyboardCapture(); | |
27 void Orphaned(); | |
28 } | |
29 public interface IFBGContainerControl { | |
30 void Invalidate(IFBGControl control, Rectangle rect); | |
31 void AddControl(IFBGControl control); | |
32 void RemoveControl(IFBGControl control); | |
33 Boolean CaptureMouse(IFBGControl control, Boolean capture); | |
34 Boolean CaptureKeyboard(IFBGControl control, Boolean capture); | |
35 } | |
36 public class FBGControl : IFBGControl { | |
37 private Rectangle bounds = new Rectangle(0, 0, 100, 100); | |
38 private Color backColor = Color.Transparent; | |
39 private Boolean visible = true; | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
40 protected FBGCursor CurrentCursor = null; |
23 | 41 public virtual IFBGContainerControl Parent { get; private set; } |
42 public event MouseEventHandler OnMouseDown; | |
43 public event MouseEventHandler OnMouseMove; | |
44 public event MouseEventHandler OnMouseUp; | |
45 public event PaintEventHandler OnPaint; | |
46 public event EventHandler OnResize; | |
47 public event EventHandler OnMove; | |
48 public FBGControl(IFBGContainerControl parent) { | |
49 this.Parent = parent; | |
50 if (Parent != null) Parent.AddControl(this); | |
51 } | |
52 public virtual Rectangle Bounds { | |
53 get { return bounds; } | |
54 set { | |
55 if (bounds == value) return; | |
56 Rectangle old = bounds; | |
57 bounds = value; | |
58 Parent.Invalidate(this, Rectangle.Union(new Rectangle(Point.Empty, value.Size), new Rectangle(old.X - value.X, old.Y - value.Y, old.Width, old.Height))); | |
59 if (value.Location != old.Location) RaiseEvent(OnMove); | |
60 if (value.Size != old.Size) RaiseEvent(OnResize); | |
61 } | |
62 } | |
63 public virtual Boolean Visible { | |
64 get { return visible; } | |
65 set { | |
66 visible = value; | |
67 Invalidate(); | |
68 } | |
69 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
70 FBGCursor IFBGControl.Cursor { get { return CurrentCursor; } } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
71 public virtual FBGCursor Cursor { get { return CurrentCursor; } set { CurrentCursor = value; } } |
23 | 72 public Size Size { get { return Bounds.Size; } set { Rectangle r = Bounds; r.Size = value; Bounds = r; } } |
73 public Point Location { get { return Bounds.Location; } set { Rectangle r = Bounds; r.Location = value; Bounds = r; } } | |
74 public int Left { get { return Bounds.Left; } set { Rectangle r = Bounds; r.X = value; Bounds = r; } } | |
75 public int Top { get { return Bounds.Top; } set { Rectangle r = Bounds; r.Y = value; Bounds = r; } } | |
76 public int Width { get { return Bounds.Width; } set { Rectangle r = Bounds; r.Width = value; Bounds = r; } } | |
77 public int Height { get { return Bounds.Height; } set { Rectangle r = Bounds; r.Height = value; Bounds = r; } } | |
78 public virtual Color BackColor { get { return backColor; } set { if (backColor == value) return; backColor = value; Invalidate(); } } | |
79 public virtual void Invalidate() { | |
80 Invalidate(new Rectangle(Point.Empty, Bounds.Size)); | |
81 } | |
82 public virtual void Invalidate(Rectangle rect) { | |
83 Parent.Invalidate(this, rect); | |
84 } | |
85 void IFBGControl.Paint(Graphics g) { Paint(g); } | |
86 void IFBGControl.MouseMove(Point position, MouseButtons buttons) { MouseMove(position, buttons); } | |
87 void IFBGControl.MouseDown(Point position, MouseButtons buttons) { MouseDown(position, buttons); } | |
88 void IFBGControl.MouseUp(Point position, MouseButtons buttons) { MouseUp(position, buttons); } | |
89 void IFBGControl.KeyDown(Keys g) { KeyDown(g); } | |
90 void IFBGControl.KeyPress(Char g) { KeyPress(g); } | |
91 void IFBGControl.KeyUp(Keys g) { KeyUp(g); } | |
92 void IFBGControl.LostKeyboardCapture() { LostKeyboardCapture(); } | |
93 void IFBGControl.Orphaned() { Orphaned(); } | |
94 protected virtual void Paint(Graphics g) { | |
95 if (!visible) return; | |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
96 if (backColor.A == 0xff) g.Clear(backColor); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
97 else if (backColor.A != 0) using (Brush brush = new SolidBrush(backColor)) g.FillRectangle(brush, g.ClipBounds); |
23 | 98 RaiseEvent(OnPaint, new PaintEventArgs(g, Rectangle.Round(g.ClipBounds))); |
99 } | |
100 protected virtual void MouseMove(Point position, MouseButtons buttons) { RaiseEvent(OnMouseMove, new MouseEventArgs(buttons, 0, position.X, position.Y, 0)); } | |
101 protected virtual void MouseDown(Point position, MouseButtons buttons) { RaiseEvent(OnMouseDown, new MouseEventArgs(buttons, 1, position.X, position.Y, 0)); } | |
102 protected virtual void MouseUp(Point position, MouseButtons buttons) { RaiseEvent(OnMouseUp, new MouseEventArgs(buttons, 1, position.X, position.Y, 0)); } | |
103 protected virtual Boolean CaptureMouse(Boolean capture) { | |
104 return Parent.CaptureMouse(this, capture); | |
105 } | |
106 protected virtual void KeyDown(Keys key) { } | |
107 protected virtual void KeyPress(Char keyChar) { } | |
108 protected virtual void KeyUp(Keys key) { } | |
109 protected virtual Boolean CaptureKeyboard(Boolean capture) { | |
110 return Parent.CaptureKeyboard(this, capture); | |
111 } | |
112 protected virtual void LostKeyboardCapture() { } | |
113 protected virtual void Orphaned() { | |
114 //IDisposable disp = this as IDisposable; | |
115 //if (!ReferenceEquals(disp, null)) disp.Dispose(); | |
116 } | |
117 protected void RaiseEvent(KeyEventHandler eh, KeyEventArgs ea) { if (eh != null) eh(this, ea); } | |
118 protected void RaiseEvent(KeyPressEventHandler eh, KeyPressEventArgs ea) { if (eh != null) eh(this, ea); } | |
119 protected void RaiseEvent(MouseEventHandler eh, MouseEventArgs ea) { if (eh != null) eh(this, ea); } | |
120 protected void RaiseEvent(PaintEventHandler eh, PaintEventArgs ea) { if (eh != null) eh(this, ea); } | |
121 protected void RaiseEvent<T>(EventHandler<T> eh, T ea) where T : EventArgs { if (eh != null) eh(this, ea); } | |
122 protected void RaiseEvent(EventHandler eh, EventArgs ea) { if (eh != null) eh(this, ea); } | |
123 protected void RaiseEvent(EventHandler eh) { if (eh != null) eh(this, new EventArgs()); } | |
124 } | |
125 public class FBGContainerControl : FBGControl, IFBGContainerControl { | |
126 protected List<IFBGControl> controls = new List<IFBGControl>(); | |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
127 protected IFBGControl mouseCaptureControl = null; |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
128 protected IFBGControl keyboardCaptureControl = null; |
23 | 129 private Rectangle childarea = Rectangle.Empty; |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
130 protected FBGCursor DefaultCursor = null; |
23 | 131 public Rectangle ClientRectangle { get { return childarea; } protected set { childarea = value; Invalidate(); } } |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
132 public Size ClientSize { get { return childarea.Size; } set { Bounds = new Rectangle(Bounds.Location, Bounds.Size - childarea.Size + value); } } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
133 public override FBGCursor Cursor { get { return DefaultCursor; } set { DefaultCursor = value; } } |
23 | 134 public FBGContainerControl(IFBGContainerControl parent) : base(parent) { } |
135 void IFBGContainerControl.AddControl(IFBGControl control) { AddControl(control); } | |
136 protected virtual void AddControl(IFBGControl control) { | |
137 controls.Add(control); | |
138 if (control.Visible) Invalidate(control); | |
139 } | |
140 public virtual void RemoveControl(IFBGControl control) { | |
141 if (controls.Remove(control)) { | |
142 if (control.Visible) Invalidate(control); | |
143 CaptureMouse(control, false); | |
144 CaptureKeyboard(control, false); | |
145 control.Orphaned(); | |
146 } | |
147 } | |
148 public virtual Point PointToChild(IFBGControl child, Point point) { | |
149 return point - (Size)child.Bounds.Location - (Size)ClientRectangle.Location; | |
150 } | |
151 public virtual Point PointFromChild(IFBGControl child, Point point) { | |
152 return point + (Size)child.Bounds.Location + (Size)ClientRectangle.Location; | |
153 } | |
154 public virtual void BringControlToFront(IFBGControl control) { | |
155 if (controls.Count == 0) return; | |
156 if (ReferenceEquals(controls[controls.Count - 1], control)) return; | |
157 if (!controls.Remove(control)) return; | |
158 controls.Add(control); | |
159 if (control.Visible) Invalidate(control); | |
160 } | |
161 public virtual void Invalidate(IFBGControl control) { | |
162 Invalidate(new Rectangle(PointFromChild(control, Point.Empty), control.Bounds.Size)); | |
163 } | |
164 public virtual void Invalidate(IFBGControl control, Rectangle rect) { | |
165 Invalidate(new Rectangle(PointFromChild(control, rect.Location), rect.Size)); | |
166 } | |
167 protected override void Paint(Graphics g) { | |
168 base.Paint(g); | |
169 if (controls == null) return; | |
170 GraphicsState state2 = null; | |
171 if (!childarea.IsEmpty) { | |
172 state2 = g.Save(); | |
173 g.TranslateTransform(childarea.X, childarea.Y, MatrixOrder.Append); | |
174 g.IntersectClip(new Rectangle(Point.Empty, childarea.Size)); | |
175 } | |
176 foreach (IFBGControl control in controls) { | |
177 if (!control.Visible) continue; | |
178 if (control.Bounds.Width <= 0 || control.Bounds.Height <= 0) continue; | |
179 if (!g.ClipBounds.IntersectsWith((RectangleF)control.Bounds)) continue; | |
180 GraphicsState state = g.Save(); | |
181 g.TranslateTransform(control.Bounds.X, control.Bounds.Y, MatrixOrder.Append); | |
182 g.IntersectClip(new Rectangle(Point.Empty, control.Bounds.Size)); | |
183 control.Paint(g); | |
184 g.Restore(state); | |
185 } | |
186 if (state2 != null) g.Restore(state2); | |
187 } | |
188 public IFBGControl FindControlAtPosition(Point p) { | |
189 if (!childarea.IsEmpty && !childarea.Contains(p)) return null; | |
190 p.Offset(-childarea.X, -childarea.Y); | |
191 return ((List<IFBGControl>)controls).FindLast(delegate(IFBGControl control) { return control.Visible && control.Bounds.Contains(p); }); | |
192 } | |
193 protected override void MouseMove(Point position, MouseButtons buttons) { | |
194 IFBGControl control = mouseCaptureControl != null ? mouseCaptureControl : FindControlAtPosition(position); | |
195 if (control == null) { | |
196 base.MouseMove(position, buttons); | |
197 } else { | |
198 control.MouseMove(PointToChild(control, position), buttons); | |
199 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
200 CurrentCursor = control == null || control.Cursor == null ? DefaultCursor : control.Cursor; |
23 | 201 } |
202 protected override void MouseDown(Point position, MouseButtons buttons) { | |
203 IFBGControl control = mouseCaptureControl != null ? mouseCaptureControl : FindControlAtPosition(position); | |
204 if (control == null) { | |
205 base.MouseDown(position, buttons); | |
206 } else { | |
207 control.MouseDown(PointToChild(control, position), buttons); | |
208 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
209 CurrentCursor = control == null || control.Cursor == null ? DefaultCursor : control.Cursor; |
23 | 210 } |
211 protected override void MouseUp(Point position, MouseButtons buttons) { | |
212 IFBGControl control = mouseCaptureControl != null ? mouseCaptureControl : FindControlAtPosition(position); | |
213 if (control == null) { | |
214 base.MouseUp(position, buttons); | |
215 } else { | |
216 control.MouseUp(PointToChild(control, position), buttons); | |
217 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
218 CurrentCursor = control == null || control.Cursor == null ? DefaultCursor : control.Cursor; |
23 | 219 } |
220 Boolean IFBGContainerControl.CaptureMouse(IFBGControl control, Boolean capture) { return CaptureMouse(control, capture); } | |
221 protected Boolean CaptureMouse(IFBGControl control, Boolean capture) { | |
222 if (capture && !ReferenceEquals(mouseCaptureControl, null)) return false; | |
223 if (!capture && !ReferenceEquals(mouseCaptureControl, control)) return false; | |
224 if (!CaptureMouse(capture)) return false; | |
225 mouseCaptureControl = capture ? control : null; | |
226 return true; | |
227 } | |
228 protected override void KeyDown(Keys key) { | |
229 if (ReferenceEquals(keyboardCaptureControl, null)) base.KeyDown(key); | |
230 else keyboardCaptureControl.KeyDown(key); | |
231 } | |
232 protected override void KeyPress(Char keyChar) { | |
233 if (ReferenceEquals(keyboardCaptureControl, null)) base.KeyPress(keyChar); | |
234 else keyboardCaptureControl.KeyPress(keyChar); | |
235 } | |
236 protected override void KeyUp(Keys key) { | |
237 if (ReferenceEquals(keyboardCaptureControl, null)) base.KeyUp(key); | |
238 else keyboardCaptureControl.KeyUp(key); | |
239 } | |
240 Boolean IFBGContainerControl.CaptureKeyboard(IFBGControl control, Boolean capture) { return CaptureKeyboard(control, capture); } | |
241 protected Boolean CaptureKeyboard(IFBGControl control, Boolean capture) { | |
242 if (!capture && !ReferenceEquals(keyboardCaptureControl, control)) return false; | |
243 if (!CaptureKeyboard(capture)) return false; | |
244 IFBGControl prev = keyboardCaptureControl; | |
245 keyboardCaptureControl = capture ? control : null; | |
246 if (prev != null) LostKeyboardCapture(); | |
247 return true; | |
248 } | |
249 protected override void LostKeyboardCapture() { | |
250 base.LostKeyboardCapture(); | |
251 if (keyboardCaptureControl != null) keyboardCaptureControl.LostKeyboardCapture(); | |
252 } | |
253 protected override void Orphaned() { | |
254 base.Orphaned(); | |
255 IFBGControl[] c = controls.ToArray(); | |
256 controls.Clear(); | |
257 foreach (IFBGControl control in c) control.Orphaned(); | |
258 mouseCaptureControl = null; | |
259 keyboardCaptureControl = null; | |
260 } | |
261 } | |
262 public class FBGDockContainer : FBGContainerControl { | |
263 private Dictionary<IFBGControl, DockStyle> dockStyles = new Dictionary<IFBGControl, DockStyle>(); | |
264 private Dictionary<IFBGControl, AnchorStyles> anchorStyles = new Dictionary<IFBGControl, AnchorStyles>(); | |
265 private Rectangle oldBounds; | |
266 public FBGDockContainer(IFBGContainerControl parent) | |
267 : base(parent) { | |
268 oldBounds = ClientRectangle.IsEmpty ? Bounds : new Rectangle(Bounds.Location + (Size)ClientRectangle.Location, ClientRectangle.Size); | |
269 } | |
270 protected override void AddControl(IFBGControl control) { | |
271 base.AddControl(control); | |
272 } | |
273 public override void BringControlToFront(IFBGControl control) { | |
274 base.BringControlToFront(control); | |
275 if (dockStyles.ContainsKey(control)) DoLayout(); | |
276 } | |
277 public override void RemoveControl(IFBGControl control) { | |
278 base.RemoveControl(control); | |
279 if (dockStyles.Remove(control)) DoLayout(); | |
280 } | |
281 public override Rectangle Bounds { | |
282 get { return base.Bounds; } | |
283 set { | |
284 base.Bounds = value; | |
285 DoLayout(); | |
286 Rectangle newBounds = ClientRectangle.IsEmpty ? Bounds : new Rectangle(Bounds.Location + (Size)ClientRectangle.Location, ClientRectangle.Size); | |
287 foreach (KeyValuePair<IFBGControl, AnchorStyles> c in anchorStyles) { | |
288 Rectangle b = c.Key.Bounds; | |
289 if ((c.Value & AnchorStyles.Right) != 0) { | |
290 if ((c.Value & AnchorStyles.Left) == 0) b.X += newBounds.Width - oldBounds.Width; | |
291 else b.Width += newBounds.Width - oldBounds.Width; | |
292 } else if ((c.Value & AnchorStyles.Left) == 0) b.X += newBounds.X - oldBounds.X; | |
293 if ((c.Value & AnchorStyles.Bottom) != 0) { | |
294 if ((c.Value & AnchorStyles.Top) == 0) b.Y += newBounds.Height - oldBounds.Height; | |
295 else b.Height += newBounds.Height - oldBounds.Height; | |
296 } else if ((c.Value & AnchorStyles.Top) == 0) b.Y += newBounds.Y - oldBounds.Y; | |
297 c.Key.Bounds = b; | |
298 } | |
299 oldBounds = newBounds; | |
300 } | |
301 } | |
302 public DockStyle GetDockStyle(IFBGControl control) { | |
303 DockStyle ds; | |
304 if (!dockStyles.TryGetValue(control, out ds)) ds = DockStyle.None; | |
305 return ds; | |
306 } | |
307 public void SetDockStyle(IFBGControl control, DockStyle style) { | |
308 if (style == DockStyle.None) { | |
309 if (dockStyles.Remove(control)) DoLayout(); | |
310 } else if (controls.Contains(control)) { | |
311 anchorStyles.Remove(control); | |
312 dockStyles[control] = style; | |
313 DoLayout(); | |
314 } | |
315 } | |
316 public AnchorStyles GetAnchorStyle(IFBGControl control) { | |
317 AnchorStyles ds; | |
318 if (!anchorStyles.TryGetValue(control, out ds)) ds = AnchorStyles.Left | AnchorStyles.Top; | |
319 return ds; | |
320 } | |
321 public void SetAnchorStyle(IFBGControl control, AnchorStyles style) { | |
322 if (style == (AnchorStyles.Left | AnchorStyles.Top)) { | |
323 anchorStyles.Remove(control); | |
324 } else if (controls.Contains(control)) { | |
325 dockStyles.Remove(control); | |
326 anchorStyles[control] = style; | |
327 } | |
328 } | |
329 public void SetAnchor(IFBGControl control, AnchorStyles style, int value) { | |
330 if (controls.Contains(control)) { | |
331 AnchorStyles oldstyle; | |
332 if (!anchorStyles.TryGetValue(control, out oldstyle)) oldstyle = AnchorStyles.Left | AnchorStyles.Top; | |
333 Rectangle b = control.Bounds; | |
334 switch (style) { | |
335 case AnchorStyles.None: throw new ArgumentException("style", "Anchor style can not be None"); | |
336 case AnchorStyles.Left: b.X = value; break; | |
337 case AnchorStyles.Top: b.Y = value; break; | |
338 case AnchorStyles.Right: | |
339 if ((oldstyle & AnchorStyles.Left) == 0) b.X = ClientRectangle.Width - b.Width - value; | |
340 else b.Width = ClientRectangle.Width - b.X - value; | |
341 break; | |
342 case AnchorStyles.Bottom: | |
343 if ((oldstyle & AnchorStyles.Top) == 0) b.Y = ClientRectangle.Height - b.Height - value; | |
344 else b.Height = ClientRectangle.Height - b.Y - value; | |
345 break; | |
346 default: throw new ArgumentOutOfRangeException("style", "The value vor the style argument is invalid"); | |
347 } | |
348 control.Bounds = b; | |
349 dockStyles.Remove(control); | |
350 anchorStyles[control] = oldstyle | style; | |
351 } | |
352 } | |
353 private void DoLayout() { | |
354 Rectangle a = new Rectangle(Point.Empty, ClientRectangle.IsEmpty ? Bounds.Size : ClientRectangle.Size); | |
355 foreach (KeyValuePair<IFBGControl, DockStyle> c in dockStyles) { | |
356 Rectangle b = c.Key.Bounds; | |
357 if (c.Value == DockStyle.Left) { | |
358 b.Location = a.Location; | |
359 b.Height = a.Height; | |
360 a.X += b.Width; | |
361 a.Width -= b.Width; | |
362 } else if (c.Value == DockStyle.Top) { | |
363 b.Location = a.Location; | |
364 b.Width = a.Width; | |
365 a.Y += b.Height; | |
366 a.Height -= b.Height; | |
367 } else if (c.Value == DockStyle.Right) { | |
368 b.X = a.X + a.Width - b.Width; | |
369 b.Y = a.Y; | |
370 b.Height = a.Height; | |
371 a.Width -= b.Width; | |
372 } else if (c.Value == DockStyle.Bottom) { | |
373 b.X = a.X; | |
374 b.Y = a.Y + a.Height - b.Height; | |
375 b.Width = a.Width; | |
376 a.Height -= b.Height; | |
377 } else if (c.Value == DockStyle.Fill) { | |
378 b = a; | |
379 } | |
380 c.Key.Bounds = b; | |
381 if (a.Width < 0) a.Width = 0; | |
382 if (a.Height < 0) a.Height = 0; | |
383 } | |
384 } | |
385 } | |
386 public class FBGGroupBox : FBGDockContainer { | |
387 private String text = String.Empty; | |
388 public FBGGroupBox(IFBGContainerControl parent) | |
389 : base(parent) { | |
390 ClientRectangle = new Rectangle(1, 15, Bounds.Width - 2, Bounds.Height - 17); | |
391 } | |
392 public override Rectangle Bounds { | |
393 get { return base.Bounds; } | |
394 set { | |
395 ClientRectangle = new Rectangle(1, 15, value.Width - 2, value.Height - 17); | |
396 base.Bounds = value; | |
397 } | |
398 } | |
399 public String Text { get { return text; } set { if (text == value) return; text = value; Invalidate(new Rectangle(0, 0, Bounds.Width, 15)); } } | |
400 protected override void Paint(Graphics g) { | |
401 base.Paint(g); | |
402 g.DrawRectangle(Pens.Gray, 0, 6, Bounds.Width - 1, Bounds.Height - 7); | |
403 SizeF ss = g.MeasureString(Text, SystemFonts.DefaultFont, new Size(Bounds.Width - 10 - 9, 15)); | |
404 g.FillRectangle(SystemBrushes.Control, 9, 0, ss.Width, ss.Height); | |
405 g.DrawString(Text, SystemFonts.DefaultFont, Brushes.DarkBlue, new Rectangle(9, 0, Bounds.Width - 10 - 9, 15)); | |
406 } | |
407 } | |
408 public class WinFormsFBGHost : Control, IFBGContainerControl { | |
409 private IFBGControl childControl = null; | |
410 private IFBGControl mouseCaptureControl = null; | |
411 private IFBGControl keyboardCaptureControl = null; | |
412 public IFBGControl ChildControl { get { return childControl; } } | |
413 | |
414 public WinFormsFBGHost() { | |
415 DoubleBuffered = true; | |
416 } | |
417 | |
418 public virtual Point PointToChild(IFBGControl child, Point point) { | |
419 return point - (Size)child.Bounds.Location; | |
420 } | |
421 public virtual Point PointFromChild(IFBGControl child, Point point) { | |
422 return point + (Size)child.Bounds.Location; | |
423 } | |
424 | |
425 void IFBGContainerControl.Invalidate(IFBGControl control, Rectangle rect) { | |
426 Invalidate(new Rectangle(PointFromChild(control, rect.Location), rect.Size)); | |
427 } | |
428 void IFBGContainerControl.AddControl(IFBGControl control) { | |
429 if (!ReferenceEquals(childControl, null)) throw new InvalidOperationException("This container can have only one child control"); | |
430 childControl = control; | |
431 control.Bounds = new Rectangle(Point.Empty, ClientSize); | |
432 Invalidate(control.Bounds); | |
433 } | |
434 void IFBGContainerControl.RemoveControl(IFBGControl control) { | |
435 if (!ReferenceEquals(childControl, control)) return; | |
436 childControl = null; | |
437 Invalidate(control.Bounds); | |
438 if (mouseCaptureControl == control) mouseCaptureControl = null; | |
439 if (keyboardCaptureControl == control) control = null; | |
440 control.Orphaned(); | |
441 } | |
442 Boolean IFBGContainerControl.CaptureMouse(IFBGControl control, Boolean capture) { | |
443 if (capture && !ReferenceEquals(mouseCaptureControl, null)) return false; | |
444 if (!capture && !ReferenceEquals(mouseCaptureControl, control)) return false; | |
445 mouseCaptureControl = capture ? control : null; | |
446 return true; | |
447 } | |
448 Boolean IFBGContainerControl.CaptureKeyboard(IFBGControl control, Boolean capture) { | |
449 if (!capture && !ReferenceEquals(keyboardCaptureControl, control)) return false; | |
450 keyboardCaptureControl = capture ? control : null; | |
451 return true; | |
452 } | |
453 | |
454 protected override void OnPaint(PaintEventArgs e) { | |
455 base.OnPaint(e); | |
456 Graphics g = e.Graphics; | |
457 GraphicsState state = g.Save(); | |
458 g.SetClip(e.ClipRectangle); | |
459 if (ReferenceEquals(childControl, null)) return; | |
460 if (childControl.Bounds.Width <= 0 || childControl.Bounds.Height <= 0) return; | |
461 if (!g.ClipBounds.IntersectsWith((RectangleF)childControl.Bounds)) return; | |
462 g.TranslateTransform(childControl.Bounds.X, childControl.Bounds.Y, MatrixOrder.Append); | |
463 g.IntersectClip(new Rectangle(Point.Empty, childControl.Bounds.Size)); | |
464 childControl.Paint(g); | |
465 g.Restore(state); | |
466 } | |
467 protected override void OnResize(EventArgs e) { | |
468 if (!ReferenceEquals(childControl, null)) childControl.Bounds = new Rectangle(Point.Empty, ClientSize); | |
469 base.OnResize(e); | |
470 } | |
471 protected override void OnMouseDown(MouseEventArgs e) { | |
472 base.OnMouseDown(e); | |
473 IFBGControl control = mouseCaptureControl != null ? mouseCaptureControl : childControl; | |
474 if (control != null) control.MouseDown(PointToChild(control, e.Location), e.Button); | |
475 } | |
476 protected override void OnMouseUp(MouseEventArgs e) { | |
477 base.OnMouseUp(e); | |
478 IFBGControl control = mouseCaptureControl != null ? mouseCaptureControl : childControl; | |
479 if (control != null) control.MouseUp(PointToChild(control, e.Location), e.Button); | |
480 } | |
481 protected override void OnMouseMove(MouseEventArgs e) { | |
482 IFBGControl control = mouseCaptureControl != null ? mouseCaptureControl : childControl; | |
483 if (control != null) control.MouseMove(PointToChild(control, e.Location), e.Button); | |
484 } | |
485 protected override bool IsInputChar(char charCode) { | |
486 return true; | |
487 } | |
488 protected override bool IsInputKey(Keys keyData) { | |
489 return true; | |
490 } | |
491 protected override void OnKeyDown(KeyEventArgs e) { | |
492 //base.OnKeyDown(e); | |
493 if (!ReferenceEquals(keyboardCaptureControl, null)) keyboardCaptureControl.KeyDown(e.KeyData); | |
494 } | |
495 protected override void OnKeyPress(KeyPressEventArgs e) { | |
496 //base.OnKeyPress(e); | |
497 if (!ReferenceEquals(keyboardCaptureControl, null)) keyboardCaptureControl.KeyPress(e.KeyChar); | |
498 } | |
499 protected override void OnKeyUp(KeyEventArgs e) { | |
500 //base.OnKeyUp(e); | |
501 if (!ReferenceEquals(keyboardCaptureControl, null)) keyboardCaptureControl.KeyUp(e.KeyData); | |
502 } | |
503 protected override void OnHandleDestroyed(EventArgs e) { | |
504 if (!ReferenceEquals(childControl, null)) childControl.Orphaned(); | |
505 base.OnHandleDestroyed(e); | |
506 } | |
507 } | |
508 public class FBGCursor { | |
509 public Image Image { get; private set; } | |
510 public Point Hotspot { get; private set; } | |
511 public Size Size { get; private set; } | |
512 public FBGCursor(Image image, Point hotspot) { | |
513 this.Image = image; | |
514 this.Hotspot = hotspot; | |
515 this.Size = image.Size; | |
516 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
517 public Rectangle Area { get { return new Rectangle(-Hotspot.X, -Hotspot.Y, Size.Width, Size.Height); } } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
518 public FBGCursor RotateFlip(RotateFlipType type) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
519 Image img = new Bitmap(Image); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
520 img.RotateFlip(type); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
521 Point hs = Hotspot; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
522 switch (type) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
523 case RotateFlipType.RotateNoneFlipNone: break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
524 case RotateFlipType.Rotate90FlipNone: hs = new Point(img.Width - hs.Y, hs.X); break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
525 case RotateFlipType.Rotate180FlipNone: hs = new Point(img.Width - hs.X, img.Height - hs.Y); break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
526 case RotateFlipType.Rotate270FlipNone: hs = new Point(hs.Y, img.Height - hs.X); break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
527 case RotateFlipType.RotateNoneFlipX: hs.X = img.Width - hs.X; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
528 case RotateFlipType.Rotate90FlipX: hs = new Point(hs.Y, hs.X); break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
529 case RotateFlipType.RotateNoneFlipY: hs.Y = img.Height - hs.Y; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
530 case RotateFlipType.Rotate90FlipY: hs = new Point(img.Width - hs.Y, img.Height - hs.X); break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
531 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
532 return new FBGCursor(img, hs); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
533 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
534 public static FBGCursor FromBase64Image(String data, Point hotspot) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
535 return new FBGCursor(Image.FromStream(new MemoryStream(Convert.FromBase64String(data))), hotspot); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
536 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
537 private static FBGCursor LoadFromResource(String name, int hotX, int hotY) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
538 using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("UCIS.FBGUI." + name + ".png")) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
539 return new FBGCursor(Image.FromStream(s), new Point(hotX, hotY)); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
540 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
541 } |
23 | 542 |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
543 public static readonly FBGCursor Arrow = LoadFromResource("cursor_arrow", 0, 0); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
544 public static readonly FBGCursor Move = LoadFromResource("cursor_move", 8, 8); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
545 public static readonly FBGCursor SizeLeft = LoadFromResource("cursor_left", 1, 10); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
546 public static readonly FBGCursor SizeRight = SizeLeft.RotateFlip(RotateFlipType.RotateNoneFlipX); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
547 public static readonly FBGCursor SizeTop = SizeLeft.RotateFlip(RotateFlipType.Rotate90FlipNone); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
548 public static readonly FBGCursor SizeBottom = SizeLeft.RotateFlip(RotateFlipType.Rotate90FlipY); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
549 public static readonly FBGCursor SizeTopLeft = LoadFromResource("cursor_topleft", 1, 1); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
550 public static readonly FBGCursor SizeTopRight = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipX); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
551 public static readonly FBGCursor SizeBottomLeft = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipY); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
552 public static readonly FBGCursor SizeBottomRight = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipXY); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
553 public static FBGCursor ArrowCursor { get { return Arrow; } } |
23 | 554 } |
555 public class FBGRenderer : FBGContainerControl, IDisposable { | |
556 private FBGCursor cursor = null; | |
557 private Point cursorposition = Point.Empty; | |
558 public IFramebuffer Framebuffer { get; private set; } | |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
559 private Bitmap Frontbuffer = null; |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
560 protected Object RenderLock = new object(); |
23 | 561 public event EventHandler<InvalidateEventArgs> Painted; |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
562 protected Size size = Size.Empty; |
23 | 563 private ThreadingTimer PaintTimer = null; |
564 private Boolean PaintScheduled = false; | |
565 private int PaintDelay = 0; | |
566 public Boolean SuspendDrawing { | |
567 get { return suspenddrawing; } | |
568 set { | |
569 lock (RenderLock) { | |
570 suspenddrawing = value; | |
571 if (!value) { | |
572 Refresh(DirtyRectangle); | |
573 DirtyRectangle = Rectangle.Empty; | |
574 } | |
575 } | |
576 } | |
577 } | |
578 public int RedrawDelay { | |
579 get { return PaintDelay; } | |
580 set { | |
581 lock (RenderLock) { | |
582 if (value < 0) throw new ArgumentOutOfRangeException("value"); | |
583 PaintDelay = value; | |
584 if (PaintDelay == 0) { | |
585 if (PaintTimer != null) PaintTimer.Dispose(); | |
586 PaintTimer = null; | |
587 if (PaintScheduled) PaintTimerCallback(null); | |
588 } else { | |
589 PaintTimer = new ThreadingTimer(PaintTimerCallback); | |
590 } | |
591 } | |
592 } | |
593 } | |
594 private Boolean suspenddrawing = false; | |
595 private Rectangle DirtyRectangle; | |
596 | |
597 public Point CursorPosition { | |
598 get { return cursorposition; } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
599 set { UpdateCursor(value, cursor); } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
600 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
601 protected void UpdateCursor(Point position, FBGCursor cursor) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
602 if (cursorposition == position && cursor == this.cursor) return; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
603 Rectangle r1 = Rectangle.Empty; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
604 if (this.cursor != null) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
605 r1 = this.cursor.Area; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
606 r1.Offset(cursorposition); |
23 | 607 } |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
608 if (cursor != null) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
609 Rectangle r2 = cursor.Area; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
610 r2.Offset(position); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
611 r1 = r1.IsEmpty ? r2 : Rectangle.Union(r1, r2); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
612 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
613 this.cursor = cursor; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
614 cursorposition = position; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
615 Invalidate(r1); |
23 | 616 } |
617 public override Rectangle Bounds { | |
618 get { return new Rectangle(Point.Empty, size); } | |
619 set { throw new NotSupportedException("Can not change the top control bounds"); } | |
620 } | |
621 public FBGRenderer(IFramebuffer fb) : this(fb.Width, fb.Height) { | |
622 Framebuffer = fb; | |
623 } | |
624 public FBGRenderer(Size fbsize) : this(fbsize.Width, fbsize.Height) { } | |
625 public FBGRenderer(int width, int height) : this(new Bitmap(width, height, PixelFormat.Format32bppRgb)) { } | |
626 public FBGRenderer(Bitmap bmp) : base(null) { | |
627 Frontbuffer = bmp; | |
628 BackColor = SystemColors.Control; | |
629 size = Frontbuffer.Size; | |
630 } | |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
631 protected FBGRenderer() : base(null) { |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
632 BackColor = SystemColors.Control; |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
633 } |
23 | 634 public override void Invalidate(Rectangle rect) { |
635 if (rect.Width == 0 || rect.Height == 0) return; | |
636 lock (RenderLock) { | |
637 if (SuspendDrawing || PaintTimer != null) { | |
638 DirtyRectangle = DirtyRectangle.IsEmpty ? rect : Rectangle.Union(DirtyRectangle, rect); | |
639 if (!SuspendDrawing && !PaintScheduled) { | |
640 PaintScheduled = true; | |
641 PaintTimer.Change(PaintDelay, Timeout.Infinite); | |
642 } | |
643 } else { | |
644 Refresh(rect); | |
645 } | |
646 } | |
647 } | |
648 private void PaintTimerCallback(Object state) { | |
649 try { | |
650 lock (RenderLock) { | |
651 PaintScheduled = false; | |
652 Refresh(DirtyRectangle); | |
653 DirtyRectangle = Rectangle.Empty; | |
654 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
655 } catch (Exception ex) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
656 Debug.WriteLine(ex); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
657 Console.Error.WriteLine(ex); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
658 } |
23 | 659 } |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
660 protected virtual void Refresh(Rectangle rect) { |
23 | 661 lock (RenderLock) { |
662 rect.Intersect(Bounds); | |
663 if (rect.Width == 0 || rect.Height == 0) return; | |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
664 if (Frontbuffer != null) { |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
665 using (Graphics g = Graphics.FromImage(Frontbuffer)) { |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
666 g.SetClip(rect); |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
667 Paint(g); |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
668 } |
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
669 if (Framebuffer != null) Framebuffer.DrawImage(Frontbuffer, rect, rect.Location); |
23 | 670 } |
671 RaiseEvent(Painted, new InvalidateEventArgs(rect)); | |
672 } | |
673 } | |
674 protected override void Paint(Graphics g) { | |
675 base.Paint(g); | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
676 if (cursor != null) { |
23 | 677 Point r = CursorPosition; |
678 r.Offset(-cursor.Hotspot.X, -cursor.Hotspot.Y); | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
679 g.DrawImage(cursor.Image, new Rectangle(r, cursor.Size)); |
23 | 680 } |
681 } | |
682 protected override Boolean CaptureMouse(Boolean capture) { | |
683 return true; | |
684 } | |
685 protected override Boolean CaptureKeyboard(bool capture) { | |
686 return true; | |
687 } | |
26
7f0b7a53a000
FBGUI: Allow derived classes to access some internals
Ivo Smits <Ivo@UCIS.nl>
parents:
23
diff
changeset
|
688 public virtual void Dispose() { |
23 | 689 lock (RenderLock) { |
690 if (PaintTimer != null) PaintTimer.Dispose(); | |
691 PaintTimer = null; | |
692 } | |
693 Orphaned(); | |
694 if (Frontbuffer != null) Frontbuffer.Dispose(); | |
695 } | |
696 public Bitmap LockBitmapBuffer() { | |
697 Monitor.Enter(RenderLock); | |
698 return Frontbuffer; | |
699 } | |
700 public void UnlockBitmapBuffer() { | |
701 Monitor.Exit(RenderLock); | |
702 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
703 public new void MouseMove(Point position, MouseButtons buttons) { base.MouseMove(position, buttons); UpdateCursor(cursorposition, CurrentCursor); } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
704 public new void MouseDown(Point position, MouseButtons buttons) { base.MouseDown(position, buttons); UpdateCursor(cursorposition, CurrentCursor); } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
705 public new void MouseUp(Point position, MouseButtons buttons) { base.MouseUp(position, buttons); UpdateCursor(cursorposition, CurrentCursor); } |
23 | 706 public new void KeyDown(Keys key) { base.KeyDown(key); } |
707 public new void KeyPress(Char key) { base.KeyPress(key); } | |
708 public new void KeyUp(Keys key) { base.KeyUp(key); } | |
709 } | |
710 public class FBGForm : FBGDockContainer { | |
711 private Point prevPosition = Point.Empty; | |
712 private NonClientOps moveresize = 0; | |
713 private String text = String.Empty; | |
714 public event EventHandler TextChanged; | |
715 public Boolean Sizable { get; set; } | |
716 public Boolean Movable { get; set; } | |
717 public Boolean Closable { get; set; } | |
718 [Flags] | |
719 private enum NonClientOps : int { | |
720 None = 0, | |
721 Move = 1, | |
722 ResizeLeft = 2, | |
723 ResizeRight = 4, | |
724 ResizeTop = 8, | |
725 ResizeBottom = 16, | |
726 ButtonClose = 32, | |
727 MoveResize = ResizeLeft | ResizeRight | ResizeBottom | ResizeTop | Move, | |
728 } | |
729 public FBGForm(IFBGContainerControl parent) : base(parent) { | |
730 BackColor = SystemColors.Control; | |
731 ClientRectangle = new Rectangle(4, 22, Bounds.Width - 8, Bounds.Height - 26); | |
732 Sizable = true; | |
733 Movable = true; | |
734 Closable = false; | |
735 } | |
736 public override Rectangle Bounds { | |
737 get { return base.Bounds; } | |
738 set { | |
739 ClientRectangle = new Rectangle(4, 22, value.Width - 8, value.Height - 26); | |
740 base.Bounds = value; | |
741 } | |
742 } | |
743 public String Text { get { return text; } set { if (text == value) return; text = value; Invalidate(new Rectangle(0, 0, Bounds.Width, 20)); RaiseEvent(TextChanged); } } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
744 private NonClientOps GetNonClientOperation(Point p) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
745 if ((new Rectangle(Bounds.Width - 5 - 14, 4, 14, 14)).Contains(p)) return NonClientOps.ButtonClose; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
746 NonClientOps mr = 0; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
747 if (Sizable) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
748 if (Movable) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
749 if (p.X < 4) mr |= NonClientOps.ResizeLeft; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
750 if (p.Y < 4) mr |= NonClientOps.ResizeTop; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
751 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
752 if (p.X >= Bounds.Width - 4) mr |= NonClientOps.ResizeRight; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
753 if (p.Y >= Bounds.Height - 4) mr |= NonClientOps.ResizeBottom; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
754 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
755 if (mr == 0 && Movable && p.Y < 20) mr = NonClientOps.Move; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
756 return mr; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
757 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
758 private void SetCursorForNonClientOperation(NonClientOps op) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
759 switch (op & NonClientOps.MoveResize) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
760 case NonClientOps.Move: CurrentCursor = FBGCursor.Move; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
761 case NonClientOps.ResizeLeft: CurrentCursor = FBGCursor.SizeLeft; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
762 case NonClientOps.ResizeRight: CurrentCursor = FBGCursor.SizeRight; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
763 case NonClientOps.ResizeBottom: CurrentCursor = FBGCursor.SizeBottom; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
764 case NonClientOps.ResizeTop: CurrentCursor = FBGCursor.SizeTop; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
765 case NonClientOps.ResizeTop | NonClientOps.ResizeLeft: CurrentCursor = FBGCursor.SizeTopLeft; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
766 case NonClientOps.ResizeTop | NonClientOps.ResizeRight: CurrentCursor = FBGCursor.SizeTopRight; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
767 case NonClientOps.ResizeBottom | NonClientOps.ResizeLeft: CurrentCursor = FBGCursor.SizeBottomLeft; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
768 case NonClientOps.ResizeBottom | NonClientOps.ResizeRight: CurrentCursor = FBGCursor.SizeBottomRight; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
769 default: CurrentCursor = DefaultCursor; break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
770 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
771 } |
23 | 772 protected override void MouseDown(Point p, MouseButtons buttons) { |
773 NonClientOps mr = 0; | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
774 if ((buttons & MouseButtons.Left) != 0) mr = GetNonClientOperation(p); |
23 | 775 if (mr != 0) { |
776 moveresize = mr; | |
777 prevPosition = p; | |
778 CaptureMouse(true); | |
779 } else { | |
780 base.MouseDown(p, buttons); | |
781 } | |
782 } | |
783 protected override void MouseMove(Point position, MouseButtons buttons) { | |
784 if (moveresize == 0) { | |
785 base.MouseMove(position, buttons); | |
786 } else if ((moveresize & NonClientOps.MoveResize) != 0) { | |
787 Rectangle b = Bounds; | |
788 int dx = position.X - prevPosition.X; | |
789 int dy = position.Y - prevPosition.Y; | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
790 if (moveresize == NonClientOps.Move) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
791 b.Offset(dx, dy); |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
792 } |
23 | 793 if ((moveresize & NonClientOps.ResizeLeft) != 0) { |
794 b.X += dx; | |
795 b.Width -= dx; | |
796 } else if ((moveresize & NonClientOps.ResizeRight) != 0) { | |
797 b.Width += dx; | |
798 prevPosition.X = position.X; | |
799 } | |
800 if ((moveresize & NonClientOps.ResizeTop) != 0) { | |
801 b.Y += dy; | |
802 b.Height -= dy; | |
803 } else if ((moveresize & NonClientOps.ResizeBottom) != 0) { | |
804 b.Height += dy; | |
805 prevPosition.Y = position.Y; | |
806 } | |
807 if (b.Width < 55) b.Width = 55; | |
808 if (b.Height < 25) b.Height = 25; | |
809 Bounds = b; | |
810 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
811 SetCursorForNonClientOperation(moveresize == 0 ? GetNonClientOperation(position) : moveresize); |
23 | 812 } |
813 protected override void MouseUp(Point position, MouseButtons buttons) { | |
814 if (moveresize == 0) { | |
815 base.MouseUp(position, buttons); | |
816 } else if ((buttons & MouseButtons.Left) != 0) { | |
817 MouseMove(position, buttons); | |
818 CaptureMouse(false); | |
819 if (moveresize == NonClientOps.ButtonClose && (new Rectangle(Bounds.Width - 5 - 14, 4, 14, 14)).Contains(position) && Closable) Close(); | |
820 moveresize = 0; | |
821 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
822 SetCursorForNonClientOperation(moveresize == 0 ? GetNonClientOperation(position) : moveresize); |
23 | 823 } |
824 protected override void Paint(Graphics g) { | |
825 base.Paint(g); | |
826 g.DrawRectangle(Pens.Gray, 0, 0, Bounds.Width - 1, Bounds.Height - 1); | |
827 g.DrawRectangle(Pens.LightGray, 1, 1, Bounds.Width - 3, Bounds.Height - 3); | |
828 g.DrawRectangle(Pens.DarkGray, 2, 20, Bounds.Width - 5, Bounds.Height - 23); | |
829 g.DrawRectangle(Pens.Gray, 3, 21, Bounds.Width - 7, Bounds.Height - 25); | |
830 using (Brush b = new LinearGradientBrush(new Rectangle(0, 1, 1, 18), Color.Gray, Color.LightGray, LinearGradientMode.Vertical)) | |
831 g.FillRectangle(b, 2, 2, Bounds.Width - 4, 18); | |
832 | |
833 g.DrawString(Text, SystemFonts.CaptionFont, Brushes.Black, 4, 1); | |
834 | |
835 g.DrawRectangle(Pens.Gray, Bounds.Width - 5 - 14, 4, 14, 14); | |
836 g.DrawRectangle(Pens.Gray, Bounds.Width - 5 - 14 - 16, 4, 14, 14); | |
837 g.DrawRectangle(Pens.Gray, Bounds.Width - 5 - 14 - 32, 4, 14, 14); | |
838 using (Brush b = new LinearGradientBrush(new Rectangle(0, 5, 1, 13), Color.LightGray, Color.DarkGray, LinearGradientMode.Vertical)) { | |
839 g.FillRectangle(b, Bounds.Width - 5 - 14 + 1, 5, 13, 13); | |
840 g.FillRectangle(b, Bounds.Width - 5 - 14 + 1 - 16, 5, 13, 13); | |
841 g.FillRectangle(b, Bounds.Width - 5 - 14 + 1 - 32, 5, 13, 13); | |
842 } | |
843 if (Closable) { | |
844 g.DrawLine(Pens.Black, Bounds.Width - 5 - 14 + 3, 4 + 3, Bounds.Width - 5 - 14 + 14 - 3, 4 + 14 - 3); | |
845 g.DrawLine(Pens.Black, Bounds.Width - 5 - 14 + 3, 4 + 14 - 3, Bounds.Width - 5 - 14 + 14 - 3, 4 + 3); | |
846 } | |
847 } | |
848 public void Close() { | |
849 Parent.RemoveControl(this); | |
850 } | |
851 } | |
852 public class FBGDesktop : FBGContainerControl { | |
853 FBGContainerControl windowcontainer; | |
854 FBGContainerControl menucontainer; | |
855 Boolean startup = true; | |
856 class FBGWindowState { | |
857 public IFBGControl Control; | |
858 public FBGButton MenuButton; | |
859 public Boolean Visible; | |
860 public Rectangle OldBounds; | |
861 public FBGWindowState(IFBGControl cntrl, FBGButton btn) { | |
862 Control = cntrl; | |
863 MenuButton = btn; | |
864 Visible = true; | |
865 } | |
866 } | |
867 Dictionary<IFBGControl, FBGWindowState> windowstates = new Dictionary<IFBGControl, FBGWindowState>(); | |
868 public FBGDesktop(IFBGContainerControl parent) : base(parent) { | |
869 menucontainer = new FBGContainerControl(this); | |
870 menucontainer.Bounds = new Rectangle(0, Bounds.Height - 25, Bounds.Width, 25); | |
871 windowcontainer = new FBGContainerControl(this); | |
872 windowcontainer.Bounds = new Rectangle(0, 0, Bounds.Width, Bounds.Height - 25); | |
873 startup = false; | |
874 } | |
875 public override Rectangle Bounds { | |
876 get { return base.Bounds; } | |
877 set { | |
878 if (Bounds == value) return; | |
879 base.Bounds = value; | |
880 if (startup) return; | |
881 menucontainer.Bounds = new Rectangle(0, value.Height - 25, value.Width, 25); | |
882 windowcontainer.Bounds = new Rectangle(0, 0, value.Width, value.Height - 25); | |
883 ScaleMenuButtons(); | |
884 } | |
885 } | |
886 protected override void AddControl(IFBGControl control) { | |
887 if (startup) { | |
888 base.AddControl(control); | |
889 return; | |
890 } | |
891 ((IFBGContainerControl)windowcontainer).AddControl(control); | |
892 FBGButton btn = new FBGButton(menucontainer); | |
893 FBGForm formcontrol = control as FBGForm; | |
894 if (formcontrol == null) { | |
895 btn.Text = "Untitled"; | |
896 } else { | |
897 formcontrol.TextChanged += delegate(Object sender, EventArgs e) { | |
898 btn.Text = formcontrol.Text; | |
899 }; | |
900 btn.Text = formcontrol.Text; | |
901 } | |
902 FBGWindowState ws = new FBGWindowState(control, btn); | |
903 windowstates.Add(control, ws); | |
904 ScaleMenuButtons(); | |
905 btn.Click += delegate(Object sender, EventArgs e) { | |
906 if (ws.Visible) { | |
907 if (ws.MenuButton.BackColor == Color.DarkGray) { | |
908 ws.OldBounds = ws.Control.Bounds; | |
909 ws.Visible = false; | |
910 ws.Control.Bounds = Rectangle.Empty; | |
911 } else { | |
912 windowcontainer.BringControlToFront(ws.Control); | |
913 foreach (FBGWindowState wsa in windowstates.Values) if (!ReferenceEquals(ws, wsa)) wsa.MenuButton.BackColor = SystemColors.ButtonFace; | |
914 ws.MenuButton.BackColor = Color.DarkGray; | |
915 } | |
916 } else { | |
917 ws.Control.Bounds = ws.OldBounds; | |
918 ws.Visible = true; | |
919 windowcontainer.BringControlToFront(ws.Control); | |
920 foreach (FBGWindowState wsa in windowstates.Values) if (!ReferenceEquals(ws, wsa)) wsa.MenuButton.BackColor = SystemColors.ButtonFace; | |
921 ws.MenuButton.BackColor = Color.DarkGray; | |
922 } | |
923 }; | |
924 } | |
925 public override void RemoveControl(IFBGControl control) { | |
926 windowcontainer.RemoveControl(control); | |
927 windowstates.Remove(control); | |
928 ScaleMenuButtons(); | |
929 } | |
930 private void ScaleMenuButtons() { | |
931 int bcount = windowstates.Count; | |
932 int bwidth = 200; | |
933 int twidth = bwidth * bcount; | |
934 if (twidth > Bounds.Width) bwidth = menucontainer.Bounds.Width / bcount; | |
935 int i = 0; | |
936 foreach (FBGWindowState ws in windowstates.Values) { | |
937 ws.MenuButton.Bounds = new Rectangle(i * bwidth, 0, bwidth, 25); | |
938 i++; | |
939 } | |
940 } | |
941 protected override void Paint(Graphics g) { | |
942 base.Paint(g); | |
943 g.DrawLine(Pens.Black, 0, Bounds.Height - 25, Bounds.Width, Bounds.Height - 25); | |
944 } | |
945 protected override void MouseDown(Point position, MouseButtons buttons) { | |
946 IFBGControl control = FindControlAtPosition(position); | |
947 if (ReferenceEquals(control, windowcontainer)) { | |
948 control = windowcontainer.FindControlAtPosition(PointToChild(windowcontainer, position)); | |
949 if (!ReferenceEquals(control, null)) { | |
950 windowcontainer.BringControlToFront(control); | |
951 foreach (FBGWindowState ws in windowstates.Values) | |
952 ws.MenuButton.BackColor = ReferenceEquals(ws.Control, control) ? Color.DarkGray : SystemColors.ButtonFace; | |
953 } | |
954 } | |
955 base.MouseDown(position, buttons); | |
956 } | |
957 } | |
958 | |
959 public class FBGLabel : FBGControl, IDisposable { | |
960 public FBGLabel(IFBGContainerControl parent) : base(parent) { | |
961 Size = new Size(200, 16); | |
962 } | |
963 private String text = String.Empty; | |
964 private Font font = SystemFonts.DefaultFont; | |
965 private Brush brush = SystemBrushes.ControlText; | |
966 private StringFormat stringformat = new StringFormat(); | |
967 public String Text { get { return text; } set { text = value; Invalidate(); } } | |
968 public Font Font { get { return font; } set { font = value; Invalidate(); } } | |
969 public Brush Brush { get { return brush; } set { brush = value; Invalidate(); } } | |
970 public Color Color { set { Brush = new SolidBrush(value); } } | |
971 public StringAlignment Alignment { get { return stringformat.Alignment; } set { stringformat.Alignment = value; Invalidate(); } } | |
972 public StringFormatFlags FormatFlags { get { return stringformat.FormatFlags; } set { stringformat.FormatFlags = value; Invalidate(); } } | |
973 public StringAlignment LineAlignment { get { return stringformat.LineAlignment; } set { stringformat.LineAlignment = value; Invalidate(); } } | |
974 public StringTrimming Trimming { get { return stringformat.Trimming; } set { stringformat.Trimming = value; Invalidate(); } } | |
975 protected override void Paint(Graphics g) { | |
976 base.Paint(g); | |
977 g.DrawString(text, font, brush, new Rectangle(Point.Empty, Bounds.Size), stringformat); | |
978 } | |
979 public void Dispose() { | |
980 stringformat.Dispose(); | |
981 } | |
982 protected override void Orphaned() { | |
983 base.Orphaned(); | |
984 Dispose(); | |
985 } | |
986 } | |
987 public class FBGTextBox : FBGControl { | |
988 public FBGTextBox(IFBGContainerControl parent) : base(parent) { | |
989 BackColor = Color.White; | |
990 Size = new Size(200, 20); | |
991 } | |
992 private String text = String.Empty; | |
993 private Char passwordChar = (Char)0; | |
994 private Font font = new Font(FontFamily.GenericMonospace, 10); | |
995 private Brush brush = SystemBrushes.ControlText; | |
996 private Boolean hasKeyboardFocus = false; | |
997 public String Text { get { return text; } set { text = value; if (CaretPosition > text.Length) CaretPosition = text.Length; Invalidate(); RaiseEvent(TextChanged); } } | |
998 public Font Font { get { return font; } set { font = value; Invalidate(); } } | |
999 public Brush Brush { get { return brush; } set { brush = value; Invalidate(); } } | |
1000 public Color Color { set { Brush = new SolidBrush(value); } } | |
1001 public Int32 CaretPosition { get; private set; } | |
1002 public Char PasswordChar { get { return passwordChar; } set { passwordChar = value; Invalidate(); } } | |
1003 public event EventHandler TextChanged; | |
1004 public event KeyPressEventHandler OnKeyPress; | |
1005 protected override void Paint(Graphics g) { | |
1006 base.Paint(g); | |
1007 g.DrawRectangle(Pens.Gray, 0, 0, Bounds.Width - 1, Bounds.Height - 1); | |
1008 using (StringFormat sf_nonprinting = new StringFormat(StringFormat.GenericTypographic)) { | |
1009 sf_nonprinting.Trimming = StringTrimming.None; | |
1010 sf_nonprinting.FormatFlags = StringFormatFlags.DisplayFormatControl | StringFormatFlags.MeasureTrailingSpaces; | |
1011 sf_nonprinting.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None; | |
1012 | |
1013 float x = 1; | |
1014 float y = 1; | |
1015 float w = Width - 2; | |
1016 if (hasKeyboardFocus && CaretPosition == 0) { | |
1017 g.DrawLine(Pens.Black, x + 2, 2, x + 2, Height - 4); | |
1018 } | |
1019 String c = passwordChar == 0 ? null : new String(passwordChar, 1); | |
1020 for (int i = 0; i < text.Length; i++) { | |
1021 if (passwordChar == 0) c = text.Substring(i, 1); | |
1022 SizeF s = g.MeasureString(c, font, (int)Math.Ceiling(w), sf_nonprinting); | |
1023 g.DrawString(c, font, brush, x, y); | |
1024 x += (float)Math.Ceiling(s.Width); | |
1025 w -= (float)Math.Ceiling(s.Width); | |
1026 | |
1027 if (hasKeyboardFocus && i == CaretPosition - 1) { | |
1028 g.DrawLine(Pens.Black, x + 2, 2, x + 2, Height - 4); | |
1029 } | |
1030 } | |
1031 } | |
1032 } | |
1033 protected override void MouseDown(Point position, MouseButtons buttons) { | |
1034 hasKeyboardFocus = CaptureKeyboard(true); | |
1035 CaretPosition = text.Length; | |
1036 float x = 1; | |
1037 String c = passwordChar == 0 ? null : new String(passwordChar, 1); | |
1038 for (int i = 0; i < text.Length; i++) { | |
1039 if (passwordChar == 0) c = text.Substring(i, 1); | |
1040 Size s; | |
1041 try { | |
1042 s = TextRenderer.MeasureText(c, font, Size.Empty, TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix); | |
1043 } catch (Exception) { | |
1044 break; | |
1045 } | |
1046 x += s.Width; | |
1047 if (position.X < x) { | |
1048 CaretPosition = i; | |
1049 break; | |
1050 } | |
1051 } | |
1052 Invalidate(); | |
1053 } | |
1054 protected override void KeyDown(Keys key) { | |
1055 if ((key & Keys.KeyCode) == Keys.Left) { | |
1056 CaretPosition--; | |
1057 if (CaretPosition < 0) CaretPosition = 0; | |
1058 Invalidate(); | |
1059 } else if ((key & Keys.KeyCode) == Keys.Right) { | |
1060 CaretPosition++; | |
1061 if (CaretPosition > text.Length) CaretPosition = text.Length; | |
1062 Invalidate(); | |
1063 } else if ((key & Keys.KeyCode) == Keys.Home) { | |
1064 CaretPosition = 0; | |
1065 Invalidate(); | |
1066 } else if ((key & Keys.KeyCode) == Keys.End) { | |
1067 CaretPosition = text.Length; | |
1068 Invalidate(); | |
1069 } else if ((key & Keys.Control) != 0 && (key & Keys.KeyCode) == Keys.V) { | |
1070 String cbtext = Clipboard.GetText(TextDataFormat.UnicodeText); | |
1071 CaretPosition += cbtext.Length; | |
1072 Text = Text.Insert(CaretPosition - cbtext.Length, cbtext); | |
1073 } | |
1074 } | |
1075 protected override void KeyPress(char keyChar) { | |
1076 KeyPressEventArgs e = new KeyPressEventArgs(keyChar); | |
1077 RaiseEvent(OnKeyPress, e); | |
1078 if (e.Handled) return; | |
1079 hasKeyboardFocus = true; | |
1080 if (keyChar == 8) { | |
1081 if (CaretPosition > 0) { | |
1082 CaretPosition--; | |
1083 Text = Text.Remove(CaretPosition, 1); | |
1084 } | |
1085 } else if (keyChar == 127) { | |
1086 if (CaretPosition < Text.Length) { | |
1087 Text = Text.Remove(CaretPosition, 1); | |
1088 } | |
1089 } else if (keyChar < 32) { | |
1090 } else { | |
1091 CaretPosition++; | |
1092 Text = Text.Insert(CaretPosition - 1, new String(keyChar, 1)); | |
1093 } | |
1094 } | |
1095 public void Focus() { | |
1096 hasKeyboardFocus = CaptureKeyboard(true); | |
1097 } | |
1098 protected override void LostKeyboardCapture() { | |
1099 base.LostKeyboardCapture(); | |
1100 hasKeyboardFocus = false; | |
1101 Invalidate(); | |
1102 } | |
1103 } | |
1104 public class FBGButton : FBGControl { | |
1105 public FBGButton(IFBGContainerControl parent) : base(parent) { | |
1106 BackColor = SystemColors.ButtonFace; | |
1107 } | |
1108 private String text = String.Empty; | |
1109 private Font font = SystemFonts.DefaultFont; | |
1110 private Color color = SystemColors.ControlText; | |
1111 private Boolean pressed = false; | |
1112 private Boolean enabled = true; | |
1113 public String Text { get { return text; } set { text = value; Invalidate(); } } | |
1114 public Font Font { get { return font; } set { font = value; Invalidate(); } } | |
1115 public Color Color { get { return color; } set { color = value; Invalidate(); } } | |
1116 public Boolean Enabled { get { return enabled; } set { enabled = value; Invalidate(); } } | |
1117 public event EventHandler Click; | |
1118 protected override void Paint(Graphics g) { | |
1119 base.Paint(g); | |
1120 if (Bounds.Width == 0 || Bounds.Height == 0) return; | |
1121 if (BackColor == SystemColors.ButtonFace) { | |
1122 ControlPaint.DrawButton(g, new Rectangle(0, 0, Bounds.Width, Bounds.Height), enabled ? (pressed ? ButtonState.Pushed : ButtonState.Normal) : ButtonState.Inactive); | |
1123 } else { | |
1124 //Hackish and not completely right... | |
1125 //Todo: borrowed from mono... possible licencing issues!? | |
1126 g.DrawLine(new Pen(ControlPaint.LightLight(BackColor)), 0, 0, Bounds.Width, 0); | |
1127 g.DrawLine(new Pen(ControlPaint.LightLight(BackColor)), 0, 0, 0, Bounds.Height); | |
1128 g.DrawLine(new Pen(ControlPaint.Dark(BackColor)), 1, Bounds.Height - 2, Bounds.Width - 1, Bounds.Height - 2); | |
1129 g.DrawLine(new Pen(ControlPaint.Dark(BackColor)), Bounds.Width - 2, 1, Bounds.Width - 2, Bounds.Height - 2); | |
1130 g.DrawLine(new Pen(ControlPaint.DarkDark(BackColor)), 0, Bounds.Height - 1, Bounds.Width, Bounds.Height - 1); | |
1131 g.DrawLine(new Pen(ControlPaint.DarkDark(BackColor)), Bounds.Width - 1, 1, Bounds.Width - 1, Bounds.Height - 1); | |
1132 Graphics dc = g; | |
1133 Rectangle rectangle = new Rectangle(0, 0, Bounds.Width - 1, Bounds.Height - 1); | |
1134 Color ColorControl = BackColor; | |
1135 Color ColorControlLight = ControlPaint.Light(ColorControl); | |
1136 ButtonState state = pressed ? ButtonState.Pushed : ButtonState.Normal; | |
1137 using (Pen NormalPen = new Pen(BackColor), LightPen = new Pen(ControlPaint.Light(BackColor)), DarkPen = new Pen(ControlPaint.Dark(BackColor))) { | |
1138 // sadly enough, the rectangle gets always filled with a hatchbrush | |
1139 using (HatchBrush hb = new HatchBrush(HatchStyle.Percent50, Color.FromArgb(Math.Min(255, ColorControl.R + 3), ColorControl.G, ColorControl.B), ColorControl)) { | |
1140 dc.FillRectangle(hb, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2); | |
1141 } | |
1142 if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) { | |
1143 using (HatchBrush hb = new HatchBrush(HatchStyle.Percent50, ColorControlLight, ColorControl)) { | |
1144 dc.FillRectangle(hb, rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4); | |
1145 } | |
1146 dc.DrawRectangle(SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); | |
1147 } else if ((state & ButtonState.Flat) == ButtonState.Flat) { | |
1148 dc.DrawRectangle(SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); | |
1149 } else if ((state & ButtonState.Checked) == ButtonState.Checked) { | |
1150 using (HatchBrush hb = new HatchBrush(HatchStyle.Percent50, ColorControlLight, ColorControl)) { | |
1151 dc.FillRectangle(hb, rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4); | |
1152 } | |
1153 Pen pen = DarkPen; | |
1154 dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); | |
1155 dc.DrawLine(pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y); | |
1156 | |
1157 pen = NormalPen; | |
1158 dc.DrawLine(pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3); | |
1159 dc.DrawLine(pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1); | |
1160 | |
1161 pen = LightPen; | |
1162 dc.DrawLine(pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1); | |
1163 dc.DrawLine(pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1); | |
1164 } else if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) { | |
1165 Pen pen = DarkPen; | |
1166 dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); | |
1167 dc.DrawLine(pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y); | |
1168 | |
1169 pen = NormalPen; | |
1170 dc.DrawLine(pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3); | |
1171 dc.DrawLine(pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1); | |
1172 | |
1173 pen = LightPen; | |
1174 dc.DrawLine(pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1); | |
1175 dc.DrawLine(pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1); | |
1176 } else if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) { | |
1177 Pen pen = LightPen; | |
1178 dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y); | |
1179 dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); | |
1180 | |
1181 pen = NormalPen; | |
1182 dc.DrawLine(pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2); | |
1183 dc.DrawLine(pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3); | |
1184 | |
1185 pen = DarkPen; | |
1186 dc.DrawLine(pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1); | |
1187 dc.DrawLine(pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2); | |
1188 } | |
1189 } | |
1190 } | |
1191 Rectangle frect = new Rectangle(Point.Empty, Bounds.Size); | |
1192 SizeF textsize = g.MeasureString(Text, Font); | |
1193 using (Brush b = new SolidBrush(enabled ? Color : Color.DarkGray)) { | |
1194 g.DrawString(Text, Font, b, new PointF(Bounds.Width / 2.0f - textsize.Width / 2.0f, Bounds.Height / 2.0f - textsize.Height / 2.0f)); | |
1195 } | |
1196 } | |
1197 protected override void MouseDown(Point position, MouseButtons buttons) { | |
1198 pressed = true; | |
1199 Invalidate(); | |
1200 CaptureMouse(true); | |
1201 base.MouseDown(position, buttons); | |
1202 } | |
1203 protected override void MouseUp(Point position, MouseButtons buttons) { | |
1204 pressed = false; | |
1205 Invalidate(); | |
1206 CaptureMouse(false); | |
1207 if (position.X >= 0 && position.X <= Bounds.Width && position.Y >= 0 && position.Y <= Bounds.Height && enabled) RaiseEvent(Click); | |
1208 base.MouseUp(position, buttons); | |
1209 } | |
1210 protected override void KeyDown(Keys key) { | |
1211 if (key == Keys.Return || key == Keys.Space) { | |
1212 pressed = true; | |
1213 Invalidate(); | |
1214 } | |
1215 base.KeyDown(key); | |
1216 } | |
1217 protected override void KeyUp(Keys key) { | |
1218 if (key == Keys.Return || key == Keys.Space) { | |
1219 if (pressed) RaiseEvent(Click); | |
1220 pressed = false; | |
1221 Invalidate(); | |
1222 } | |
1223 base.KeyUp(key); | |
1224 } | |
1225 public void Focus() { | |
1226 CaptureKeyboard(true); | |
1227 } | |
1228 } | |
1229 public class FBGCheckBox : FBGControl { | |
1230 public FBGCheckBox(IFBGContainerControl parent) : base(parent) { } | |
1231 private String text = String.Empty; | |
1232 private Font font = SystemFonts.DefaultFont; | |
1233 private Color color = SystemColors.ControlText; | |
1234 private Boolean _checked = false; | |
1235 public String Text { get { return text; } set { text = value; Invalidate(); } } | |
1236 public Font Font { get { return font; } set { font = value; Invalidate(); } } | |
1237 public Color Color { get { return color; } set { color = value; Invalidate(); } } | |
1238 public Boolean Checked { get { return _checked; } set { _checked = value; Invalidate(); } } | |
1239 public event EventHandler CheckedChanged; | |
1240 protected override void Paint(Graphics g) { | |
1241 base.Paint(g); | |
1242 ControlPaint.DrawCheckBox(g, 0, 0, 13, 13, _checked ? ButtonState.Checked : ButtonState.Normal); | |
1243 g.DrawString(Text, Font, new SolidBrush(Color), 15, 0); | |
1244 } | |
1245 protected override void MouseDown(Point position, MouseButtons buttons) { | |
1246 Checked = !Checked; | |
1247 RaiseEvent(CheckedChanged); | |
1248 base.MouseDown(position, buttons); | |
1249 } | |
1250 } | |
1251 public class FBGImageBox : FBGControl { | |
1252 Image image = null; | |
1253 PictureBoxSizeMode sizeMode = PictureBoxSizeMode.Normal; | |
1254 Rectangle imageRect; | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1255 public Image Image { get { return image; } set { image = value; UpdateImageRect(Size.Empty); } } |
23 | 1256 public FBGImageBox(IFBGContainerControl parent) : base(parent) { } |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1257 public PictureBoxSizeMode SizeMode { get { return sizeMode; } set { sizeMode = value; UpdateImageRect(Size.Empty); } } |
23 | 1258 public override Rectangle Bounds { |
1259 get { | |
1260 return base.Bounds; | |
1261 } | |
1262 set { | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1263 UpdateImageRect(value.Size); |
23 | 1264 base.Bounds = value; |
1265 } | |
1266 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1267 private void UpdateImageRect(Size csize) { |
23 | 1268 if (image == null) return; |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1269 Boolean boundsset = !csize.IsEmpty; |
23 | 1270 if (!boundsset && sizeMode == PictureBoxSizeMode.AutoSize) { |
1271 Size = Image.Size; | |
1272 return; | |
1273 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1274 if (!boundsset) csize = Bounds.Size; |
23 | 1275 switch (sizeMode) { |
1276 case PictureBoxSizeMode.AutoSize: | |
1277 case PictureBoxSizeMode.Normal: | |
1278 imageRect = new Rectangle(Point.Empty, image.Size); | |
1279 break; | |
1280 case PictureBoxSizeMode.CenterImage: | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1281 imageRect = new Rectangle(csize.Width / 2 - image.Width / 2, csize.Height / 2 - Image.Height / 2, image.Width, image.Height); |
23 | 1282 break; |
1283 case PictureBoxSizeMode.StretchImage: | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1284 imageRect = new Rectangle(Point.Empty, csize); |
23 | 1285 break; |
1286 case PictureBoxSizeMode.Zoom: | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1287 float xrat = (float)csize.Width / (float)image.Width; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1288 float yrat = (float)csize.Height / (float)image.Height; |
23 | 1289 float rat = Math.Min(xrat, yrat); |
1290 SizeF dispsize = new SizeF(image.Width * rat, image.Height * rat); | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1291 imageRect = Rectangle.Round(new RectangleF(csize.Width / 2f - dispsize.Width / 2f, csize.Height / 2f - dispsize.Height / 2f, dispsize.Width, dispsize.Height)); |
23 | 1292 break; |
1293 } | |
1294 if (!boundsset) Invalidate(); | |
1295 } | |
1296 protected override void Paint(Graphics g) { | |
1297 if (!Visible) return; | |
1298 base.Paint(g); | |
1299 if (image != null) g.DrawImage(image, imageRect); | |
1300 } | |
30
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1301 public Point PointToImage(Point point) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1302 switch (sizeMode) { |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1303 case PictureBoxSizeMode.AutoSize: |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1304 case PictureBoxSizeMode.Normal: |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1305 break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1306 case PictureBoxSizeMode.CenterImage: |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1307 point.X -= imageRect.X; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1308 point.Y -= imageRect.Y; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1309 break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1310 case PictureBoxSizeMode.StretchImage: |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1311 case PictureBoxSizeMode.Zoom: |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1312 default: |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1313 point.X = (point.X - imageRect.X) * image.Width / imageRect.Width; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1314 point.Y = (point.Y - imageRect.Y) * image.Height / imageRect.Height; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1315 break; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1316 } |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1317 return point; |
24e918d2ac18
FBGUI: Added per-control Cursor handling, added more cursors for Form operations, fixed ImageBox image sizing
Ivo Smits <Ivo@UCIS.nl>
parents:
27
diff
changeset
|
1318 } |
23 | 1319 } |
1320 public class FBGListBox : FBGControl { | |
1321 private List<Object> items = new List<object>(); | |
1322 private Object selected = null; | |
1323 private Object highlighted = null; | |
1324 private Boolean hasScrollBar = false; | |
1325 private Boolean hitScrollBar = false; | |
1326 private int offset = 0; | |
1327 private ButtonState buttonUpState = ButtonState.Normal; | |
1328 private ButtonState buttonDownState = ButtonState.Normal; | |
1329 private Converter<Object, String> itemFormatter = null; | |
1330 public Converter<Object, String> ItemFormatter { get { return itemFormatter; } set { itemFormatter = value; Invalidate(); } } | |
1331 public FBGListBox(IFBGContainerControl parent) | |
1332 : base(parent) { | |
1333 BackColor = Color.White; | |
1334 } | |
1335 public void AddItem(Object item) { | |
1336 items.Add(item); | |
1337 Invalidate(); | |
1338 } | |
1339 protected override void Paint(Graphics g) { | |
1340 base.Paint(g); | |
1341 g.DrawRectangle(Pens.DarkBlue, 0, 0, Bounds.Width - 1, Bounds.Height - 1); | |
1342 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight()); | |
1343 int th = lh * items.Count; | |
1344 int y = 2; | |
1345 using (Pen dottedpen = new Pen(Brushes.Black)) { | |
1346 dottedpen.DashStyle = DashStyle.Dot; | |
1347 using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap)) { | |
1348 for (int i = offset; i < items.Count; i++) { | |
1349 Object item = items[i]; | |
1350 String text = itemFormatter == null ? (item == null ? String.Empty : item.ToString()) : itemFormatter(item); | |
1351 if (item == selected) g.FillRectangle(Brushes.DarkGray, 2, y, Bounds.Width - 4, lh); | |
1352 if (item == highlighted) g.DrawRectangle(dottedpen, 2, y, Bounds.Width - 5, lh - 1); | |
1353 g.DrawString(text, SystemFonts.DefaultFont, SystemBrushes.WindowText, new Rectangle(3, y, Bounds.Width - 6, lh), sf); | |
1354 y += lh; | |
1355 if (y + lh + 2 >= Bounds.Height) break; | |
1356 } | |
1357 } | |
1358 } | |
1359 if (y < th) hasScrollBar = true; | |
1360 if (hasScrollBar) { | |
1361 int xoff = Bounds.Width - 17; | |
1362 using (Brush b = new LinearGradientBrush(new Rectangle(xoff, 0, 17, 1), Color.LightGray, Color.White, LinearGradientMode.Horizontal)) | |
1363 g.FillRectangle(b, xoff, 17, 16, Bounds.Height - 17 - 17); | |
1364 ControlPaint.DrawScrollButton(g, xoff, 1, 16, 16, ScrollButton.Up, buttonUpState); | |
1365 ControlPaint.DrawScrollButton(g, xoff, Bounds.Height - 17, 16, 16, ScrollButton.Down, buttonDownState); | |
1366 g.DrawRectangle(Pens.Black, new Rectangle(xoff, 17 + offset * (Bounds.Height - 17 - 17 - 20) / (items.Count - 1), 15, 20)); | |
1367 } | |
1368 } | |
1369 protected override void MouseDown(Point position, MouseButtons buttons) { | |
1370 if ((buttons & MouseButtons.Left) != 0) { | |
1371 CaptureMouse(true); | |
1372 if (hasScrollBar && position.X > Bounds.Width - 17) { | |
1373 hitScrollBar = true; | |
1374 if (position.Y < 17) { | |
1375 offset--; | |
1376 buttonUpState = ButtonState.Pushed; | |
1377 } else if (position.Y > Bounds.Height - 17) { | |
1378 offset++; | |
1379 buttonDownState = ButtonState.Pushed; | |
1380 } else { | |
1381 offset = (int)Math.Round((position.Y - 17) * (items.Count - 1) / (double)(Bounds.Height - 17 - 17 - 10)); | |
1382 } | |
1383 if (offset < 0) offset = 0; | |
1384 if (offset >= items.Count) offset = items.Count - 1; | |
1385 Invalidate(); | |
1386 } else { | |
1387 MouseHandler(position, buttons); | |
1388 } | |
1389 } | |
1390 } | |
1391 protected override void MouseMove(Point position, MouseButtons buttons) { | |
1392 if (hitScrollBar) { | |
1393 if (position.Y < 17) { | |
1394 } else if (position.Y > Bounds.Height - 17) { | |
1395 } else { | |
1396 offset = (int)Math.Round((position.Y - 17) * (items.Count - 1) / (double)(Bounds.Height - 17 - 17 - 10)); | |
1397 if (offset < 0) offset = 0; | |
1398 if (offset >= items.Count) offset = items.Count - 1; | |
1399 Invalidate(); | |
1400 } | |
1401 return; | |
1402 } | |
1403 MouseHandler(position, buttons); | |
1404 } | |
1405 protected override void MouseUp(Point position, MouseButtons buttons) { | |
1406 if ((buttons & MouseButtons.Left) != 0) { | |
1407 CaptureMouse(false); | |
1408 buttonUpState = buttonDownState = ButtonState.Normal; | |
1409 Invalidate(); | |
1410 if (hitScrollBar) { | |
1411 hitScrollBar = false; | |
1412 return; | |
1413 } | |
1414 } | |
1415 if (hitScrollBar) return; | |
1416 MouseHandler(position, buttons); | |
1417 } | |
1418 private void MouseHandler(Point position, MouseButtons buttons) { | |
1419 if ((buttons & MouseButtons.Left) != 0) { | |
1420 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight()); | |
1421 int i = (position.Y - 2) / lh + offset; | |
1422 if (i < 0) i = 0; | |
1423 if (i >= items.Count) i = items.Count - 1; | |
1424 Boolean changed = false; | |
1425 Object current = items[i]; | |
1426 if (!ReferenceEquals(highlighted, current)) changed = true; | |
1427 highlighted = current; | |
1428 if ((new Rectangle(Point.Empty, Bounds.Size)).Contains(position)) { | |
1429 if (!ReferenceEquals(selected, current)) changed = true; | |
1430 selected = current; | |
1431 } | |
1432 if (changed) Invalidate(); | |
1433 } | |
1434 } | |
1435 } | |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1436 public abstract class FBGUpDownControlBase : FBGControl { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1437 private ButtonState buttonUpState = ButtonState.Normal; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1438 private ButtonState buttonDownState = ButtonState.Normal; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1439 public FBGUpDownControlBase(IFBGContainerControl parent) : base(parent) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1440 BackColor = Color.White; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1441 Height = 25; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1442 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1443 protected override void Paint(Graphics g) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1444 base.Paint(g); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1445 g.DrawRectangle(Pens.DarkBlue, 0, 0, Bounds.Width - 1, Bounds.Height - 1); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1446 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight()); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1447 String text = SelectedText; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1448 if (text == null) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1449 g.FillRectangle(Brushes.DarkGray, 2, 2, Bounds.Width - 4 - 16, Bounds.Height - 4); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1450 } else { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1451 using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap)) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1452 sf.LineAlignment = StringAlignment.Center; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1453 g.FillRectangle(Brushes.LightGray, 2, 2, Bounds.Width - 4 - 16, Bounds.Height - 4); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1454 g.DrawString(text, SystemFonts.DefaultFont, SystemBrushes.WindowText, new Rectangle(3, 2, Bounds.Width - 6 - 16, Bounds.Height - 4), sf); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1455 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1456 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1457 int xoff = Bounds.Width - 17; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1458 int he = (Bounds.Height - 2) / 2; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1459 ControlPaint.DrawScrollButton(g, xoff, 1, 16, he, ScrollButton.Up, buttonUpState); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1460 ControlPaint.DrawScrollButton(g, xoff, Bounds.Height - he - 1, 16, he, ScrollButton.Down, buttonDownState); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1461 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1462 protected abstract String SelectedText { get; } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1463 protected override void MouseDown(Point position, MouseButtons buttons) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1464 CaptureKeyboard(true); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1465 if ((buttons & MouseButtons.Left) != 0) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1466 CaptureMouse(true); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1467 if (position.X > Bounds.Width - 17) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1468 if (position.Y < Bounds.Height / 2) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1469 buttonUpState = ButtonState.Pushed; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1470 ButtonPressUp(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1471 } else { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1472 buttonDownState = ButtonState.Pushed; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1473 ButtonPressDown(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1474 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1475 Invalidate(new Rectangle(Bounds.Width - 16, 0, 16, Bounds.Height)); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1476 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1477 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1478 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1479 protected override void MouseUp(Point position, MouseButtons buttons) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1480 if ((buttons & MouseButtons.Left) != 0) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1481 CaptureMouse(false); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1482 buttonUpState = buttonDownState = ButtonState.Normal; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1483 Invalidate(new Rectangle(Bounds.Width - 16, 0, 16, Bounds.Height)); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1484 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1485 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1486 protected override void KeyDown(Keys key) { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1487 base.KeyDown(key); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1488 if (key == Keys.Down) ButtonPressDown(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1489 else if (key == Keys.Up) ButtonPressUp(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1490 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1491 protected abstract void ButtonPressUp(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1492 protected abstract void ButtonPressDown(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1493 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1494 public class FBGDomainUpDown : FBGUpDownControlBase { |
23 | 1495 private List<Object> items = new List<object>(); |
1496 private int selectedIndex = -1; | |
1497 private Converter<Object, String> itemFormatter = null; | |
1498 public Boolean AllowSelectEmpty { get; set; } | |
1499 public Converter<Object, String> ItemFormatter { get { return itemFormatter; } set { itemFormatter = value; Invalidate(); } } | |
1500 public event EventHandler SelectedIndexChanged; | |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1501 public FBGDomainUpDown(IFBGContainerControl parent) : base(parent) { } |
23 | 1502 public void AddItem(Object item) { |
1503 items.Add(item); | |
1504 Invalidate(); | |
1505 } | |
1506 public void RemoveItem(Object item) { | |
1507 items.Remove(item); | |
1508 FixSelectedIndex(0); | |
1509 } | |
1510 public void RemoveItem(int index) { | |
1511 items.RemoveAt(index); | |
1512 FixSelectedIndex(0); | |
1513 } | |
1514 public int SelectedIndex { | |
1515 get { return selectedIndex; } | |
1516 set { | |
1517 if (value < -2 || value >= items.Count) throw new ArgumentOutOfRangeException("value", "Value must be between -1 and the number of items minus one"); | |
1518 if (selectedIndex == value) return; | |
1519 selectedIndex = value; | |
1520 Invalidate(); | |
1521 RaiseEvent(SelectedIndexChanged); | |
1522 } | |
1523 } | |
1524 public Object SelectedItem { | |
1525 get { return selectedIndex == -1 ? null : items[selectedIndex]; } | |
1526 set { | |
1527 if (value == null) { | |
1528 SelectedIndex = -1; | |
1529 } else { | |
1530 for (int i = 0; i < items.Count; i++) { | |
1531 if (items[i] == value) { | |
1532 SelectedIndex = i; | |
1533 break; | |
1534 } | |
1535 } | |
1536 } | |
1537 } | |
1538 } | |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1539 protected override string SelectedText { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1540 get { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1541 if (selectedIndex == -1) return null; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1542 Object item = items[selectedIndex]; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1543 if (itemFormatter != null) return itemFormatter(item); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1544 if (item == null) return null; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1545 return item.ToString(); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1546 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1547 } |
23 | 1548 private void FixSelectedIndex(int change) { |
1549 int value = selectedIndex; | |
1550 if (value == 0 && change == -1 && !AllowSelectEmpty) change = 0; | |
1551 value += change; | |
1552 if (value < -1) value = -1; | |
1553 if (value >= items.Count) value = items.Count - 1; | |
1554 SelectedIndex = value; | |
1555 } | |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1556 protected override void ButtonPressDown() { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1557 FixSelectedIndex(1); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1558 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1559 protected override void ButtonPressUp() { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1560 FixSelectedIndex(-1); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1561 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1562 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1563 public class FBGNumericUpDown : FBGUpDownControlBase { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1564 private int minimum = 0; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1565 private int maximum = 0; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1566 private int value = 0; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1567 public event EventHandler SelectedValueChanged; |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1568 public FBGNumericUpDown(IFBGContainerControl parent) : base(parent) { } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1569 public int Value { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1570 get { return value; } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1571 set { if (this.value == value) return; this.value = value; Invalidate(); RaiseEvent(SelectedValueChanged); } |
23 | 1572 } |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1573 public int Minimum { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1574 get { return minimum; } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1575 set { minimum = value; if (this.value < minimum) this.Value = minimum; } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1576 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1577 public int Maximum { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1578 get { return maximum; } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1579 set { maximum = value; if (this.value > maximum) this.Value = maximum; } |
23 | 1580 } |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1581 public int Step { get; set; } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1582 protected override string SelectedText { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1583 get { return value.ToString(); } |
23 | 1584 } |
27
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1585 protected override void ButtonPressDown() { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1586 Value = Math.Max(minimum, value - Step); |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1587 } |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1588 protected override void ButtonPressUp() { |
5bfc6c68591e
FBGUI: Added numeric up/down control, fix for transparent control background
Ivo Smits <Ivo@UCIS.nl>
parents:
26
diff
changeset
|
1589 Value = Math.Min(maximum, value + Step); |
23 | 1590 } |
1591 } | |
1592 public interface IFBGTreeParent { | |
1593 FBGTreeView TreeView { get; } | |
1594 int Depth { get; } | |
1595 void AddChild(FBGTreeNode node); | |
1596 void RemoveChild(FBGTreeNode node); | |
1597 } | |
1598 public class FBGTreeNode : IFBGTreeParent { | |
1599 private List<FBGTreeNode> children = new List<FBGTreeNode>(); | |
1600 private Boolean expanded = true; | |
1601 private Boolean hasCheckBox = false; | |
1602 private Boolean isChecked = false; | |
1603 private Object item; | |
1604 | |
1605 public FBGTreeView TreeView { get; private set; } | |
1606 public int Depth { get; private set; } | |
1607 public Object Tag { get; set; } | |
1608 public IFBGTreeParent Parent { get; private set; } | |
1609 | |
1610 public IList<FBGTreeNode> Children { get { return children.AsReadOnly(); } } | |
1611 | |
1612 public Object Item { | |
1613 get { return item; } | |
1614 set { | |
1615 item = value; | |
1616 Invalidate(); | |
1617 } | |
1618 } | |
1619 public Boolean Expanded { | |
1620 get { return expanded; } | |
1621 set { | |
1622 if (expanded == value) return; | |
1623 expanded = value; | |
1624 UpdateTree(); | |
1625 } | |
1626 } | |
1627 public Boolean HasCheckBox { | |
1628 get { return hasCheckBox; } | |
1629 set { | |
1630 if (hasCheckBox == value) return; | |
1631 hasCheckBox = value; | |
1632 Invalidate(); | |
1633 } | |
1634 } | |
1635 public Boolean Checked { | |
1636 get { return isChecked; } | |
1637 set { | |
1638 if (isChecked == value) return; | |
1639 isChecked = value; | |
1640 Invalidate(); | |
1641 if (TreeView != null) TreeView.RaiseNodeCheckedChanged(this); | |
1642 } | |
1643 } | |
1644 | |
1645 public FBGTreeNode(IFBGTreeParent parent, Object item) { | |
1646 this.TreeView = parent.TreeView; | |
1647 this.Depth = parent.Depth + 1; | |
1648 this.Parent = parent; | |
1649 this.item = item; | |
1650 parent.AddChild(this); | |
1651 } | |
1652 | |
1653 public void Remove() { | |
1654 Parent.RemoveChild(this); | |
1655 } | |
1656 void IFBGTreeParent.AddChild(FBGTreeNode node) { | |
1657 children.Add(node); | |
1658 if (Expanded) UpdateTree(); | |
1659 else Invalidate(); | |
1660 } | |
1661 void IFBGTreeParent.RemoveChild(FBGTreeNode node) { | |
1662 children.Remove(node); | |
1663 TreeView.ReleaseNodeFromTree(node); | |
1664 if (Expanded) UpdateTree(); | |
1665 else Invalidate(); | |
1666 } | |
1667 public void Invalidate() { | |
1668 if (TreeView != null) TreeView.Invalidate(this); | |
1669 } | |
1670 private void UpdateTree() { | |
1671 if (TreeView != null) TreeView.UpdateView(); | |
1672 } | |
1673 public FBGTreeNode AddNode(Object item) { | |
1674 return new FBGTreeNode(this, item); | |
1675 } | |
1676 } | |
1677 public class FBGTreeView : FBGControl, IFBGTreeParent { | |
1678 private List<FBGTreeNode> items = new List<FBGTreeNode>(); | |
1679 private List<FBGTreeNode> itemsView = new List<FBGTreeNode>(); | |
1680 private FBGTreeNode selected = null; | |
1681 private FBGTreeNode highlighted = null; | |
1682 private Boolean hasScrollBar = false; | |
1683 private Boolean hitScrollBar = false; | |
1684 private int offset = 0; | |
1685 private ButtonState buttonUpState = ButtonState.Normal; | |
1686 private ButtonState buttonDownState = ButtonState.Normal; | |
1687 private Converter<Object, String> itemFormatter = null; | |
1688 | |
1689 public Converter<Object, String> ItemFormatter { get { return itemFormatter; } set { itemFormatter = value; Invalidate(); } } | |
1690 public FBGTreeNode SelectedNode { get { return selected; } set { if (selected != value) { selected = value; Invalidate(); RaiseEvent(SelectedNodeChanged); } } } | |
1691 public IList<FBGTreeNode> Nodes { get { return items.AsReadOnly(); } } | |
1692 | |
1693 public event EventHandler SelectedNodeChanged; | |
1694 public event EventHandler NodeCheckedChanged; | |
1695 | |
1696 public FBGTreeView(IFBGContainerControl parent) : base(parent) { | |
1697 BackColor = Color.White; | |
1698 } | |
1699 FBGTreeView IFBGTreeParent.TreeView { get { return this; } } | |
1700 int IFBGTreeParent.Depth { get { return -1; } } | |
1701 void IFBGTreeParent.AddChild(FBGTreeNode node) { | |
1702 items.Add(node); | |
1703 UpdateView(); | |
1704 } | |
1705 void IFBGTreeParent.RemoveChild(FBGTreeNode node) { | |
1706 items.Remove(node); | |
1707 ReleaseNodeFromTree(node); | |
1708 UpdateView(); | |
1709 } | |
1710 public FBGTreeNode AddNode(Object item) { return new FBGTreeNode(this, item); } | |
1711 internal void ReleaseNodeFromTree(FBGTreeNode node) { | |
1712 if (highlighted == node) highlighted = null; | |
1713 if (selected == node) SelectedNode = null; | |
1714 } | |
1715 internal void RaiseNodeCheckedChanged(FBGTreeNode node) { | |
1716 RaiseEvent(NodeCheckedChanged); | |
1717 } | |
1718 internal void UpdateView() { | |
1719 List<FBGTreeNode> newView = new List<FBGTreeNode>(); | |
1720 Stack<Queue<FBGTreeNode>> stack = new Stack<Queue<FBGTreeNode>>(); | |
1721 stack.Push(new Queue<FBGTreeNode>(items)); | |
1722 while (stack.Count > 0) { | |
1723 Queue<FBGTreeNode> list = stack.Peek(); | |
1724 if (list.Count == 0) { | |
1725 stack.Pop(); | |
1726 continue; | |
1727 } | |
1728 FBGTreeNode item = list.Dequeue(); | |
1729 newView.Add(item); | |
1730 if (item.Expanded) stack.Push(new Queue<FBGTreeNode>(item.Children)); | |
1731 } | |
1732 itemsView = newView; | |
1733 Invalidate(); | |
1734 } | |
1735 internal void Invalidate(FBGTreeNode node) { | |
1736 int i = itemsView.IndexOf(node); | |
1737 if (i == -1) return; | |
1738 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight() / 2.0) * 2; | |
1739 Invalidate(new Rectangle(1, i * lh, Bounds.Width - 1, lh)); | |
1740 } | |
1741 protected override void Paint(Graphics g) { | |
1742 base.Paint(g); | |
1743 | |
1744 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight() / 2.0) * 2; | |
1745 int th = lh * itemsView.Count; | |
1746 hasScrollBar = offset > 0 || th + 2 > Bounds.Height; | |
1747 int y = 2; | |
1748 using (Pen dottedpen = new Pen(Brushes.Black)) { | |
1749 dottedpen.DashStyle = DashStyle.Dot; | |
1750 using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap)) { | |
1751 int lw = Bounds.Width - 2; | |
1752 if (hasScrollBar) lw -= 17; | |
1753 for (int i = offset; i < itemsView.Count; i++) { | |
1754 FBGTreeNode item = itemsView[i]; | |
1755 if (y + 2 < Bounds.Height) { | |
1756 Object obj = item.Item; | |
1757 String text = itemFormatter == null ? (obj == null ? String.Empty : obj.ToString()) : itemFormatter(obj); | |
1758 if (item == selected) g.FillRectangle(Brushes.DarkGray, 2, y, lw - 2, lh); | |
1759 if (item == highlighted) g.DrawRectangle(dottedpen, 2, y, lw - 3, lh - 1); | |
1760 int x = 3 + 19 * item.Depth + 14; | |
1761 if (item.HasCheckBox) { | |
1762 x += 2; | |
1763 ControlPaint.DrawCheckBox(g, x, y, lh, lh, item.Checked ? ButtonState.Checked : ButtonState.Normal); | |
1764 x += lh + 1; | |
1765 } | |
1766 g.DrawString(text, SystemFonts.DefaultFont, SystemBrushes.WindowText, new Rectangle(x, y, lw - x, lh), sf); | |
1767 } | |
1768 int upto = y + 2 + 4 - 8; | |
1769 for (int j = i - 1; j >= 0; j--) { | |
1770 if (itemsView[j].Depth < item.Depth) { | |
1771 break; | |
1772 } | |
1773 if (itemsView[j].Depth == item.Depth) { | |
1774 if (itemsView[j].Children.Count > 0) { | |
1775 upto = 2 + lh * (j - offset) + 10; | |
1776 } else { | |
1777 upto = 2 + lh * (j - offset) + 6; | |
1778 } | |
1779 break; | |
1780 } | |
1781 if (j <= offset) { | |
1782 upto = 2 + 2 + 4 - 8; | |
1783 break; | |
1784 } | |
1785 } | |
1786 if (item.Children.Count > 0) { | |
1787 g.DrawRectangle(Pens.Black, 3 + 19 * item.Depth, y + 2, 8, 8); | |
1788 g.DrawLine(Pens.Black, 3 + 19 * item.Depth + 2, y + 2 + 4, 3 + 19 * item.Depth + 6, y + 2 + 4); | |
1789 if (!item.Expanded) g.DrawLine(Pens.Black, 3 + 19 * item.Depth + 4, y + 4, 3 + 19 * item.Depth + 4, y + 2 + 6); | |
1790 | |
1791 g.DrawLine(dottedpen, 3 + 19 * item.Depth + 8, y + 2 + 4, 3 + 19 * item.Depth + 14, y + 2 + 4); | |
1792 g.DrawLine(dottedpen, 3 + 19 * item.Depth + 4, y + 2 + 4 - 6, 3 + 19 * item.Depth + 4, upto); | |
1793 } else { | |
1794 g.DrawLine(dottedpen, 3 + 19 * item.Depth + 4, y + 2 + 4, 3 + 19 * item.Depth + 14, y + 2 + 4); | |
1795 g.DrawLine(dottedpen, 3 + 19 * item.Depth + 4, y + 2 + 4 - 2, 3 + 19 * item.Depth + 4, upto); | |
1796 } | |
1797 y += lh; | |
1798 //if (y + lh + 2 >= Bounds.Height && item.Depth == 0) break; | |
1799 if (y + 2 >= Bounds.Height && item.Depth == 0) break; | |
1800 } | |
1801 } | |
1802 } | |
1803 //if (y < th) hasScrollBar = true; | |
1804 //hasScrollBar = true; | |
1805 if (hasScrollBar) { | |
1806 int xoff = Bounds.Width - 17; | |
1807 using (Brush b = new LinearGradientBrush(new Rectangle(xoff, 0, 17, 1), Color.LightGray, Color.White, LinearGradientMode.Horizontal)) | |
1808 g.FillRectangle(b, xoff, 17, 16, Bounds.Height - 17 - 17); | |
1809 ControlPaint.DrawScrollButton(g, xoff, 1, 16, 16, ScrollButton.Up, buttonUpState); | |
1810 ControlPaint.DrawScrollButton(g, xoff, Bounds.Height - 17, 16, 16, ScrollButton.Down, buttonDownState); | |
1811 g.DrawRectangle(Pens.Black, new Rectangle(xoff, 17 + offset * (Bounds.Height - 17 - 17 - 20) / (itemsView.Count - 1), 15, 20)); | |
1812 } | |
1813 | |
1814 g.DrawRectangle(Pens.DarkBlue, 0, 0, Bounds.Width - 1, Bounds.Height - 1); | |
1815 } | |
1816 protected override void MouseDown(Point position, MouseButtons buttons) { | |
1817 CaptureKeyboard(true); | |
1818 if ((buttons & MouseButtons.Left) != 0) { | |
1819 CaptureMouse(true); | |
1820 if (hasScrollBar && position.X > Bounds.Width - 17) { | |
1821 hitScrollBar = true; | |
1822 if (position.Y < 17) { | |
1823 offset--; | |
1824 buttonUpState = ButtonState.Pushed; | |
1825 } else if (position.Y > Bounds.Height - 17) { | |
1826 offset++; | |
1827 buttonDownState = ButtonState.Pushed; | |
1828 } else { | |
1829 offset = (int)Math.Round((position.Y - 17) * (itemsView.Count - 1) / (double)(Bounds.Height - 17 - 17 - 10)); | |
1830 } | |
1831 if (offset < 0) offset = 0; | |
1832 if (offset >= itemsView.Count) offset = itemsView.Count - 1; | |
1833 Invalidate(); | |
1834 } else { | |
1835 MouseHandler(position, buttons, true); | |
1836 } | |
1837 } | |
1838 } | |
1839 protected override void MouseMove(Point position, MouseButtons buttons) { | |
1840 if (hitScrollBar) { | |
1841 if (position.Y < 17) { | |
1842 } else if (position.Y > Bounds.Height - 17) { | |
1843 } else { | |
1844 offset = (int)Math.Round((position.Y - 17) * (itemsView.Count - 1) / (double)(Bounds.Height - 17 - 17 - 10)); | |
1845 if (offset < 0) offset = 0; | |
1846 if (offset >= itemsView.Count) offset = itemsView.Count - 1; | |
1847 Invalidate(); | |
1848 } | |
1849 return; | |
1850 } | |
1851 MouseHandler(position, buttons, false); | |
1852 } | |
1853 protected override void MouseUp(Point position, MouseButtons buttons) { | |
1854 if ((buttons & MouseButtons.Left) != 0) { | |
1855 CaptureMouse(false); | |
1856 buttonUpState = buttonDownState = ButtonState.Normal; | |
1857 Invalidate(); | |
1858 if (hitScrollBar) { | |
1859 hitScrollBar = false; | |
1860 return; | |
1861 } | |
1862 } | |
1863 if (hitScrollBar) return; | |
1864 MouseHandler(position, buttons, false); | |
1865 } | |
1866 private void MouseHandler(Point position, MouseButtons buttons, Boolean down) { | |
1867 if ((buttons & MouseButtons.Left) != 0 && itemsView.Count > 0) { | |
1868 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight() / 2.0) * 2; | |
1869 int i = (position.Y - 2) / lh + offset; | |
1870 if (i < 0) i = 0; | |
1871 if (i >= itemsView.Count) i = itemsView.Count - 1; | |
1872 Boolean changed = false; | |
1873 FBGTreeNode current = itemsView[i]; | |
1874 if (!ReferenceEquals(highlighted, current)) changed = true; | |
1875 highlighted = current; | |
1876 if (current.Children.Count > 0 && (new Rectangle(3 + 19 * current.Depth, 2 + lh * (i - offset) + 2, 8, 8)).Contains(position)) { | |
1877 if (down) current.Expanded = !current.Expanded; | |
1878 } else if (current.HasCheckBox && (new Rectangle(3 + 19 * current.Depth + 14 + 2, 2 + lh * (i - offset), lh, lh)).Contains(position)) { | |
1879 if (down) current.Checked = !current.Checked; | |
1880 } else if ((new Rectangle(Point.Empty, Bounds.Size)).Contains(position)) { | |
1881 SelectedNode = current; | |
1882 changed = false; | |
1883 } | |
1884 if (changed) Invalidate(); | |
1885 } | |
1886 } | |
1887 protected override void KeyDown(Keys key) { | |
1888 base.KeyDown(key); | |
1889 if (key == Keys.Up) { | |
1890 int i = itemsView.IndexOf(selected); | |
1891 i--; | |
1892 if (i >= 0) SelectAndScrollIntoView(itemsView[i]); | |
1893 } else if (key == Keys.Down) { | |
1894 int i = itemsView.IndexOf(selected); | |
1895 i++; | |
1896 if (i < itemsView.Count) SelectAndScrollIntoView(itemsView[i]); | |
1897 } else if (key == Keys.Left && selected != null) { | |
1898 if (selected.Expanded && selected.Children.Count > 0) { | |
1899 selected.Expanded = false; | |
1900 } else { | |
1901 FBGTreeNode tn = selected.Parent as FBGTreeNode; | |
1902 if (tn != null) SelectAndScrollIntoView(tn); | |
1903 } | |
1904 } else if (key == Keys.Right && selected != null) { | |
1905 if (!selected.Expanded && selected.Children.Count > 0) { | |
1906 selected.Expanded = true; | |
1907 } else if (selected.Children.Count > 0) { | |
1908 SelectAndScrollIntoView(selected.Children[0]); | |
1909 } | |
1910 } else if (key == Keys.Space && selected != null) { | |
1911 if (selected.HasCheckBox) selected.Checked = !selected.Checked; | |
1912 } | |
1913 } | |
1914 private void SelectAndScrollIntoView(FBGTreeNode tn) { | |
1915 int i = itemsView.IndexOf(tn); | |
1916 if (i == -1) { | |
1917 for (FBGTreeNode tp = tn.Parent as FBGTreeNode; tp != null; tp = tp.Parent as FBGTreeNode) if (!tp.Expanded) tp.Expanded = true; | |
1918 i = itemsView.IndexOf(tn); | |
1919 } | |
1920 if (i != -1) { | |
1921 int lh = (int)Math.Ceiling(SystemFonts.DefaultFont.GetHeight() / 2.0) * 2; | |
1922 if (i < offset) offset = i; | |
1923 offset = Math.Max(offset, i - Bounds.Height / lh + 1); | |
1924 } | |
1925 highlighted = tn; | |
1926 SelectedNode = tn; | |
1927 } | |
1928 } | |
1929 } |