comparison FBGUI/FBGUI.cs @ 92:ac0a29c05d03

FBGUI: Improved TextBox mouse interaction
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 04 Apr 2014 23:21:33 +0200
parents 3347e1758e55
children
comparison
equal deleted inserted replaced
91:3347e1758e55 92:ac0a29c05d03
656 public static readonly FBGCursor SizeTopLeft = LoadFromResource("cursor_topleft", 1, 1); 656 public static readonly FBGCursor SizeTopLeft = LoadFromResource("cursor_topleft", 1, 1);
657 public static readonly FBGCursor SizeTopRight = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipX); 657 public static readonly FBGCursor SizeTopRight = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipX);
658 public static readonly FBGCursor SizeBottomLeft = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipY); 658 public static readonly FBGCursor SizeBottomLeft = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipY);
659 public static readonly FBGCursor SizeBottomRight = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipXY); 659 public static readonly FBGCursor SizeBottomRight = SizeTopLeft.RotateFlip(RotateFlipType.RotateNoneFlipXY);
660 public static readonly FBGCursor Hand = LoadFromResource("cursor_hand", 5, 0); 660 public static readonly FBGCursor Hand = LoadFromResource("cursor_hand", 5, 0);
661 public static readonly FBGCursor IBeam = LoadFromResource("cursor_ibeam", 3, 7);
661 public static FBGCursor ArrowCursor { get { return Arrow; } } 662 public static FBGCursor ArrowCursor { get { return Arrow; } }
662 } 663 }
663 public class FBGRenderer : FBGContainerControl, IDisposable { 664 public class FBGRenderer : FBGContainerControl, IDisposable {
664 private FBGCursor cursor = null; 665 private FBGCursor cursor = null;
665 private Point cursorposition = Point.Empty; 666 private Point cursorposition = Point.Empty;
1147 } 1148 }
1148 public class FBGTextBox : FBGControl { 1149 public class FBGTextBox : FBGControl {
1149 public FBGTextBox(IFBGContainerControl parent) : base(parent) { 1150 public FBGTextBox(IFBGContainerControl parent) : base(parent) {
1150 BackColor = Color.White; 1151 BackColor = Color.White;
1151 Size = new Size(200, 20); 1152 Size = new Size(200, 20);
1153 Cursor = FBGCursor.IBeam;
1152 } 1154 }
1153 private String text = String.Empty; 1155 private String text = String.Empty;
1154 private Char passwordChar = (Char)0; 1156 private Char passwordChar = (Char)0;
1155 private Font font = new Font(FontFamily.GenericMonospace, 10); 1157 private Font font = new Font(FontFamily.GenericMonospace, 10);
1156 private Brush brush = SystemBrushes.ControlText; 1158 private Brush brush = SystemBrushes.ControlText;
1157 private Boolean hasKeyboardFocus = false; 1159 private Boolean hasKeyboardFocus = false;
1158 public String Text { get { return text; } set { text = value; if (CaretPosition > text.Length) CaretPosition = text.Length; Invalidate(); RaiseEvent(TextChanged); } } 1160 private float[] characterPositions = null;
1159 public Font Font { get { return font; } set { font = value; Invalidate(); } } 1161 public String Text { get { return text; } set { text = value; if (CaretPosition > text.Length) CaretPosition = text.Length; characterPositions = null; Invalidate(); RaiseEvent(TextChanged); } }
1162 public Font Font { get { return font; } set { font = value; characterPositions = null; Invalidate(); } }
1160 public Brush Brush { get { return brush; } set { brush = value; Invalidate(); } } 1163 public Brush Brush { get { return brush; } set { brush = value; Invalidate(); } }
1161 public Color Color { set { Brush = new SolidBrush(value); } } 1164 public Color Color { set { Brush = new SolidBrush(value); } }
1162 public Int32 CaretPosition { get; private set; } 1165 public Int32 CaretPosition { get; private set; }
1163 public Char PasswordChar { get { return passwordChar; } set { passwordChar = value; Invalidate(); } } 1166 public Char PasswordChar { get { return passwordChar; } set { passwordChar = value; Invalidate(); } }
1164 public event EventHandler TextChanged; 1167 public event EventHandler TextChanged;
1165 public event KeyPressEventHandler OnKeyPress; 1168 public event KeyPressEventHandler OnKeyPress;
1166 protected override void Paint(Graphics g) { 1169 protected override void Paint(Graphics g) {
1167 base.Paint(g); 1170 base.Paint(g);
1168 g.DrawRectangle(Pens.Gray, 0, 0, Bounds.Width - 1, Bounds.Height - 1); 1171 g.DrawRectangle(Pens.Gray, 0, 0, Bounds.Width - 1, Bounds.Height - 1);
1172 float[] positions = characterPositions;
1173 String textbuffer = text;
1174 int textlength = textbuffer == null ? 0 : textbuffer.Length;
1175 if (positions == null || positions.Length != textlength) characterPositions = positions = new float[text.Length];
1169 using (StringFormat sf_nonprinting = new StringFormat(StringFormat.GenericTypographic)) { 1176 using (StringFormat sf_nonprinting = new StringFormat(StringFormat.GenericTypographic)) {
1170 sf_nonprinting.Trimming = StringTrimming.None; 1177 sf_nonprinting.Trimming = StringTrimming.None;
1171 sf_nonprinting.FormatFlags = StringFormatFlags.DisplayFormatControl | StringFormatFlags.MeasureTrailingSpaces; 1178 sf_nonprinting.FormatFlags = StringFormatFlags.DisplayFormatControl | StringFormatFlags.MeasureTrailingSpaces;
1172 sf_nonprinting.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None; 1179 sf_nonprinting.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
1173 1180
1174 float x = 1; 1181 float x = 1;
1175 float y = 1; 1182 float y = 1;
1176 float w = Width - 2; 1183 if (hasKeyboardFocus && CaretPosition == 0) g.DrawLine(Pens.Black, x + 2, 2, x + 2, Height - 4);
1177 if (hasKeyboardFocus && CaretPosition == 0) {
1178 g.DrawLine(Pens.Black, x + 2, 2, x + 2, Height - 4);
1179 }
1180 String c = passwordChar == 0 ? null : new String(passwordChar, 1); 1184 String c = passwordChar == 0 ? null : new String(passwordChar, 1);
1181 for (int i = 0; i < text.Length; i++) { 1185 for (int i = 0; i < textlength; i++) {
1182 if (passwordChar == 0) c = text.Substring(i, 1); 1186 if (passwordChar == 0) c = textbuffer.Substring(i, 1);
1183 SizeF s = g.MeasureString(c, font, (int)Math.Ceiling(w), sf_nonprinting);
1184 g.DrawString(c, font, brush, x, y); 1187 g.DrawString(c, font, brush, x, y);
1188 SizeF s = g.MeasureString(c, font, int.MaxValue, sf_nonprinting);
1185 x += (float)Math.Ceiling(s.Width); 1189 x += (float)Math.Ceiling(s.Width);
1186 w -= (float)Math.Ceiling(s.Width); 1190 if (positions.Length > i) positions[i] = x;
1187 1191
1188 if (hasKeyboardFocus && i == CaretPosition - 1) { 1192 if (hasKeyboardFocus && i == CaretPosition - 1) g.DrawLine(Pens.Black, x + 2, 2, x + 2, Height - 4);
1189 g.DrawLine(Pens.Black, x + 2, 2, x + 2, Height - 4); 1193 }
1190 } 1194 }
1191 } 1195 }
1192 } 1196 int GetCharacterIndexAtPosition(float x) {
1197 float[] positions = characterPositions;
1198 if (positions == null) return -1;
1199 for (int i = 0; i < positions.Length; i++) if (x < characterPositions[i]) return i;
1200 return characterPositions.Length;
1193 } 1201 }
1194 protected override void MouseDown(Point position, MouseButtons buttons) { 1202 protected override void MouseDown(Point position, MouseButtons buttons) {
1195 hasKeyboardFocus = CaptureKeyboard(true); 1203 hasKeyboardFocus = CaptureKeyboard(true);
1196 CaretPosition = text.Length; 1204 CaretPosition = GetCharacterIndexAtPosition(position.X);
1197 float x = 1;
1198 String c = passwordChar == 0 ? null : new String(passwordChar, 1);
1199 for (int i = 0; i < text.Length; i++) {
1200 if (passwordChar == 0) c = text.Substring(i, 1);
1201 Size s;
1202 try {
1203 s = TextRenderer.MeasureText(c, font, Size.Empty, TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix);
1204 } catch (Exception) {
1205 break;
1206 }
1207 x += s.Width;
1208 if (position.X < x) {
1209 CaretPosition = i;
1210 break;
1211 }
1212 }
1213 Invalidate(); 1205 Invalidate();
1214 } 1206 }
1215 protected override void KeyDown(Keys key) { 1207 protected override void KeyDown(Keys key) {
1216 if ((key & Keys.KeyCode) == Keys.Left) { 1208 if ((key & Keys.KeyCode) == Keys.Left) {
1217 CaretPosition--; 1209 CaretPosition--;
1253 Text = Text.Insert(CaretPosition - 1, new String(keyChar, 1)); 1245 Text = Text.Insert(CaretPosition - 1, new String(keyChar, 1));
1254 } 1246 }
1255 } 1247 }
1256 public void Focus() { 1248 public void Focus() {
1257 hasKeyboardFocus = CaptureKeyboard(true); 1249 hasKeyboardFocus = CaptureKeyboard(true);
1250 Invalidate();
1258 } 1251 }
1259 protected override void LostKeyboardCapture() { 1252 protected override void LostKeyboardCapture() {
1260 base.LostKeyboardCapture(); 1253 base.LostKeyboardCapture();
1261 hasKeyboardFocus = false; 1254 hasKeyboardFocus = false;
1262 Invalidate(); 1255 Invalidate();