| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- // 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) 2004 Novell, Inc.
- //
- // Authors:
- // Miguel de Icaza ([email protected]).
- //
- //
- /*
- TODO:
- - Force the size of the entry: it can not be resized vertically
- ever, the size is set by the size of the font
- */
- using System;
- using System.Drawing;
- namespace System.Windows.Forms {
- public abstract class UpDownBase : ContainerControl {
- internal class Spinner : Control, IDisposable {
- UpDownBase updownbase;
- Rectangle up, down, pressed;
- Timer timer;
- bool up_pressed, down_pressed;
- bool captured, mouse_in;
- //
- // Interval values
- //
- const int StartInterval = 1000;
- const int RepeatInterval = 400;
- const int ChangeInterval = 75;
- const int MinimumInterval = 20;
-
- internal Spinner (UpDownBase updownbase)
- {
- this.updownbase = updownbase;
- }
- protected override void OnPaint (PaintEventArgs args)
- {
- Draw (args.ClipRectangle);
- args.Graphics.DrawImage (ImageBuffer, 0, 0);
- }
- protected override void OnLayout (LayoutEventArgs args)
- {
- base.OnLayout (args);
- Rectangle bounds = Bounds;
- up = new Rectangle (0, 0, bounds.Width, bounds.Height/2);
- down = new Rectangle (0, bounds.Height/2, bounds.Width, bounds.Height/2);
- }
- protected override void OnMouseDown (MouseEventArgs args)
- {
- base.OnMouseDown (args);
- if (args.Button != MouseButtons.Left)
- return;
- if (up.Contains (args.X, args.Y)){
- up_pressed = true;
- pressed = up;
- } else if (down.Contains (args.X, args.Y)){
- down_pressed = true;
- pressed = down;
- } else
- return;
- Click ();
- Invalidate (pressed);
- Capture = true;
- InitTimer ();
-
- mouse_in = down_pressed | up_pressed;
- }
- protected override void OnMouseUp (MouseEventArgs args)
- {
- if (Capture){
- if (up_pressed){
- up_pressed = false;
- Invalidate (up);
- }
- if (down_pressed){
- down_pressed = false;
- Invalidate (down);
- }
- }
- Capture = false;
- }
- //
- // Sets up the auto-repeat timer, we give a one second
- // delay, and then we use the keyboard settings for auto-repeat.
- //
- void InitTimer ()
- {
- timer = new Timer ();
- int kd = SystemInformation.KeyboardDelay;
- kd = kd < 0 ? 0 : (kd > 4 ? 4 : kd);
- timer.Interval = StartInterval;
- timer.Tick += new EventHandler (ClockTick);
- timer.Enabled = true;
- }
- void ClockTick (object o, EventArgs a)
- {
- if (timer == null)
- throw new Exception ("The timer that owns this callback is null!");
-
- int interval = timer.Interval;
- if (interval == StartInterval)
- interval = RepeatInterval;
- else
- interval -= ChangeInterval;
- if (interval < MinimumInterval)
- interval = MinimumInterval;
- timer.Interval = interval;
- Click ();
- }
- void Click ()
- {
- if (up_pressed)
- updownbase.UpButton ();
- if (down_pressed)
- updownbase.DownButton ();
- }
- protected override void OnMouseMove (MouseEventArgs args)
- {
- base.OnMouseMove (args);
- if (Capture){
- bool old = mouse_in;
- if (pressed.Contains (args.X, args.Y)){
- if (timer == null)
- InitTimer ();
- mouse_in = true;
- } else {
- if (timer != null){
- timer.Enabled = false;
- timer.Dispose ();
- timer = null;
- }
- mouse_in = false;
- }
- if (mouse_in ^ old){
- Console.WriteLine ("STATE CHANGE");
- if (mouse_in)
- Click ();
- Invalidate (pressed);
- }
- }
- }
-
- void DrawUp ()
- {
- ButtonState bs;
- bs = mouse_in && up_pressed ? ButtonState.Pushed : ButtonState.Normal;
- ThemeEngine.Current.CPDrawScrollButton (DeviceContext, up, ScrollButton.Up, bs);
- }
-
- void DrawDown ()
- {
- ButtonState bs;
- bs = mouse_in && down_pressed ? ButtonState.Pushed : ButtonState.Normal;
- ThemeEngine.Current.CPDrawScrollButton (DeviceContext, down, ScrollButton.Down, bs);
- }
- void Draw (Rectangle clip)
- {
- if (clip.Contains (up))
- DrawUp ();
- if (clip.Contains (down))
- DrawDown ();
- }
- void IDisposable.Dispose ()
- {
- if (timer != null){
- timer.Stop ();
- timer.Dispose ();
- }
- timer = null;
- base.Dispose ();
- }
- }
- int desired_height = 0;
- Label entry;
- Spinner spinner;
- int scrollbar_button_size = ThemeEngine.Current.ScrollBarButtonSize;
-
- public UpDownBase () : base ()
- {
- SuspendLayout ();
- entry = new Label ();
- entry.Text = "I will be an Entry";
- entry.Font = Font;
- entry.Size = new Size (100, Font.Height + 4);
- entry.Location = new Point (0, 0);
- Controls.Add (entry);
- spinner = new Spinner (this);
- Controls.Add (spinner);
-
- ResumeLayout ();
-
- }
- #region UpDownBase overwritten methods
-
- protected override void OnMouseWheel (MouseEventArgs args)
- {
- base.OnMouseWheel (args);
- if (args.Delta > 0)
- UpButton ();
- else if (args.Delta < 0)
- DownButton ();
- }
- protected virtual void OnChanged (object source, EventArgs e)
- {
- // Not clear, the docs state that this will raise the
- // Changed event, but that event is not listed anywhere.
- }
- protected override void OnFontChanged (EventArgs e)
- {
- base.OnFontChanged (e);
- entry.Font = Font;
- desired_height = entry.Height;
- Height = desired_height;
- }
- protected override void OnHandleCreated (EventArgs e)
- {
- base.OnHandleCreated (e);
- desired_height = entry.Height;
- }
-
- protected override void OnLayout (LayoutEventArgs args)
- {
- base.OnLayout (args);
- Rectangle bounds = Bounds;
- int entry_width = bounds.Right - scrollbar_button_size - 1;
- entry.SetBounds (bounds.X, bounds.Y, entry_width, bounds.Height);
- spinner.SetBounds (entry_width + 1, bounds.Y, scrollbar_button_size, bounds.Height);
- }
- protected override void OnPaint (PaintEventArgs e)
- {
- base.OnPaint (e);
- }
- protected override void SetVisibleCore (bool state)
- {
- base.SetVisibleCore (state);
- }
- protected override void WndProc (ref Message m)
- {
- base.WndProc (ref m);
- }
- protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
- {
- //
- // Force the size to be our height.
- //
- base.SetBoundsCore (x, y, width, desired_height, specified);
- }
-
- protected override void Dispose (bool disposing)
- {
- if (spinner != null){
- if (disposing){
- spinner.Dispose ();
- entry.Dispose ();
- }
- }
- spinner = null;
- entry = null;
- base.Dispose (true);
- }
-
- #endregion
-
- #region UpDownBase virtual methods
- //
- // These are hooked up to the various events from the Entry line that
- // we do not have yet, and implement the keyboard behavior (use a different
- // widget to test)
- //
- protected virtual void OnTextBoxKeyDown (object source, KeyEventArgs e)
- {
- }
-
- protected virtual void OnTextBoxKeyPress (object source, KeyPressEventArgs e)
- {
- }
- protected virtual void OnTextBoxLostFocus (object source, EventArgs e)
- {
- }
- protected virtual void OnTextBoxResize (object source, EventArgs e)
- {
- }
- protected virtual void OnTextBoxTextChanged (object source, EventArgs e)
- {
- }
- protected virtual void ValidateEditText ()
- {
- }
- #endregion
- #region UpDownBase standard methods
- public void Select (int start, int length)
- {
- // Selects text from start for lenght chars.
- }
- #endregion
- #region Abstract methods
- public abstract void DownButton ();
- public abstract void UpButton ();
- public abstract void UpdateEditText ();
- #endregion
- }
- }
|