ButtonBase.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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 ImeMode ime_mode;
  39. private bool is_default;
  40. internal bool has_focus;
  41. internal bool is_pressed;
  42. internal bool is_entered;
  43. internal bool redraw;
  44. internal StringFormat text_format;
  45. #endregion // Local Variables
  46. #region Private Properties and Methods
  47. internal ButtonState ButtonState {
  48. get {
  49. ButtonState ret = ButtonState.Normal;
  50. if (Enabled) {
  51. // Popup style is only followed as long as the mouse isn't "in" the control
  52. if (is_entered) {
  53. if (flat_style == FlatStyle.Flat) {
  54. ret |= ButtonState.Flat;
  55. }
  56. } else {
  57. if (flat_style == FlatStyle.Flat || flat_style == FlatStyle.Popup) {
  58. ret |= ButtonState.Flat;
  59. }
  60. }
  61. if (is_entered && is_pressed) {
  62. ret |= ButtonState.Pushed;
  63. }
  64. } else {
  65. ret |= ButtonState.Inactive;
  66. if ((flat_style == FlatStyle.Flat) || (flat_style == FlatStyle.Popup)) {
  67. ret |= ButtonState.Flat;
  68. }
  69. }
  70. return ret;
  71. }
  72. }
  73. [MonoTODO("Make the FillRectangle use a global brush instead of creating one every time")]
  74. internal void Redraw() {
  75. redraw = true;
  76. Refresh ();
  77. }
  78. // Derived classes should override Draw method and we dont want
  79. // to break the control signature, hence this approach.
  80. internal virtual void Draw (PaintEventArgs pevent) {
  81. if (redraw) {
  82. ThemeEngine.Current.DrawButtonBase(this.DeviceContext, pevent.ClipRectangle, this);
  83. redraw = false;
  84. }
  85. }
  86. private void RedrawEvent(object sender, System.EventArgs e) {
  87. Redraw();
  88. }
  89. #endregion // Private Properties and Methods
  90. #region Public Constructors
  91. protected ButtonBase() : base() {
  92. flat_style = FlatStyle.Standard;
  93. image_index = -1;
  94. image = null;
  95. image_list = null;
  96. image_alignment = ContentAlignment.MiddleCenter;
  97. text_alignment = ContentAlignment.MiddleCenter;
  98. ime_mode = ImeMode.Inherit;
  99. is_default = false;
  100. is_entered = false;
  101. is_pressed = false;
  102. has_focus = false;
  103. redraw = true;
  104. text_format = new StringFormat();
  105. text_format.Alignment = StringAlignment.Center;
  106. text_format.LineAlignment = StringAlignment.Center;
  107. text_format.HotkeyPrefix = HotkeyPrefix.Show;
  108. TextChanged+=new System.EventHandler(RedrawEvent);
  109. ForeColorChanged+=new EventHandler(RedrawEvent);
  110. BackColorChanged+=new System.EventHandler(RedrawEvent);
  111. FontChanged+=new EventHandler(RedrawEvent);
  112. SizeChanged+=new EventHandler(RedrawEvent);
  113. SetStyle (ControlStyles.ResizeRedraw, true);
  114. }
  115. #endregion // Public Constructors
  116. #region Public Instance Properties
  117. public FlatStyle FlatStyle {
  118. get {
  119. return flat_style;
  120. }
  121. set {
  122. flat_style = value;
  123. Redraw();
  124. }
  125. }
  126. public Image Image {
  127. get {
  128. return image;
  129. }
  130. set {
  131. image = value;
  132. Redraw();
  133. }
  134. }
  135. public ContentAlignment ImageAlign {
  136. get {
  137. return image_alignment;
  138. }
  139. set {
  140. image_alignment=value;
  141. Redraw();
  142. }
  143. }
  144. public int ImageIndex {
  145. get {
  146. if (image_list==null) {
  147. return -1;
  148. }
  149. return image_index;
  150. }
  151. set {
  152. image_index=value;
  153. Redraw();
  154. }
  155. }
  156. public ImageList ImageList {
  157. get {
  158. return image_list;
  159. }
  160. set {
  161. if (image_list != null) {
  162. image_list.Dispose();
  163. }
  164. image_list = value;
  165. if (value != null) {
  166. if (image != null) {
  167. image=null;
  168. }
  169. if (image_list.Images.Count >= image_index) {
  170. image_index=image_list.Images.Count-1;
  171. }
  172. }
  173. Redraw();
  174. }
  175. }
  176. public ImeMode ImeMode {
  177. get {
  178. return ime_mode;
  179. }
  180. set {
  181. ime_mode = value;
  182. }
  183. }
  184. public virtual ContentAlignment TextAlign {
  185. get {
  186. return text_alignment;
  187. }
  188. set {
  189. if (text_alignment != value) {
  190. text_alignment = value;
  191. switch(text_alignment) {
  192. case ContentAlignment.TopLeft: {
  193. text_format.Alignment=StringAlignment.Near;
  194. text_format.LineAlignment=StringAlignment.Near;
  195. break;
  196. }
  197. case ContentAlignment.TopCenter: {
  198. text_format.Alignment=StringAlignment.Center;
  199. text_format.LineAlignment=StringAlignment.Near;
  200. break;
  201. }
  202. case ContentAlignment.TopRight: {
  203. text_format.Alignment=StringAlignment.Far;
  204. text_format.LineAlignment=StringAlignment.Near;
  205. break;
  206. }
  207. case ContentAlignment.MiddleLeft: {
  208. text_format.Alignment=StringAlignment.Near;
  209. text_format.LineAlignment=StringAlignment.Center;
  210. break;
  211. }
  212. case ContentAlignment.MiddleCenter: {
  213. text_format.Alignment=StringAlignment.Center;
  214. text_format.LineAlignment=StringAlignment.Center;
  215. break;
  216. }
  217. case ContentAlignment.MiddleRight: {
  218. text_format.Alignment=StringAlignment.Far;
  219. text_format.LineAlignment=StringAlignment.Center;
  220. break;
  221. }
  222. case ContentAlignment.BottomLeft: {
  223. text_format.Alignment=StringAlignment.Near;
  224. text_format.LineAlignment=StringAlignment.Far;
  225. break;
  226. }
  227. case ContentAlignment.BottomCenter: {
  228. text_format.Alignment=StringAlignment.Center;
  229. text_format.LineAlignment=StringAlignment.Far;
  230. break;
  231. }
  232. case ContentAlignment.BottomRight: {
  233. text_format.Alignment=StringAlignment.Far;
  234. text_format.LineAlignment=StringAlignment.Far;
  235. break;
  236. }
  237. }
  238. Redraw();
  239. }
  240. }
  241. }
  242. #endregion // Public Instance Properties
  243. #region Protected Instance Properties
  244. protected override CreateParams CreateParams {
  245. get {
  246. CreateParams cp;
  247. cp=base.CreateParams;
  248. cp.Style=(int)WindowStyles.WS_VISIBLE | (int)WindowStyles.WS_CHILD;
  249. SetStyle(ControlStyles.UserPaint, true);
  250. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  251. return cp;
  252. }
  253. }
  254. protected override ImeMode DefaultImeMode {
  255. get {
  256. return ImeMode.Inherit;
  257. }
  258. }
  259. protected override Size DefaultSize {
  260. get {
  261. return ThemeEngine.Current.ButtonBaseDefaultSize;
  262. }
  263. }
  264. protected bool IsDefault {
  265. get {
  266. return is_default;
  267. }
  268. set {
  269. if (is_default != value) {
  270. is_default = true;
  271. Redraw();
  272. }
  273. }
  274. }
  275. #endregion // Public Instance Properties
  276. #region Protected Instance Methods
  277. [MonoTODO("Finish setting properties of the AccessibleObject")]
  278. protected override AccessibleObject CreateAccessibilityInstance() {
  279. AccessibleObject ao;
  280. ao=base.CreateAccessibilityInstance();
  281. ao.description="Button";
  282. return ao;
  283. }
  284. protected override void Dispose(bool Disposing) {
  285. base.Dispose(Disposing);
  286. }
  287. protected override void OnEnabledChanged(EventArgs e) {
  288. Redraw();
  289. base.OnEnabledChanged(e);
  290. }
  291. protected override void OnGotFocus(EventArgs e) {
  292. has_focus=true;
  293. Redraw();
  294. base.OnGotFocus(e);
  295. }
  296. protected override void OnKeyDown(KeyEventArgs kevent) {
  297. if (is_enabled && (kevent.KeyData == Keys.Enter || kevent.KeyData == Keys.Space)) {
  298. OnClick(EventArgs.Empty);
  299. kevent.Handled=true;
  300. }
  301. base.OnKeyDown(kevent);
  302. }
  303. protected override void OnKeyUp(KeyEventArgs kevent) {
  304. base.OnKeyUp(kevent);
  305. }
  306. protected override void OnLostFocus(EventArgs e) {
  307. has_focus=false;
  308. Redraw();
  309. base.OnLostFocus(e);
  310. }
  311. protected override void OnMouseDown(MouseEventArgs mevent) {
  312. if (is_enabled && (mevent.Button == MouseButtons.Left)) {
  313. is_pressed = true;
  314. this.Capture = true;
  315. Redraw();
  316. }
  317. base.OnMouseDown(mevent);
  318. }
  319. protected override void OnMouseEnter(EventArgs e) {
  320. is_entered=true;
  321. if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
  322. Redraw();
  323. }
  324. base.OnMouseEnter(e);
  325. }
  326. protected override void OnMouseLeave(EventArgs e) {
  327. is_entered=false;
  328. if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
  329. Redraw();
  330. }
  331. base.OnMouseLeave(e);
  332. }
  333. protected override void OnMouseMove(MouseEventArgs mevent) {
  334. bool inside = false;
  335. bool redraw = false;
  336. if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
  337. inside = true;
  338. }
  339. // If the button was pressed and we leave, release the button press and vice versa
  340. if (this.Capture && (inside != is_pressed)) {
  341. is_pressed = inside;
  342. redraw = true;
  343. }
  344. if (is_entered != inside) {
  345. is_entered = inside;
  346. redraw = true;
  347. }
  348. if (redraw) {
  349. Redraw();
  350. }
  351. base.OnMouseMove(mevent);
  352. }
  353. protected override void OnMouseUp(MouseEventArgs mevent) {
  354. if (this.Capture && mevent.Button == MouseButtons.Left) {
  355. this.Capture = false;
  356. if (is_pressed) {
  357. is_pressed = false;
  358. Redraw();
  359. } else if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
  360. Redraw();
  361. }
  362. if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
  363. OnClick(EventArgs.Empty);
  364. }
  365. }
  366. base.OnMouseUp(mevent);
  367. }
  368. protected override void OnPaint(PaintEventArgs pevent) {
  369. Draw (pevent);
  370. pevent.Graphics.DrawImage(this.ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
  371. base.OnPaint (pevent);
  372. }
  373. protected override void OnParentChanged(EventArgs e) {
  374. base.OnParentChanged(e);
  375. }
  376. protected override void OnTextChanged(EventArgs e) {
  377. Redraw();
  378. base.OnTextChanged(e);
  379. }
  380. protected override void OnVisibleChanged(EventArgs e) {
  381. if (!Visible) {
  382. is_pressed = false;
  383. has_focus = false;
  384. is_entered = false;
  385. }
  386. base.OnVisibleChanged(e);
  387. }
  388. protected void ResetFlagsandPaint() {
  389. // Nothing to do; MS internal
  390. // Should we do Redraw (); ?
  391. }
  392. protected override void WndProc(ref Message m) {
  393. base.WndProc(ref m);
  394. }
  395. #endregion // Public Instance Properties
  396. }
  397. }