ScrollBar.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. //
  2. // System.Windows.Forms.ScrollBar.cs
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining
  5. // a copy of this software and associated documentation files (the
  6. // "Software"), to deal in the Software without restriction, including
  7. // without limitation the rights to use, copy, modify, merge, publish,
  8. // distribute, sublicense, and/or sell copies of the Software, and to
  9. // permit persons to whom the Software is furnished to do so, subject to
  10. // the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be
  13. // included in all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. //
  23. // Copyright (C) 2004, Novell, Inc.
  24. //
  25. // Authors:
  26. // Jordi Mas i Hernandez [email protected]
  27. //
  28. //
  29. // COMPLETE
  30. using System.Drawing;
  31. using System.Drawing.Imaging;
  32. using System.Drawing.Drawing2D;
  33. using System.ComponentModel;
  34. using System.Runtime.InteropServices;
  35. namespace System.Windows.Forms
  36. {
  37. [DefaultEvent ("Scroll")]
  38. [DefaultProperty ("Value")]
  39. public class ScrollBar : Control
  40. {
  41. #region Local Variables
  42. private int position;
  43. private int minimum;
  44. private int maximum;
  45. private int large_change;
  46. private int small_change;
  47. internal int scrollbutton_height;
  48. internal int scrollbutton_width;
  49. private ScrollBars type;
  50. private Rectangle first_arrow_area = new Rectangle (); // up or left
  51. private Rectangle second_arrow_area = new Rectangle (); // down or right
  52. private Rectangle thumb_pos = new Rectangle ();
  53. private Rectangle thumb_area = new Rectangle ();
  54. internal ButtonState firstbutton_state = ButtonState.Normal;
  55. internal ButtonState secondbutton_state = ButtonState.Normal;
  56. private bool firstbutton_pressed = false;
  57. private bool secondbutton_pressed = false;
  58. private bool thumb_pressed = false;
  59. private float pixel_per_pos = 0;
  60. private Timer timer = new Timer ();
  61. private TimerType timer_type;
  62. private int thumb_pixel_click_move;
  63. private int thumb_pixel_click_move_prev;
  64. private int thumb_size = 40;
  65. private const int thumb_min_size = 8;
  66. private const int thumb_notshown_size = 40;
  67. internal bool vert;
  68. private int lastclick_pos; // Position of the last button-down event
  69. private int lastclick_pos_thumb; // Position of the last button-down event relative to the thumb
  70. private bool outside_thumbarea_right = false;
  71. private bool outside_thumbarea_left = false;
  72. internal ThumbMoving thumb_moving = ThumbMoving.None;
  73. #endregion // Local Variables
  74. private enum TimerType
  75. {
  76. HoldButton,
  77. RepeatButton,
  78. HoldThumbArea,
  79. RepeatThumbArea
  80. }
  81. internal enum ThumbMoving
  82. {
  83. None,
  84. Forward,
  85. Backwards,
  86. }
  87. #region Events
  88. public new event EventHandler BackColorChanged;
  89. public new event EventHandler BackgroundImageChanged;
  90. public new event EventHandler Click;
  91. public new event EventHandler DoubleClick;
  92. public new event EventHandler FontChanged;
  93. public new event EventHandler ForeColorChanged;
  94. public new event EventHandler ImeModeChanged;
  95. public new event MouseEventHandler MouseDown;
  96. public new event MouseEventHandler MouseMove;
  97. public new event MouseEventHandler MouseUp;
  98. public new event PaintEventHandler Paint;
  99. public event ScrollEventHandler Scroll;
  100. public new event EventHandler TextChanged;
  101. public event EventHandler ValueChanged;
  102. #endregion Events
  103. public ScrollBar ()
  104. {
  105. position = 0;
  106. minimum = 0;
  107. maximum = 100;
  108. large_change = 10;
  109. small_change = 1;
  110. timer.Tick += new EventHandler (OnTimer);
  111. base.KeyDown += new KeyEventHandler (OnKeyDownSB);
  112. base.MouseDown += new MouseEventHandler (OnMouseDownSB);
  113. base.MouseUp += new MouseEventHandler (OnMouseUpSB);
  114. base.MouseMove += new MouseEventHandler (OnMouseMoveSB);
  115. base.Resize += new EventHandler (OnResizeSB);
  116. base.TabStop = false;
  117. if (ThemeEngine.Current.DoubleBufferingSupported == true) {
  118. double_buffering = true;
  119. } else {
  120. double_buffering = false;
  121. }
  122. SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
  123. SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
  124. }
  125. #region Internal & Private Properties
  126. internal Rectangle FirstArrowArea {
  127. get {
  128. return this.first_arrow_area;
  129. }
  130. set {
  131. this.first_arrow_area = value;
  132. }
  133. }
  134. internal Rectangle SecondArrowArea {
  135. get {
  136. return this.second_arrow_area;
  137. }
  138. set {
  139. this.second_arrow_area = value;
  140. }
  141. }
  142. internal Rectangle ThumbPos {
  143. get {
  144. return thumb_pos;
  145. }
  146. set {
  147. thumb_pos = value;
  148. }
  149. }
  150. #endregion // Internal & Private Properties
  151. #region Public Properties
  152. [EditorBrowsable (EditorBrowsableState.Never)]
  153. public override Color BackColor
  154. {
  155. get { return base.BackColor; }
  156. set {
  157. if (base.BackColor == value)
  158. return;
  159. if (BackColorChanged != null)
  160. BackColorChanged (this, EventArgs.Empty);
  161. base.BackColor = value;
  162. Refresh ();
  163. }
  164. }
  165. [EditorBrowsable (EditorBrowsableState.Never)]
  166. public override Image BackgroundImage
  167. {
  168. get { return base.BackgroundImage; }
  169. set {
  170. if (base.BackgroundImage == value)
  171. return;
  172. if (BackgroundImageChanged != null)
  173. BackgroundImageChanged (this, EventArgs.Empty);
  174. base.BackgroundImage = value;
  175. }
  176. }
  177. protected override CreateParams CreateParams
  178. {
  179. get { return base.CreateParams; }
  180. }
  181. protected override ImeMode DefaultImeMode
  182. {
  183. get { return ImeMode.Disable; }
  184. }
  185. public override Font Font
  186. {
  187. get { return base.Font; }
  188. set {
  189. if (base.Font == value)
  190. return;
  191. if (FontChanged != null)
  192. FontChanged (this, EventArgs.Empty);
  193. base.Font = value;
  194. }
  195. }
  196. [EditorBrowsable (EditorBrowsableState.Never)]
  197. public override Color ForeColor
  198. {
  199. get { return base.ForeColor; }
  200. set {
  201. if (base.ForeColor == value)
  202. return;
  203. if (ForeColorChanged != null)
  204. ForeColorChanged (this, EventArgs.Empty);
  205. base.ForeColor = value;
  206. Refresh ();
  207. }
  208. }
  209. [EditorBrowsable (EditorBrowsableState.Never)]
  210. public new ImeMode ImeMode
  211. {
  212. get { return base.ImeMode; }
  213. set {
  214. if (base.ImeMode == value)
  215. return;
  216. if (ImeModeChanged != null)
  217. ImeModeChanged (this, EventArgs.Empty);
  218. base.ImeMode = value;
  219. }
  220. }
  221. public int LargeChange {
  222. get {
  223. if (large_change > maximum)
  224. return (maximum + 1);
  225. else
  226. return large_change;
  227. }
  228. set {
  229. if (value < 0)
  230. throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
  231. if (large_change != value) {
  232. large_change = value;
  233. // thumb area depends on large change value,
  234. // so we need to recalculate it.
  235. CalcThumbArea ();
  236. UpdatePos (Value, true);
  237. Refresh ();
  238. }
  239. }
  240. }
  241. public int Maximum {
  242. get { return maximum; }
  243. set {
  244. maximum = value;
  245. if (maximum < minimum)
  246. minimum = maximum;
  247. // thumb area depends on maximum value,
  248. // so we need to recalculate it.
  249. CalcThumbArea ();
  250. UpdatePos (Value, true);
  251. Refresh ();
  252. }
  253. }
  254. public int Minimum {
  255. get { return minimum; }
  256. set {
  257. minimum = value;
  258. if (minimum > maximum)
  259. maximum = minimum;
  260. // thumb area depends on minimum value,
  261. // so we need to recalculate it.
  262. CalcThumbArea ();
  263. UpdatePos (Value, true);
  264. Refresh ();
  265. }
  266. }
  267. public int SmallChange {
  268. get { return small_change; }
  269. set {
  270. if ( value < 0 )
  271. throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
  272. if (small_change != value) {
  273. small_change = value;
  274. UpdatePos (Value, true);
  275. Refresh ();
  276. }
  277. }
  278. }
  279. public new bool TabStop {
  280. get { return base.TabStop; }
  281. set { base.TabStop = value; }
  282. }
  283. [EditorBrowsable (EditorBrowsableState.Never)]
  284. public override string Text {
  285. get { return base.Text; }
  286. set { base.Text = value; }
  287. }
  288. public int Value {
  289. get { return position; }
  290. set {
  291. if ( value < minimum || value > maximum )
  292. throw new ArgumentException(
  293. string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
  294. if (position != value){
  295. position = value;
  296. if (ValueChanged != null)
  297. ValueChanged (this, EventArgs.Empty);
  298. UpdatePos (Value, true);
  299. Refresh ();
  300. }
  301. }
  302. }
  303. #endregion //Public Properties
  304. #region Public Methods
  305. protected override void OnEnabledChanged (EventArgs e)
  306. {
  307. base.OnEnabledChanged (e);
  308. if (Enabled)
  309. firstbutton_state = secondbutton_state = ButtonState.Normal;
  310. else
  311. firstbutton_state = secondbutton_state = ButtonState.Inactive;
  312. Refresh ();
  313. }
  314. protected override void OnHandleCreated (System.EventArgs e)
  315. {
  316. base.OnHandleCreated (e);
  317. CalcThumbArea ();
  318. UpdatePos (Value, true);
  319. }
  320. protected virtual void OnScroll (ScrollEventArgs event_args)
  321. {
  322. if (Scroll == null)
  323. return;
  324. Scroll (this, event_args);
  325. }
  326. protected virtual void OnValueChanged (EventArgs e)
  327. {
  328. if (ValueChanged != null)
  329. ValueChanged (this, e);
  330. }
  331. public override string ToString()
  332. {
  333. return string.Format("{0}, Minimum: {1}, Maximum: {2}, Value: {3}",
  334. GetType( ).FullName.ToString( ), minimum, maximum, position);
  335. }
  336. protected void UpdateScrollInfo ()
  337. {
  338. Refresh ();
  339. }
  340. protected override void WndProc (ref Message m)
  341. {
  342. switch ((Msg) m.Msg)
  343. {
  344. case Msg.WM_PAINT:
  345. {
  346. PaintEventArgs paint_event;
  347. paint_event = XplatUI.PaintEventStart (Handle);
  348. OnPaintSB (paint_event);
  349. XplatUI.PaintEventEnd (Handle);
  350. return;
  351. }
  352. case Msg.WM_ERASEBKGND:
  353. m.Result = (IntPtr) 1; /// Disable background painting to avoid flickering
  354. return;
  355. default:
  356. break;
  357. }
  358. base.WndProc (ref m);
  359. }
  360. #endregion //Public Methods
  361. #region Private Methods
  362. private void CalcThumbArea ()
  363. {
  364. // Thumb area
  365. if (vert) {
  366. thumb_area.Height = Height - scrollbutton_height - scrollbutton_height;
  367. thumb_area.X = 0;
  368. thumb_area.Y = scrollbutton_height;
  369. thumb_area.Width = Width;
  370. if (Height < thumb_notshown_size)
  371. thumb_size = 0;
  372. else {
  373. double per = ((double) this.LargeChange / (double)((1 + maximum - minimum)));
  374. thumb_size = 1 + (int) (thumb_area.Height * per);
  375. if (thumb_size < thumb_min_size)
  376. thumb_size = thumb_min_size;
  377. }
  378. pixel_per_pos = ((float)(thumb_area.Height - thumb_size) / (float) ((maximum - minimum - this.LargeChange) + 1));
  379. } else {
  380. thumb_area.Y = 0;
  381. thumb_area.X = scrollbutton_width;
  382. thumb_area.Height = Height;
  383. thumb_area.Width = Width - scrollbutton_width - scrollbutton_width;
  384. if (Width < thumb_notshown_size)
  385. thumb_size = 0;
  386. else {
  387. double per = ((double) this.LargeChange / (double)((1 + maximum - minimum)));
  388. thumb_size = 1 + (int) (thumb_area.Width * per);
  389. if (thumb_size < thumb_min_size)
  390. thumb_size = thumb_min_size;
  391. }
  392. pixel_per_pos = ((float)(thumb_area.Width - thumb_size) / (float) ((maximum - minimum - this.LargeChange) + 1));
  393. }
  394. }
  395. private void Draw ()
  396. {
  397. ThemeEngine.Current.DrawScrollBar(DeviceContext, this.ClientRectangle, this);
  398. }
  399. private void LargeIncrement ()
  400. {
  401. UpdatePos (position + large_change, true);
  402. Refresh ();
  403. OnScroll (new ScrollEventArgs (ScrollEventType.LargeIncrement, position));
  404. OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
  405. }
  406. private void LargeDecrement ()
  407. {
  408. UpdatePos (position - large_change, true);
  409. Refresh ();
  410. OnScroll (new ScrollEventArgs (ScrollEventType.LargeDecrement, position));
  411. OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
  412. }
  413. private void OnResizeSB (Object o, EventArgs e)
  414. {
  415. if (Width <= 0 || Height <= 0)
  416. return;
  417. if (vert) {
  418. if (Height < ThemeEngine.Current.ScrollBarButtonSize * 2)
  419. scrollbutton_height = Height /2;
  420. else
  421. scrollbutton_height = ThemeEngine.Current.ScrollBarButtonSize;
  422. } else {
  423. if (Width < ThemeEngine.Current.ScrollBarButtonSize * 2)
  424. scrollbutton_width = Width /2;
  425. else
  426. scrollbutton_width = ThemeEngine.Current.ScrollBarButtonSize;
  427. }
  428. CalcThumbArea ();
  429. UpdatePos (position, true);
  430. }
  431. private void OnPaintSB (PaintEventArgs pevent)
  432. {
  433. if (Width <= 0 || Height <= 0 || Visible == false)
  434. return;
  435. /* Copies memory drawing buffer to screen*/
  436. Draw ();
  437. if (double_buffering)
  438. pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
  439. }
  440. private void OnTimer (Object source, EventArgs e)
  441. {
  442. switch (timer_type) {
  443. case TimerType.HoldButton:
  444. SetRepeatButtonTimer ();
  445. break;
  446. case TimerType.RepeatButton:
  447. {
  448. if ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
  449. SmallDecrement();
  450. if ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
  451. SmallIncrement();
  452. break;
  453. }
  454. case TimerType.HoldThumbArea:
  455. SetRepeatThumbAreaTimer ();
  456. break;
  457. case TimerType.RepeatThumbArea:
  458. {
  459. Point pnt;
  460. pnt = PointToClient (MousePosition);
  461. if (vert)
  462. lastclick_pos = pnt.Y;
  463. else
  464. lastclick_pos = pnt.X;
  465. if (thumb_moving == ThumbMoving.Forward) {
  466. if ((vert && (thumb_pos.Y + thumb_size > lastclick_pos)) ||
  467. (!vert && (thumb_pos.X + thumb_size > lastclick_pos)) ||
  468. (thumb_area.Contains (pnt) == false)){
  469. timer.Enabled = false;
  470. thumb_moving = ThumbMoving.None;
  471. Refresh ();
  472. } else
  473. LargeIncrement ();
  474. }
  475. else
  476. if ((vert && (thumb_pos.Y < lastclick_pos)) ||
  477. (!vert && (thumb_pos.X < lastclick_pos))){
  478. timer.Enabled = false;
  479. thumb_moving = ThumbMoving.None;
  480. Refresh ();
  481. } else
  482. LargeDecrement ();
  483. break;
  484. }
  485. default:
  486. break;
  487. }
  488. }
  489. private void OnMouseMoveSB (object sender, MouseEventArgs e)
  490. {
  491. if (Enabled == false || thumb_size == 0)
  492. return;
  493. if (firstbutton_pressed) {
  494. if (!first_arrow_area.Contains (e.X, e.Y) && ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) {
  495. firstbutton_state = ButtonState.Normal;
  496. Refresh ();
  497. return;
  498. } else if (first_arrow_area.Contains (e.X, e.Y) && ((firstbutton_state & ButtonState.Normal) == ButtonState.Normal)) {
  499. firstbutton_state = ButtonState.Pushed;
  500. Refresh ();
  501. return;
  502. }
  503. } else if (secondbutton_pressed) {
  504. if (!second_arrow_area.Contains (e.X, e.Y) && ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) {
  505. secondbutton_state = ButtonState.Normal;
  506. Refresh ();
  507. return;
  508. } else if (second_arrow_area.Contains (e.X, e.Y) && ((secondbutton_state & ButtonState.Normal) == ButtonState.Normal)) {
  509. secondbutton_state = ButtonState.Pushed;
  510. Refresh ();
  511. return;
  512. }
  513. } else if (thumb_pressed == true) {
  514. int pixel_pos;
  515. if (vert) {
  516. int mouse_click = e.Y;
  517. int outside_curpos = thumb_area.Y + thumb_area.Height - thumb_size + lastclick_pos_thumb;
  518. if (mouse_click > thumb_area.Y + thumb_area.Height) {
  519. outside_thumbarea_right = true;
  520. mouse_click = thumb_area.Y + thumb_area.Height;
  521. }
  522. if (mouse_click < thumb_area.Y) {
  523. outside_thumbarea_left = true;
  524. mouse_click = thumb_area.Y;
  525. }
  526. if (outside_thumbarea_right && mouse_click < outside_curpos) {
  527. outside_thumbarea_right = false;
  528. thumb_pixel_click_move_prev =
  529. thumb_pixel_click_move = outside_curpos;
  530. }
  531. if (outside_thumbarea_left && mouse_click > thumb_area.Y + lastclick_pos_thumb) {
  532. outside_thumbarea_left = false;
  533. thumb_pixel_click_move_prev =
  534. thumb_pixel_click_move = thumb_area.Y + lastclick_pos_thumb;
  535. }
  536. if (outside_thumbarea_right == false && outside_thumbarea_left == false) {
  537. pixel_pos = thumb_pos.Y + (thumb_pixel_click_move - thumb_pixel_click_move_prev);
  538. thumb_pixel_click_move_prev = thumb_pixel_click_move;
  539. thumb_pixel_click_move = mouse_click;
  540. UpdateThumbPos (pixel_pos, true);
  541. }
  542. }
  543. else {
  544. int mouse_click = e.X;
  545. int outside_curpos = thumb_area.X + thumb_area.Width - thumb_size + lastclick_pos_thumb;
  546. if (mouse_click > thumb_area.X + thumb_area.Width) {
  547. outside_thumbarea_right = true;
  548. mouse_click = thumb_area.X + thumb_area.Width;
  549. }
  550. if (mouse_click < thumb_area.X) {
  551. outside_thumbarea_left = true;
  552. mouse_click = thumb_area.X;
  553. }
  554. if (outside_thumbarea_right && mouse_click < outside_curpos) {
  555. outside_thumbarea_right = false;
  556. thumb_pixel_click_move_prev =
  557. thumb_pixel_click_move = outside_curpos;
  558. }
  559. if (outside_thumbarea_left && mouse_click > thumb_area.X + lastclick_pos_thumb) {
  560. outside_thumbarea_left = false;
  561. thumb_pixel_click_move_prev =
  562. thumb_pixel_click_move = thumb_area.X + lastclick_pos_thumb;
  563. }
  564. if (outside_thumbarea_right == false && outside_thumbarea_left == false) {
  565. pixel_pos = thumb_pos.X + (thumb_pixel_click_move - thumb_pixel_click_move_prev);
  566. thumb_pixel_click_move_prev = thumb_pixel_click_move;
  567. thumb_pixel_click_move = mouse_click;
  568. UpdateThumbPos (pixel_pos, true);
  569. }
  570. }
  571. Refresh ();
  572. }
  573. }
  574. private void OnMouseDownSB (object sender, MouseEventArgs e)
  575. {
  576. if (Enabled == false)
  577. return;
  578. if (firstbutton_state != ButtonState.Inactive && first_arrow_area.Contains (e.X, e.Y)) {
  579. this.Capture = true;
  580. firstbutton_state = ButtonState.Pushed;
  581. firstbutton_pressed = true;
  582. Refresh ();
  583. }
  584. if (secondbutton_state != ButtonState.Inactive && second_arrow_area.Contains (e.X, e.Y)) {
  585. this.Capture = true;
  586. secondbutton_state = ButtonState.Pushed;
  587. secondbutton_pressed = true;
  588. Refresh ();
  589. }
  590. if (thumb_size > 0 && thumb_pos.Contains (e.X, e.Y)) {
  591. thumb_pressed = true;
  592. this.Capture = true;
  593. Refresh ();
  594. if (vert) {
  595. lastclick_pos_thumb = e.Y - thumb_pos.Y;
  596. lastclick_pos = e.Y;
  597. thumb_pixel_click_move_prev = thumb_pixel_click_move = e.Y;
  598. }
  599. else {
  600. lastclick_pos_thumb = e.X - thumb_pos.X;
  601. lastclick_pos = e.X;
  602. thumb_pixel_click_move_prev = thumb_pixel_click_move = e.X;
  603. }
  604. }
  605. else {
  606. if (thumb_size > 0 && thumb_area.Contains (e.X, e.Y)) {
  607. if (vert) {
  608. lastclick_pos_thumb = e.Y - thumb_pos.Y;
  609. lastclick_pos = e.Y;
  610. if (e.Y > thumb_pos.Y + thumb_pos.Height) {
  611. LargeIncrement ();
  612. thumb_moving = ThumbMoving.Forward;
  613. }
  614. else {
  615. LargeDecrement ();
  616. thumb_moving = ThumbMoving.Backwards;
  617. }
  618. }
  619. else {
  620. lastclick_pos_thumb = e.X - thumb_pos.X;
  621. lastclick_pos = e.X;
  622. if (e.X > thumb_pos.X + thumb_pos.Width) {
  623. thumb_moving = ThumbMoving.Forward;
  624. LargeIncrement ();
  625. }
  626. else {
  627. thumb_moving = ThumbMoving.Backwards;
  628. LargeDecrement ();
  629. }
  630. }
  631. SetHoldThumbAreaTimer ();
  632. timer.Enabled = true;
  633. Refresh ();
  634. }
  635. }
  636. /* If arrows are pressed, fire timer for auto-repeat */
  637. if ((((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
  638. || ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) &&
  639. timer.Enabled == false) {
  640. SetHoldButtonClickTimer ();
  641. timer.Enabled = true;
  642. }
  643. }
  644. private void OnMouseUpSB (object sender, MouseEventArgs e)
  645. {
  646. if (Enabled == false)
  647. return;
  648. timer.Enabled = false;
  649. if (thumb_moving != ThumbMoving.None) {
  650. thumb_moving = ThumbMoving.None;
  651. Refresh ();
  652. }
  653. this.Capture = false;
  654. if (firstbutton_pressed) {
  655. firstbutton_state = ButtonState.Normal;
  656. if (first_arrow_area.Contains (e.X, e.Y)) {
  657. SmallDecrement ();
  658. }
  659. firstbutton_pressed = false;
  660. return;
  661. } else if (secondbutton_pressed) {
  662. secondbutton_state = ButtonState.Normal;
  663. if (second_arrow_area.Contains (e.X, e.Y)) {
  664. SmallIncrement ();
  665. }
  666. secondbutton_pressed = false;
  667. return;
  668. } else if (thumb_pressed == true) {
  669. OnScroll (new ScrollEventArgs (ScrollEventType.ThumbPosition, position));
  670. OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
  671. thumb_pressed = false;
  672. Refresh ();
  673. }
  674. }
  675. private void OnKeyDownSB (Object o, KeyEventArgs key)
  676. {
  677. if (Enabled == false)
  678. return;
  679. switch (key.KeyCode){
  680. case Keys.Up:
  681. {
  682. SmallDecrement ();
  683. break;
  684. }
  685. case Keys.Down:
  686. {
  687. SmallIncrement ();
  688. break;
  689. }
  690. case Keys.PageUp:
  691. {
  692. LargeDecrement ();
  693. break;
  694. }
  695. case Keys.PageDown:
  696. {
  697. LargeIncrement ();
  698. break;
  699. }
  700. default:
  701. break;
  702. }
  703. }
  704. private void SmallIncrement ()
  705. {
  706. UpdatePos (position + small_change, true);
  707. Refresh ();
  708. OnScroll (new ScrollEventArgs (ScrollEventType.SmallIncrement, position));
  709. OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
  710. }
  711. private void SmallDecrement ()
  712. {
  713. UpdatePos (position - small_change, true);
  714. Refresh ();
  715. OnScroll (new ScrollEventArgs (ScrollEventType.SmallDecrement, position));
  716. OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
  717. }
  718. private void SetHoldButtonClickTimer ()
  719. {
  720. timer.Enabled = false;
  721. timer.Interval = 200;
  722. timer_type = TimerType.HoldButton;
  723. timer.Enabled = true;
  724. }
  725. private void SetRepeatButtonTimer ()
  726. {
  727. timer.Enabled = false;
  728. timer.Interval = 50;
  729. timer_type = TimerType.RepeatButton;
  730. timer.Enabled = true;
  731. }
  732. private void SetHoldThumbAreaTimer ()
  733. {
  734. timer.Enabled = false;
  735. timer.Interval = 200;
  736. timer_type = TimerType.HoldThumbArea;
  737. timer.Enabled = true;
  738. }
  739. private void SetRepeatThumbAreaTimer ()
  740. {
  741. timer.Enabled = false;
  742. timer.Interval = 50;
  743. timer_type = TimerType.RepeatThumbArea;
  744. timer.Enabled = true;
  745. }
  746. private void UpdatePos (int newPos, bool update_thumbpos)
  747. {
  748. int old = position;
  749. int pos;
  750. if (newPos < minimum)
  751. pos = minimum;
  752. else
  753. if (newPos > maximum + 1 - large_change)
  754. pos = maximum + 1 - large_change;
  755. else
  756. pos = newPos;
  757. // pos can't be less than minimum
  758. if (pos < minimum)
  759. pos = minimum;
  760. if (update_thumbpos) {
  761. if (vert)
  762. UpdateThumbPos (thumb_area.Y + (int)(((float)(pos - minimum)) * pixel_per_pos), false);
  763. else
  764. UpdateThumbPos (thumb_area.X + (int)(((float)(pos - minimum)) * pixel_per_pos), false);
  765. Value = pos;
  766. }
  767. else {
  768. position = pos; // Updates directly the value to avoid thumb pos update
  769. if (ValueChanged != null)
  770. ValueChanged (this, EventArgs.Empty);
  771. }
  772. if (pos != old) // Fire event
  773. OnScroll (new ScrollEventArgs (ScrollEventType.ThumbTrack, pos));
  774. }
  775. private void UpdateThumbPos (int pixel, bool update_value)
  776. {
  777. float new_pos = 0;
  778. if (vert) {
  779. if (pixel < thumb_area.Y)
  780. thumb_pos.Y = thumb_area.Y;
  781. else
  782. if (pixel > thumb_area.Y + thumb_area.Height - thumb_size)
  783. thumb_pos.Y = thumb_area.Y + thumb_area.Height - thumb_size;
  784. else
  785. thumb_pos.Y = pixel;
  786. thumb_pos.X = 0;
  787. thumb_pos.Width = ThemeEngine.Current.ScrollBarButtonSize;
  788. thumb_pos.Height = thumb_size;
  789. new_pos = (float) (thumb_pos.Y - thumb_area.Y);
  790. new_pos = new_pos / pixel_per_pos;
  791. } else {
  792. if (pixel < thumb_area.X)
  793. thumb_pos.X = thumb_area.X;
  794. else
  795. if (pixel > thumb_area.X + thumb_area.Width - thumb_size)
  796. thumb_pos.X = thumb_area.X + thumb_area.Width - thumb_size;
  797. else
  798. thumb_pos.X = pixel;
  799. thumb_pos.Y = 0;
  800. thumb_pos.Width = thumb_size;
  801. thumb_pos.Height = ThemeEngine.Current.ScrollBarButtonSize;
  802. new_pos = (float) (thumb_pos.X - thumb_area.X);
  803. new_pos = new_pos / pixel_per_pos;
  804. }
  805. if (update_value)
  806. UpdatePos ((int) new_pos + minimum, false);
  807. }
  808. #endregion //Private Methods
  809. }
  810. }