StatusBar.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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. // Jackson Harper ([email protected])
  24. using System.Collections;
  25. using System.Drawing;
  26. using System.Drawing.Text;
  27. using System.Drawing.Imaging;
  28. namespace System.Windows.Forms {
  29. public class StatusBar : Control {
  30. private StatusBarPanelCollection panels;
  31. private bool show_panels = false;
  32. private bool sizing_grip = true;
  33. private Rectangle paint_area = new Rectangle ();
  34. public StatusBar ()
  35. {
  36. Dock = DockStyle.Bottom;
  37. Anchor = AnchorStyles.Top | AnchorStyles.Left;
  38. }
  39. public bool ShowPanels {
  40. get { return show_panels; }
  41. set {
  42. bool refresh = (show_panels != value);
  43. show_panels = value;
  44. if (refresh)
  45. Refresh ();
  46. }
  47. }
  48. public bool SizingGrip {
  49. get { return sizing_grip; }
  50. set {
  51. bool refresh = (sizing_grip != value);
  52. sizing_grip = value;
  53. if (refresh)
  54. Refresh ();
  55. }
  56. }
  57. public StatusBarPanelCollection Panels {
  58. get {
  59. if (panels == null)
  60. panels = new StatusBarPanelCollection (this);
  61. return panels;
  62. }
  63. }
  64. protected override Size DefaultSize {
  65. get { return new Size (100, 22); }
  66. }
  67. protected override void WndProc(ref Message m)
  68. {
  69. switch ((Msg) m.Msg) {
  70. case Msg.WM_PAINT: {
  71. Rectangle rect;
  72. PaintEventArgs paint_event;
  73. paint_event = XplatUI.PaintEventStart (Handle);
  74. Paint (paint_event);
  75. XplatUI.PaintEventEnd (Handle);
  76. return;
  77. }
  78. }
  79. base.WndProc (ref m);
  80. }
  81. protected override void OnResize (EventArgs e)
  82. {
  83. base.OnResize (e);
  84. if (Width <= 0 || Height <= 0)
  85. return;
  86. UpdateArea ();
  87. CreateBuffers (Width, Height);
  88. CalcPanelSizes ();
  89. Draw ();
  90. }
  91. protected override void OnHandleCreated (EventArgs e)
  92. {
  93. base.OnHandleCreated (e);
  94. UpdateArea ();
  95. CreateBuffers (Width, Height);
  96. Draw();
  97. }
  98. private void Paint (PaintEventArgs pevent)
  99. {
  100. if (Width <= 0 || Height <= 0 || Visible == false)
  101. return;
  102. UpdateArea ();
  103. CalcPanelSizes ();
  104. Draw();
  105. pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
  106. }
  107. private void CalcPanelSizes ()
  108. {
  109. if (panels == null || !show_panels)
  110. return;
  111. int gap = ThemeEngine.Current.StatusBarHorzGapWidth;
  112. int taken = 0;
  113. ArrayList springs = null;
  114. for (int i = 0; i < panels.Count; i++) {
  115. StatusBarPanel p = panels [i];
  116. if (p.AutoSize == StatusBarPanelAutoSize.None) {
  117. taken += p.Width;
  118. taken += gap;
  119. continue;
  120. }
  121. if (p.AutoSize == StatusBarPanelAutoSize.Contents) {
  122. if (DeviceContext == null)
  123. CreateBuffers (Width, Height);
  124. int len = (int) (DeviceContext.MeasureString (p.Text, Font).Width + 0.5F);
  125. p.Width = (int) (len * 1.5F);
  126. taken += p.Width;
  127. taken += gap;
  128. continue;
  129. }
  130. if (p.AutoSize == StatusBarPanelAutoSize.Spring) {
  131. if (springs == null)
  132. springs = new ArrayList ();
  133. springs.Add (p);
  134. taken += gap;
  135. continue;
  136. }
  137. }
  138. if (springs == null)
  139. return;
  140. int spring_total = springs.Count;
  141. int total_width = Width - taken - ThemeEngine.Current.SizeGripWidth;
  142. for (int i = 0; i < spring_total; i++) {
  143. StatusBarPanel p = (StatusBarPanel) springs [i];
  144. p.Width = total_width / spring_total;
  145. }
  146. }
  147. private void UpdateArea ()
  148. {
  149. paint_area.X = paint_area.Y = 0;
  150. paint_area.Width = Width;
  151. paint_area.Height = Height;
  152. }
  153. private void Draw ()
  154. {
  155. ThemeEngine.Current.DrawStatusBar (DeviceContext, paint_area, this);
  156. }
  157. public class StatusBarPanelCollection : IList, ICollection, IEnumerable {
  158. private StatusBar owner;
  159. private ArrayList panels;
  160. public StatusBarPanelCollection (StatusBar owner)
  161. {
  162. this.owner = owner;
  163. }
  164. public virtual int Count {
  165. get {
  166. if (panels == null)
  167. return 0;
  168. return panels.Count;
  169. }
  170. }
  171. public virtual bool IsReadOnly {
  172. get { return false; }
  173. }
  174. bool IList.IsFixedSize {
  175. get { return false; }
  176. }
  177. bool ICollection.IsSynchronized {
  178. get { return panels.IsSynchronized; }
  179. }
  180. object ICollection.SyncRoot {
  181. get { return panels.SyncRoot; }
  182. }
  183. public virtual StatusBarPanel this [int index] {
  184. get {
  185. if (index < 0 || index >= Count)
  186. throw new ArgumentOutOfRangeException ("index");
  187. return (StatusBarPanel) panels [index];
  188. }
  189. set {
  190. if (value == null)
  191. throw new ArgumentNullException ("index");
  192. if (index < 0 || index >= Count)
  193. throw new ArgumentOutOfRangeException ("index");
  194. panels [index] = value;
  195. }
  196. }
  197. public virtual int Add (StatusBarPanel p)
  198. {
  199. return AddInternal (p, true);
  200. }
  201. public virtual StatusBarPanel Add (string text)
  202. {
  203. StatusBarPanel res = new StatusBarPanel ();
  204. res.Text = text;
  205. Add (res);
  206. return res;
  207. }
  208. private int AddInternal (StatusBarPanel p, bool refresh)
  209. {
  210. if (p == null)
  211. throw new ArgumentNullException ("value");
  212. if (panels == null)
  213. panels = new ArrayList ();
  214. int res = panels.Add (p);
  215. p.SetParent (owner);
  216. if (refresh) {
  217. owner.CalcPanelSizes ();
  218. owner.Refresh ();
  219. }
  220. return res;
  221. }
  222. public virtual void AddRange (StatusBarPanel [] range)
  223. {
  224. if (range == null)
  225. throw new ArgumentNullException ("panels");
  226. if (range.Length == 0)
  227. return;
  228. if (panels == null)
  229. panels = new ArrayList (range.Length);
  230. for (int i = 0; i < range.Length; i++)
  231. AddInternal (range [i], false);
  232. owner.Refresh ();
  233. }
  234. public virtual void Insert (int index, StatusBarPanel value)
  235. {
  236. if (value == null)
  237. throw new ArgumentNullException ("value");
  238. if (index > Count)
  239. throw new ArgumentOutOfRangeException ("index");
  240. // TODO: InvalidArgumentException for bad AutoSize values
  241. // although it seems impossible to set it to a bad value
  242. value.SetParent (owner);
  243. panels [index] = value;
  244. owner.Refresh ();
  245. }
  246. public virtual void Clear ()
  247. {
  248. panels.Clear ();
  249. owner.Refresh ();
  250. }
  251. public virtual bool Contains (StatusBarPanel panel)
  252. {
  253. return panels.Contains (panel);
  254. }
  255. public virtual IEnumerator GetEnumerator ()
  256. {
  257. return panels.GetEnumerator ();
  258. }
  259. public virtual int IndexOf (StatusBarPanel panel)
  260. {
  261. return panels.IndexOf (panel);
  262. }
  263. public virtual void Remove (StatusBarPanel panel)
  264. {
  265. panels.Remove (panel);
  266. }
  267. public virtual void RemoveAt (int index)
  268. {
  269. panels.RemoveAt (index);
  270. }
  271. void ICollection.CopyTo (Array dest, int index)
  272. {
  273. panels.CopyTo (dest, index);
  274. }
  275. object IList.this [int index] {
  276. get { return panels [index]; }
  277. set { panels [index] = value; }
  278. }
  279. int IList.Add (object value)
  280. {
  281. return panels.Add (value);
  282. }
  283. bool IList.Contains (object panel)
  284. {
  285. return panels.Contains (panel);
  286. }
  287. int IList.IndexOf (object panel)
  288. {
  289. return panels.IndexOf (panel);
  290. }
  291. void IList.Insert (int index, object value)
  292. {
  293. panels.Insert (index, value);
  294. }
  295. void IList.Remove (object value)
  296. {
  297. panels.Remove (value);
  298. }
  299. }
  300. }
  301. }