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