a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
890 lines
23 KiB
C#
890 lines
23 KiB
C#
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
// Copyright (c) 2005 Novell, Inc.
|
|
//
|
|
// Authors:
|
|
// Jonathan Gilbert <logic@deltaq.org>
|
|
//
|
|
// Integration into MWF:
|
|
// Peter Bartok <pbartok@novell.com>
|
|
//
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
|
|
namespace System.Windows.Forms
|
|
{
|
|
[ClassInterface (ClassInterfaceType.AutoDispatch)]
|
|
[ComVisible (true)]
|
|
[Designer("System.Windows.Forms.Design.UpDownBaseDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
|
|
public abstract class UpDownBase : ContainerControl {
|
|
#region UpDownSpinner Sub-class
|
|
internal sealed class UpDownSpinner : Control {
|
|
#region Local Variables
|
|
private const int InitialRepeatDelay = 50;
|
|
private UpDownBase owner;
|
|
private Timer tmrRepeat;
|
|
private Rectangle top_button_rect;
|
|
private Rectangle bottom_button_rect;
|
|
private int mouse_pressed;
|
|
private int mouse_x;
|
|
private int mouse_y;
|
|
private int repeat_delay;
|
|
private int repeat_counter;
|
|
bool top_button_entered;
|
|
bool bottom_button_entered;
|
|
#endregion // Local Variables
|
|
|
|
#region Constructors
|
|
public UpDownSpinner(UpDownBase owner)
|
|
{
|
|
this.owner = owner;
|
|
|
|
mouse_pressed = 0;
|
|
|
|
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
SetStyle(ControlStyles.DoubleBuffer, true);
|
|
SetStyle(ControlStyles.Opaque, true);
|
|
SetStyle(ControlStyles.ResizeRedraw, true);
|
|
SetStyle(ControlStyles.UserPaint, true);
|
|
SetStyle(ControlStyles.FixedHeight, true);
|
|
SetStyle(ControlStyles.Selectable, false);
|
|
|
|
tmrRepeat = new Timer();
|
|
|
|
tmrRepeat.Enabled = false;
|
|
tmrRepeat.Interval = 10;
|
|
tmrRepeat.Tick += new EventHandler(tmrRepeat_Tick);
|
|
|
|
compute_rects();
|
|
}
|
|
#endregion // Constructors
|
|
|
|
#region Private & Internal Methods
|
|
private void compute_rects ()
|
|
{
|
|
int top_button_height;
|
|
int bottom_button_height;
|
|
|
|
top_button_height = ClientSize.Height / 2;
|
|
bottom_button_height = ClientSize.Height - top_button_height;
|
|
|
|
top_button_rect = new Rectangle(0, 0, ClientSize.Width, top_button_height);
|
|
bottom_button_rect = new Rectangle(0, top_button_height, ClientSize.Width, bottom_button_height);
|
|
}
|
|
|
|
private void redraw (Graphics graphics)
|
|
{
|
|
VisualStyles.PushButtonState top_button_state = VisualStyles.PushButtonState.Normal;
|
|
VisualStyles.PushButtonState bottom_button_state = VisualStyles.PushButtonState.Normal;
|
|
|
|
if (owner.Enabled) {
|
|
if (mouse_pressed != 0) {
|
|
if (mouse_pressed == 1 && top_button_rect.Contains(mouse_x, mouse_y))
|
|
top_button_state = VisualStyles.PushButtonState.Pressed;
|
|
|
|
if (mouse_pressed == 2 && bottom_button_rect.Contains(mouse_x, mouse_y))
|
|
bottom_button_state = VisualStyles.PushButtonState.Pressed;
|
|
} else {
|
|
if (top_button_entered)
|
|
top_button_state = VisualStyles.PushButtonState.Hot;
|
|
if (bottom_button_entered)
|
|
bottom_button_state = VisualStyles.PushButtonState.Hot;
|
|
}
|
|
} else {
|
|
top_button_state = VisualStyles.PushButtonState.Disabled;
|
|
bottom_button_state = VisualStyles.PushButtonState.Disabled;
|
|
}
|
|
ThemeEngine.Current.UpDownBaseDrawButton (graphics, top_button_rect, true, top_button_state);
|
|
ThemeEngine.Current.UpDownBaseDrawButton (graphics, bottom_button_rect, false, bottom_button_state);
|
|
}
|
|
|
|
private void tmrRepeat_Tick (object sender, EventArgs e)
|
|
{
|
|
if (repeat_delay > 1) {
|
|
repeat_counter++;
|
|
|
|
if (repeat_counter < repeat_delay) {
|
|
return;
|
|
}
|
|
|
|
repeat_counter = 0;
|
|
repeat_delay = (repeat_delay * 3 / 4);
|
|
}
|
|
|
|
if (mouse_pressed == 0) {
|
|
tmrRepeat.Enabled = false;
|
|
}
|
|
|
|
if ((mouse_pressed == 1) && top_button_rect.Contains(mouse_x, mouse_y)) {
|
|
owner.UpButton();
|
|
}
|
|
|
|
if ((mouse_pressed == 2) && bottom_button_rect.Contains(mouse_x, mouse_y)) {
|
|
owner.DownButton();
|
|
}
|
|
}
|
|
#endregion // Private & Internal Methods
|
|
|
|
#region Protected Instance Methods
|
|
protected override void OnMouseDown (MouseEventArgs e)
|
|
{
|
|
if (e.Button != MouseButtons.Left) {
|
|
return;
|
|
}
|
|
|
|
if (top_button_rect.Contains(e.X, e.Y)) {
|
|
mouse_pressed = 1;
|
|
owner.UpButton();
|
|
} else if (bottom_button_rect.Contains(e.X, e.Y)) {
|
|
mouse_pressed = 2;
|
|
owner.DownButton();
|
|
}
|
|
|
|
mouse_x = e.X;
|
|
mouse_y = e.Y;
|
|
Capture = true;
|
|
|
|
tmrRepeat.Enabled = true;
|
|
repeat_counter = 0;
|
|
repeat_delay = InitialRepeatDelay;
|
|
|
|
Refresh ();
|
|
}
|
|
|
|
protected override void OnMouseMove (MouseEventArgs e)
|
|
{
|
|
ButtonState before, after;
|
|
|
|
before = ButtonState.Normal;
|
|
if ((mouse_pressed == 1) && top_button_rect.Contains(mouse_x, mouse_y))
|
|
before = ButtonState.Pushed;
|
|
if ((mouse_pressed == 2) && bottom_button_rect.Contains(mouse_x, mouse_y))
|
|
before = ButtonState.Pushed;
|
|
|
|
mouse_x = e.X;
|
|
mouse_y = e.Y;
|
|
|
|
after = ButtonState.Normal;
|
|
if ((mouse_pressed == 1) && top_button_rect.Contains(mouse_x, mouse_y))
|
|
after = ButtonState.Pushed;
|
|
if ((mouse_pressed == 2) && bottom_button_rect.Contains(mouse_x, mouse_y))
|
|
after = ButtonState.Pushed;
|
|
|
|
bool new_top_button_entered = top_button_rect.Contains (e.Location);
|
|
bool new_bottom_button_entered = bottom_button_rect.Contains (e.Location);
|
|
|
|
if (before != after) {
|
|
if (after == ButtonState.Pushed) {
|
|
tmrRepeat.Enabled = true;
|
|
repeat_counter = 0;
|
|
repeat_delay = InitialRepeatDelay;
|
|
|
|
// fire off one right now too for good luck
|
|
if (mouse_pressed == 1)
|
|
owner.UpButton();
|
|
if (mouse_pressed == 2)
|
|
owner.DownButton();
|
|
}
|
|
else
|
|
tmrRepeat.Enabled = false;
|
|
|
|
top_button_entered = new_top_button_entered;
|
|
bottom_button_entered = new_bottom_button_entered;
|
|
|
|
Refresh ();
|
|
} else {
|
|
if (ThemeEngine.Current.UpDownBaseHasHotButtonStyle) {
|
|
Region area_to_invalidate = new Region ();
|
|
bool dirty = false;
|
|
area_to_invalidate.MakeEmpty ();
|
|
if (top_button_entered != new_top_button_entered) {
|
|
top_button_entered = new_top_button_entered;
|
|
area_to_invalidate.Union (top_button_rect);
|
|
dirty = true;
|
|
}
|
|
if (bottom_button_entered != new_bottom_button_entered) {
|
|
bottom_button_entered = new_bottom_button_entered;
|
|
area_to_invalidate.Union (bottom_button_rect);
|
|
dirty = true;
|
|
}
|
|
if (dirty)
|
|
Invalidate (area_to_invalidate);
|
|
area_to_invalidate.Dispose ();
|
|
} else {
|
|
top_button_entered = new_top_button_entered;
|
|
bottom_button_entered = new_bottom_button_entered;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
{
|
|
mouse_pressed = 0;
|
|
Capture = false;
|
|
|
|
Refresh ();
|
|
}
|
|
|
|
protected override void OnMouseWheel(MouseEventArgs e)
|
|
{
|
|
if (e.Delta > 0)
|
|
owner.UpButton();
|
|
else if (e.Delta < 0)
|
|
owner.DownButton();
|
|
}
|
|
|
|
protected override void OnMouseLeave (EventArgs e)
|
|
{
|
|
if (top_button_entered) {
|
|
top_button_entered = false;
|
|
if (ThemeEngine.Current.UpDownBaseHasHotButtonStyle)
|
|
Invalidate (top_button_rect);
|
|
}
|
|
if (bottom_button_entered) {
|
|
bottom_button_entered = false;
|
|
if (ThemeEngine.Current.UpDownBaseHasHotButtonStyle)
|
|
Invalidate (bottom_button_rect);
|
|
}
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
redraw(e.Graphics);
|
|
}
|
|
|
|
protected override void OnResize(EventArgs e)
|
|
{
|
|
base.OnResize(e);
|
|
compute_rects();
|
|
}
|
|
#endregion // Protected Instance Methods
|
|
}
|
|
#endregion // UpDownSpinner Sub-class
|
|
|
|
internal class UpDownTextBox : TextBox {
|
|
|
|
private UpDownBase owner;
|
|
|
|
public UpDownTextBox (UpDownBase owner)
|
|
{
|
|
this.owner = owner;
|
|
|
|
SetStyle (ControlStyles.FixedWidth, false);
|
|
SetStyle (ControlStyles.Selectable, false);
|
|
}
|
|
|
|
|
|
// The following can be shown to be present by
|
|
// adding events to both the UpDown and the
|
|
// internal textbox. the textbox doesn't
|
|
// generate any, and the updown generates them
|
|
// all instead.
|
|
protected override void OnGotFocus (EventArgs e)
|
|
{
|
|
ShowSelection = true;
|
|
owner.OnGotFocus (e);
|
|
// doesn't chain up
|
|
}
|
|
|
|
protected override void OnLostFocus (EventArgs e)
|
|
{
|
|
ShowSelection = false;
|
|
owner.OnLostFocus (e);
|
|
// doesn't chain up
|
|
}
|
|
|
|
protected override void OnMouseDown (MouseEventArgs e)
|
|
{
|
|
// XXX look into whether or not the
|
|
// mouse event args are altered in
|
|
// some way.
|
|
|
|
owner.OnMouseDown (e);
|
|
base.OnMouseDown (e);
|
|
}
|
|
|
|
protected override void OnMouseUp (MouseEventArgs e)
|
|
{
|
|
// XXX look into whether or not the
|
|
// mouse event args are altered in
|
|
// some way.
|
|
|
|
owner.OnMouseUp (e);
|
|
base.OnMouseUp (e);
|
|
}
|
|
|
|
// XXX there are likely more events that forward up to the UpDown
|
|
}
|
|
|
|
#region Local Variables
|
|
internal UpDownTextBox txtView;
|
|
private UpDownSpinner spnSpinner;
|
|
private bool _InterceptArrowKeys = true;
|
|
private LeftRightAlignment _UpDownAlign;
|
|
private bool changing_text;
|
|
private bool user_edit;
|
|
#endregion // Local Variables
|
|
|
|
#region Public Constructors
|
|
public UpDownBase()
|
|
{
|
|
_UpDownAlign = LeftRightAlignment.Right;
|
|
InternalBorderStyle = BorderStyle.Fixed3D;
|
|
|
|
spnSpinner = new UpDownSpinner(this);
|
|
|
|
txtView = new UpDownTextBox (this);
|
|
txtView.ModifiedChanged += new EventHandler(OnChanged);
|
|
txtView.AcceptsReturn = true;
|
|
txtView.AutoSize = false;
|
|
txtView.BorderStyle = BorderStyle.None;
|
|
txtView.Location = new System.Drawing.Point(17, 17);
|
|
txtView.TabIndex = TabIndex;
|
|
|
|
spnSpinner.Width = 16;
|
|
spnSpinner.Dock = DockStyle.Right;
|
|
|
|
txtView.Dock = DockStyle.Fill;
|
|
|
|
SuspendLayout ();
|
|
Controls.Add (spnSpinner);
|
|
Controls.Add (txtView);
|
|
ResumeLayout ();
|
|
|
|
Height = PreferredHeight;
|
|
base.BackColor = txtView.BackColor;
|
|
|
|
TabIndexChanged += new EventHandler (TabIndexChangedHandler);
|
|
|
|
txtView.KeyDown += new KeyEventHandler(OnTextBoxKeyDown);
|
|
txtView.KeyPress += new KeyPressEventHandler(OnTextBoxKeyPress);
|
|
// txtView.LostFocus += new EventHandler(OnTextBoxLostFocus);
|
|
txtView.Resize += new EventHandler(OnTextBoxResize);
|
|
txtView.TextChanged += new EventHandler(OnTextBoxTextChanged);
|
|
|
|
// So the child controls don't get auto selected when the updown is selected
|
|
auto_select_child = false;
|
|
SetStyle(ControlStyles.FixedHeight, true);
|
|
SetStyle(ControlStyles.Selectable, true);
|
|
SetStyle (ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
|
|
SetStyle (ControlStyles.StandardClick | ControlStyles.UseTextForAccessibility, false);
|
|
}
|
|
#endregion
|
|
|
|
#region UIA Framework Events
|
|
static object UIAUpButtonClickEvent = new object ();
|
|
|
|
internal event EventHandler UIAUpButtonClick {
|
|
add { Events.AddHandler (UIAUpButtonClickEvent, value); }
|
|
remove { Events.RemoveHandler (UIAUpButtonClickEvent, value); }
|
|
}
|
|
|
|
internal void OnUIAUpButtonClick (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler) Events [UIAUpButtonClickEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
static object UIADownButtonClickEvent = new object ();
|
|
|
|
internal event EventHandler UIADownButtonClick {
|
|
add { Events.AddHandler (UIADownButtonClickEvent, value); }
|
|
remove { Events.RemoveHandler (UIADownButtonClickEvent, value); }
|
|
}
|
|
|
|
internal void OnUIADownButtonClick (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler) Events [UIADownButtonClickEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
private void TabIndexChangedHandler (object sender, EventArgs e)
|
|
{
|
|
txtView.TabIndex = TabIndex;
|
|
}
|
|
|
|
internal override void OnPaintInternal (PaintEventArgs e)
|
|
{
|
|
e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), ClientRectangle);
|
|
}
|
|
|
|
#endregion // Private Methods
|
|
|
|
#region Public Instance Properties
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public override bool AutoScroll {
|
|
get {
|
|
return base.AutoScroll;
|
|
}
|
|
|
|
set {
|
|
base.AutoScroll = value;
|
|
}
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new Size AutoScrollMargin {
|
|
get { return base.AutoScrollMargin; }
|
|
set { base.AutoScrollMargin = value; }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new Size AutoScrollMinSize {
|
|
get { return base.AutoScrollMinSize; }
|
|
set { base.AutoScrollMinSize = value; }
|
|
}
|
|
|
|
[Browsable (true)]
|
|
[EditorBrowsable (EditorBrowsableState.Always)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
|
|
public override bool AutoSize {
|
|
get { return base.AutoSize; }
|
|
set { base.AutoSize = value; }
|
|
}
|
|
|
|
public override Color BackColor {
|
|
get {
|
|
return base.BackColor;
|
|
}
|
|
|
|
set {
|
|
base.BackColor = value;
|
|
txtView.BackColor = value;
|
|
}
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public override Image BackgroundImage {
|
|
get {
|
|
return base.BackgroundImage;
|
|
}
|
|
set {
|
|
base.BackgroundImage = value;
|
|
txtView.BackgroundImage = value;
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
public override ImageLayout BackgroundImageLayout {
|
|
get { return base.BackgroundImageLayout; }
|
|
set { base.BackgroundImageLayout = value; }
|
|
}
|
|
|
|
[DefaultValue(BorderStyle.Fixed3D)]
|
|
[DispId(-504)]
|
|
public BorderStyle BorderStyle {
|
|
get { return InternalBorderStyle; }
|
|
set { InternalBorderStyle = value; }
|
|
}
|
|
|
|
public override ContextMenu ContextMenu {
|
|
get {
|
|
return base.ContextMenu;
|
|
}
|
|
set {
|
|
base.ContextMenu = value;
|
|
txtView.ContextMenu = value;
|
|
spnSpinner.ContextMenu = value;
|
|
}
|
|
}
|
|
|
|
public override ContextMenuStrip ContextMenuStrip {
|
|
get { return base.ContextMenuStrip; }
|
|
set {
|
|
base.ContextMenuStrip = value;
|
|
txtView.ContextMenuStrip = value;
|
|
spnSpinner.ContextMenuStrip = value;
|
|
}
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new DockPaddingEdges DockPadding {
|
|
get { return base.DockPadding; }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public override bool Focused {
|
|
get {
|
|
return txtView.Focused;
|
|
}
|
|
}
|
|
|
|
public override Color ForeColor {
|
|
get {
|
|
return base.ForeColor;
|
|
}
|
|
set {
|
|
base.ForeColor = value;
|
|
txtView.ForeColor = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue(true)]
|
|
public bool InterceptArrowKeys {
|
|
get {
|
|
return _InterceptArrowKeys;
|
|
}
|
|
set {
|
|
_InterceptArrowKeys = value;
|
|
}
|
|
}
|
|
|
|
public override Size MaximumSize {
|
|
get { return base.MaximumSize; }
|
|
set { base.MaximumSize = new Size (value.Width, 0); }
|
|
}
|
|
|
|
public override Size MinimumSize {
|
|
get { return base.MinimumSize; }
|
|
set { base.MinimumSize = new Size (value.Width, 0); }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
|
public int PreferredHeight {
|
|
get {
|
|
// For some reason, the TextBox's PreferredHeight does not
|
|
// change when the Font property is assigned. Without a
|
|
// border, it will always be Font.Height anyway.
|
|
//int text_box_preferred_height = (txtView != null) ? txtView.PreferredHeight : Font.Height;
|
|
int text_box_preferred_height = Font.Height;
|
|
|
|
switch (border_style) {
|
|
case BorderStyle.FixedSingle:
|
|
case BorderStyle.Fixed3D:
|
|
text_box_preferred_height += 3; // magic number? :-)
|
|
|
|
return text_box_preferred_height + 4;
|
|
|
|
case BorderStyle.None:
|
|
default:
|
|
return text_box_preferred_height;
|
|
}
|
|
}
|
|
}
|
|
|
|
[DefaultValue(false)]
|
|
public bool ReadOnly {
|
|
get {
|
|
return txtView.ReadOnly;
|
|
}
|
|
set {
|
|
txtView.ReadOnly = value;
|
|
}
|
|
}
|
|
|
|
[Localizable(true)]
|
|
public override string Text {
|
|
get {
|
|
if (txtView != null) {
|
|
return txtView.Text;
|
|
}
|
|
return "";
|
|
}
|
|
set {
|
|
txtView.Text = value;
|
|
if (this.UserEdit)
|
|
ValidateEditText();
|
|
|
|
txtView.SelectionLength = 0;
|
|
}
|
|
}
|
|
|
|
[DefaultValue(HorizontalAlignment.Left)]
|
|
[Localizable(true)]
|
|
public HorizontalAlignment TextAlign {
|
|
get {
|
|
return txtView.TextAlign;
|
|
}
|
|
set{
|
|
txtView.TextAlign = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue(LeftRightAlignment.Right)]
|
|
[Localizable(true)]
|
|
public LeftRightAlignment UpDownAlign {
|
|
get {
|
|
return _UpDownAlign;
|
|
}
|
|
set {
|
|
if (_UpDownAlign != value) {
|
|
_UpDownAlign = value;
|
|
|
|
if (value == LeftRightAlignment.Left)
|
|
spnSpinner.Dock = DockStyle.Left;
|
|
else
|
|
spnSpinner.Dock = DockStyle.Right;
|
|
}
|
|
}
|
|
}
|
|
#endregion // Public Instance Properties
|
|
|
|
#region Protected Instance Properties
|
|
protected bool ChangingText {
|
|
get {
|
|
return changing_text;
|
|
}
|
|
set {
|
|
changing_text = value;
|
|
}
|
|
}
|
|
|
|
protected override CreateParams CreateParams {
|
|
get {
|
|
return base.CreateParams;
|
|
}
|
|
}
|
|
|
|
protected override Size DefaultSize {
|
|
get {
|
|
return new Size(120, this.PreferredHeight);
|
|
}
|
|
}
|
|
|
|
protected bool UserEdit {
|
|
get {
|
|
return user_edit;
|
|
}
|
|
set {
|
|
user_edit = value;
|
|
}
|
|
}
|
|
#endregion // Protected Instance Properties
|
|
|
|
#region Public Instance Methods
|
|
public abstract void DownButton ();
|
|
public void Select(int start, int length)
|
|
{
|
|
txtView.Select(start, length);
|
|
}
|
|
|
|
public abstract void UpButton ();
|
|
#endregion // Public Instance Methods
|
|
|
|
#region Protected Instance Methods
|
|
protected virtual void OnChanged (object source, EventArgs e)
|
|
{
|
|
}
|
|
|
|
protected override void OnFontChanged (EventArgs e)
|
|
{
|
|
txtView.Font = this.Font;
|
|
Height = PreferredHeight;
|
|
}
|
|
|
|
protected override void OnHandleCreated (EventArgs e)
|
|
{
|
|
base.OnHandleCreated (e);
|
|
}
|
|
|
|
protected override void OnHandleDestroyed (EventArgs e)
|
|
{
|
|
base.OnHandleDestroyed (e);
|
|
}
|
|
|
|
protected override void OnLayout (LayoutEventArgs e)
|
|
{
|
|
base.OnLayout(e);
|
|
}
|
|
|
|
protected override void OnMouseDown (MouseEventArgs e)
|
|
{
|
|
base.OnMouseDown (e);
|
|
}
|
|
|
|
protected override void OnMouseUp (MouseEventArgs mevent)
|
|
{
|
|
base.OnMouseUp (mevent);
|
|
}
|
|
|
|
protected override void OnMouseWheel (MouseEventArgs e)
|
|
{
|
|
if (e.Delta > 0)
|
|
UpButton();
|
|
else if (e.Delta < 0)
|
|
DownButton();
|
|
}
|
|
|
|
protected override void OnPaint (PaintEventArgs e)
|
|
{
|
|
base.OnPaint (e);
|
|
}
|
|
|
|
protected virtual void OnTextBoxKeyDown (object source, KeyEventArgs e)
|
|
{
|
|
if (_InterceptArrowKeys) {
|
|
if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down)) {
|
|
e.Handled = true;
|
|
|
|
if (e.KeyCode == Keys.Up)
|
|
UpButton();
|
|
if (e.KeyCode == Keys.Down)
|
|
DownButton();
|
|
}
|
|
}
|
|
|
|
OnKeyDown(e);
|
|
}
|
|
|
|
protected virtual void OnTextBoxKeyPress (object source, KeyPressEventArgs e)
|
|
{
|
|
if (e.KeyChar == '\r') {
|
|
e.Handled = true;
|
|
ValidateEditText();
|
|
}
|
|
OnKeyPress(e);
|
|
}
|
|
|
|
protected virtual void OnTextBoxLostFocus (object source, EventArgs e)
|
|
{
|
|
if (UserEdit) {
|
|
ValidateEditText();
|
|
}
|
|
}
|
|
|
|
protected virtual void OnTextBoxResize (object source, EventArgs e)
|
|
{
|
|
// compute the new height, taking the border into account
|
|
Height = PreferredHeight;
|
|
|
|
// let anchoring reposition the controls
|
|
}
|
|
|
|
protected virtual void OnTextBoxTextChanged (object source, EventArgs e)
|
|
{
|
|
if (changing_text)
|
|
ChangingText = false;
|
|
else
|
|
UserEdit = true;
|
|
|
|
OnTextChanged(e);
|
|
}
|
|
|
|
internal override void SetBoundsCoreInternal(int x, int y, int width, int height, BoundsSpecified specified)
|
|
{
|
|
base.SetBoundsCoreInternal (x, y, width, Math.Min (width, PreferredHeight), specified);
|
|
}
|
|
|
|
protected abstract void UpdateEditText ();
|
|
|
|
protected virtual void ValidateEditText ()
|
|
{
|
|
// to be overridden by subclassers
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
|
protected override void WndProc (ref Message m)
|
|
{
|
|
switch((Msg) m.Msg) {
|
|
case Msg.WM_KEYUP:
|
|
case Msg.WM_KEYDOWN:
|
|
case Msg.WM_CHAR:
|
|
XplatUI.SendMessage (txtView.Handle, (Msg) m.Msg, m.WParam, m.LParam);
|
|
break;
|
|
case Msg.WM_SETFOCUS:
|
|
ActiveControl = txtView;
|
|
break;
|
|
case Msg.WM_KILLFOCUS:
|
|
ActiveControl = null;
|
|
break;
|
|
default:
|
|
base.WndProc (ref m);
|
|
break;
|
|
}
|
|
}
|
|
#endregion // Protected Instance Methods
|
|
|
|
#region Events
|
|
[Browsable (true)]
|
|
[EditorBrowsable (EditorBrowsableState.Always)]
|
|
public new event EventHandler AutoSizeChanged {
|
|
add { base.AutoSizeChanged += value; }
|
|
remove { base.AutoSizeChanged -= value; }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new event EventHandler BackgroundImageChanged {
|
|
add { base.BackgroundImageChanged += value; }
|
|
remove { base.BackgroundImageChanged -= value; }
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new event EventHandler BackgroundImageLayoutChanged {
|
|
add { base.BackgroundImageLayoutChanged += value; }
|
|
remove { base.BackgroundImageLayoutChanged -= value; }
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new event EventHandler MouseEnter {
|
|
add { base.MouseEnter += value; }
|
|
remove { base.MouseEnter -= value; }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new event EventHandler MouseHover {
|
|
add { base.MouseHover += value; }
|
|
remove { base.MouseHover -= value; }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new event EventHandler MouseLeave {
|
|
add { base.MouseLeave += value; }
|
|
remove { base.MouseLeave -= value; }
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public new event MouseEventHandler MouseMove {
|
|
add { base.MouseMove += value; }
|
|
remove { base.MouseMove -= value; }
|
|
}
|
|
#endregion // Events
|
|
}
|
|
}
|