ButtonBase.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004 Novell, Inc.
  21. //
  22. // Authors:
  23. // Peter Bartok [email protected]
  24. //
  25. // NOT COMPLETE
  26. using System.ComponentModel;
  27. using System.Drawing;
  28. using System.Drawing.Text;
  29. namespace System.Windows.Forms {
  30. public abstract class ButtonBase : Control {
  31. #region Local Variables
  32. internal FlatStyle flat_style;
  33. internal int image_index;
  34. internal Image image;
  35. internal ImageList image_list;
  36. internal ContentAlignment image_alignment;
  37. internal ContentAlignment text_alignment;
  38. private bool is_default;
  39. internal bool is_pressed;
  40. internal bool redraw;
  41. internal StringFormat text_format;
  42. #endregion // Local Variables
  43. #region Private Properties and Methods
  44. internal ButtonState ButtonState {
  45. get {
  46. ButtonState ret = ButtonState.Normal;
  47. if (Enabled) {
  48. // Popup style is only followed as long as the mouse isn't "in" the control
  49. if (is_entered) {
  50. if (flat_style == FlatStyle.Flat) {
  51. ret |= ButtonState.Flat;
  52. }
  53. } else {
  54. if (flat_style == FlatStyle.Flat || flat_style == FlatStyle.Popup) {
  55. ret |= ButtonState.Flat;
  56. }
  57. }
  58. if (is_entered && is_pressed) {
  59. ret |= ButtonState.Pushed;
  60. }
  61. } else {
  62. ret |= ButtonState.Inactive;
  63. if ((flat_style == FlatStyle.Flat) || (flat_style == FlatStyle.Popup)) {
  64. ret |= ButtonState.Flat;
  65. }
  66. }
  67. return ret;
  68. }
  69. }
  70. [MonoTODO("Make the FillRectangle use a global brush instead of creating one every time")]
  71. internal void Redraw() {
  72. redraw = true;
  73. Refresh ();
  74. }
  75. // Derived classes should override Draw method and we dont want
  76. // to break the control signature, hence this approach.
  77. internal virtual void Draw (PaintEventArgs pevent) {
  78. if (redraw) {
  79. ThemeEngine.Current.DrawButtonBase(this.DeviceContext, pevent.ClipRectangle, this);
  80. redraw = false;
  81. }
  82. }
  83. private void RedrawEvent(object sender, System.EventArgs e) {
  84. Redraw();
  85. }
  86. #endregion // Private Properties and Methods
  87. #region Public Constructors
  88. protected ButtonBase() : base() {
  89. flat_style = FlatStyle.Standard;
  90. image_index = -1;
  91. image = null;
  92. image_list = null;
  93. image_alignment = ContentAlignment.MiddleCenter;
  94. text_alignment = ContentAlignment.MiddleCenter;
  95. ime_mode = ImeMode.Inherit;
  96. is_default = false;
  97. is_entered = false;
  98. is_pressed = false;
  99. has_focus = false;
  100. redraw = true;
  101. text_format = new StringFormat();
  102. text_format.Alignment = StringAlignment.Center;
  103. text_format.LineAlignment = StringAlignment.Center;
  104. text_format.HotkeyPrefix = HotkeyPrefix.Show;
  105. TextChanged+=new System.EventHandler(RedrawEvent);
  106. ForeColorChanged+=new EventHandler(RedrawEvent);
  107. BackColorChanged+=new System.EventHandler(RedrawEvent);
  108. FontChanged+=new EventHandler(RedrawEvent);
  109. SizeChanged+=new EventHandler(RedrawEvent);
  110. SetStyle (ControlStyles.ResizeRedraw, true);
  111. }
  112. #endregion // Public Constructors
  113. #region Public Instance Properties
  114. public FlatStyle FlatStyle {
  115. get {
  116. return flat_style;
  117. }
  118. set {
  119. flat_style = value;
  120. Redraw();
  121. }
  122. }
  123. public Image Image {
  124. get {
  125. return image;
  126. }
  127. set {
  128. image = value;
  129. Redraw();
  130. }
  131. }
  132. public ContentAlignment ImageAlign {
  133. get {
  134. return image_alignment;
  135. }
  136. set {
  137. image_alignment=value;
  138. Redraw();
  139. }
  140. }
  141. public int ImageIndex {
  142. get {
  143. if (image_list==null) {
  144. return -1;
  145. }
  146. return image_index;
  147. }
  148. set {
  149. image_index=value;
  150. Redraw();
  151. }
  152. }
  153. public ImageList ImageList {
  154. get {
  155. return image_list;
  156. }
  157. set {
  158. if (image_list != null) {
  159. image_list.Dispose();
  160. }
  161. image_list = value;
  162. if (value != null) {
  163. if (image != null) {
  164. image=null;
  165. }
  166. if (image_list.Images.Count >= image_index) {
  167. image_index=image_list.Images.Count-1;
  168. }
  169. }
  170. Redraw();
  171. }
  172. }
  173. public new ImeMode ImeMode {
  174. get {
  175. return ime_mode;
  176. }
  177. set {
  178. ime_mode = value;
  179. }
  180. }
  181. public virtual ContentAlignment TextAlign {
  182. get {
  183. return text_alignment;
  184. }
  185. set {
  186. if (text_alignment != value) {
  187. text_alignment = value;
  188. switch(text_alignment) {
  189. case ContentAlignment.TopLeft: {
  190. text_format.Alignment=StringAlignment.Near;
  191. text_format.LineAlignment=StringAlignment.Near;
  192. break;
  193. }
  194. case ContentAlignment.TopCenter: {
  195. text_format.Alignment=StringAlignment.Center;
  196. text_format.LineAlignment=StringAlignment.Near;
  197. break;
  198. }
  199. case ContentAlignment.TopRight: {
  200. text_format.Alignment=StringAlignment.Far;
  201. text_format.LineAlignment=StringAlignment.Near;
  202. break;
  203. }
  204. case ContentAlignment.MiddleLeft: {
  205. text_format.Alignment=StringAlignment.Near;
  206. text_format.LineAlignment=StringAlignment.Center;
  207. break;
  208. }
  209. case ContentAlignment.MiddleCenter: {
  210. text_format.Alignment=StringAlignment.Center;
  211. text_format.LineAlignment=StringAlignment.Center;
  212. break;
  213. }
  214. case ContentAlignment.MiddleRight: {
  215. text_format.Alignment=StringAlignment.Far;
  216. text_format.LineAlignment=StringAlignment.Center;
  217. break;
  218. }
  219. case ContentAlignment.BottomLeft: {
  220. text_format.Alignment=StringAlignment.Near;
  221. text_format.LineAlignment=StringAlignment.Far;
  222. break;
  223. }
  224. case ContentAlignment.BottomCenter: {
  225. text_format.Alignment=StringAlignment.Center;
  226. text_format.LineAlignment=StringAlignment.Far;
  227. break;
  228. }
  229. case ContentAlignment.BottomRight: {
  230. text_format.Alignment=StringAlignment.Far;
  231. text_format.LineAlignment=StringAlignment.Far;
  232. break;
  233. }
  234. }
  235. Redraw();
  236. }
  237. }
  238. }
  239. #endregion // Public Instance Properties
  240. #region Protected Instance Properties
  241. protected override CreateParams CreateParams {
  242. get {
  243. CreateParams cp;
  244. cp=base.CreateParams;
  245. cp.Style=(int)WindowStyles.WS_VISIBLE | (int)WindowStyles.WS_CHILD;
  246. SetStyle(ControlStyles.UserPaint, true);
  247. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  248. return cp;
  249. }
  250. }
  251. protected override ImeMode DefaultImeMode {
  252. get {
  253. return ImeMode.Inherit;
  254. }
  255. }
  256. protected override Size DefaultSize {
  257. get {
  258. return ThemeEngine.Current.ButtonBaseDefaultSize;
  259. }
  260. }
  261. protected bool IsDefault {
  262. get {
  263. return is_default;
  264. }
  265. set {
  266. if (is_default != value) {
  267. is_default = true;
  268. Redraw();
  269. }
  270. }
  271. }
  272. #endregion // Public Instance Properties
  273. #region Protected Instance Methods
  274. [MonoTODO("Finish setting properties of the AccessibleObject")]
  275. protected override AccessibleObject CreateAccessibilityInstance() {
  276. AccessibleObject ao;
  277. ao=base.CreateAccessibilityInstance();
  278. ao.description="Button";
  279. return ao;
  280. }
  281. protected override void Dispose(bool Disposing) {
  282. base.Dispose(Disposing);
  283. }
  284. protected override void OnEnabledChanged(EventArgs e) {
  285. Redraw();
  286. base.OnEnabledChanged(e);
  287. }
  288. protected override void OnGotFocus(EventArgs e) {
  289. has_focus=true;
  290. Redraw();
  291. base.OnGotFocus(e);
  292. }
  293. protected override void OnKeyDown(KeyEventArgs kevent) {
  294. if (is_enabled && (kevent.KeyData == Keys.Enter || kevent.KeyData == Keys.Space)) {
  295. OnClick(EventArgs.Empty);
  296. kevent.Handled=true;
  297. }
  298. base.OnKeyDown(kevent);
  299. }
  300. protected override void OnKeyUp(KeyEventArgs kevent) {
  301. base.OnKeyUp(kevent);
  302. }
  303. protected override void OnLostFocus(EventArgs e) {
  304. has_focus=false;
  305. Redraw();
  306. base.OnLostFocus(e);
  307. }
  308. protected override void OnMouseDown(MouseEventArgs mevent) {
  309. if (is_enabled && (mevent.Button == MouseButtons.Left)) {
  310. is_pressed = true;
  311. this.Capture = true;
  312. Redraw();
  313. }
  314. base.OnMouseDown(mevent);
  315. }
  316. protected override void OnMouseEnter(EventArgs e) {
  317. is_entered=true;
  318. if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
  319. Redraw();
  320. }
  321. base.OnMouseEnter(e);
  322. }
  323. protected override void OnMouseLeave(EventArgs e) {
  324. is_entered=false;
  325. if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
  326. Redraw();
  327. }
  328. base.OnMouseLeave(e);
  329. }
  330. protected override void OnMouseMove(MouseEventArgs mevent) {
  331. bool inside = false;
  332. bool redraw = false;
  333. if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
  334. inside = true;
  335. }
  336. // If the button was pressed and we leave, release the button press and vice versa
  337. if (this.Capture && (inside != is_pressed)) {
  338. is_pressed = inside;
  339. redraw = true;
  340. }
  341. if (is_entered != inside) {
  342. is_entered = inside;
  343. redraw = true;
  344. }
  345. if (redraw) {
  346. Redraw();
  347. }
  348. base.OnMouseMove(mevent);
  349. }
  350. protected override void OnMouseUp(MouseEventArgs mevent) {
  351. if (this.Capture && mevent.Button == MouseButtons.Left) {
  352. this.Capture = false;
  353. if (is_pressed) {
  354. is_pressed = false;
  355. Redraw();
  356. } else if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
  357. Redraw();
  358. }
  359. if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
  360. OnClick(EventArgs.Empty);
  361. }
  362. }
  363. base.OnMouseUp(mevent);
  364. }
  365. protected override void OnPaint(PaintEventArgs pevent) {
  366. Draw (pevent);
  367. pevent.Graphics.DrawImage(this.ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
  368. base.OnPaint (pevent);
  369. }
  370. protected override void OnParentChanged(EventArgs e) {
  371. base.OnParentChanged(e);
  372. }
  373. protected override void OnTextChanged(EventArgs e) {
  374. Redraw();
  375. base.OnTextChanged(e);
  376. }
  377. protected override void OnVisibleChanged(EventArgs e) {
  378. if (!Visible) {
  379. is_pressed = false;
  380. has_focus = false;
  381. is_entered = false;
  382. }
  383. base.OnVisibleChanged(e);
  384. }
  385. protected void ResetFlagsandPaint() {
  386. // Nothing to do; MS internal
  387. // Should we do Redraw (); ?
  388. }
  389. protected override void WndProc(ref Message m) {
  390. base.WndProc(ref m);
  391. }
  392. #endregion // Public Instance Properties
  393. }
  394. }