ViewConfigStrip.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. using PaintDotNet.SystemLayer;
  2. using System;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Windows.Forms;
  6. namespace PaintDotNet
  7. {
  8. internal sealed class ViewConfigStrip : ToolStripEx
  9. {
  10. private string windowText;
  11. private string percentageFormat;
  12. private ToolStripSeparator separator0;
  13. private ScaleFactor scaleFactor;
  14. private ToolStripButton zoomOutButton;
  15. private ToolStripButton zoomInButton;
  16. private ToolStripComboBox zoomComboBox;
  17. private ToolStripSeparator separator1;
  18. private ToolStripButton gridButton;
  19. private ToolStripLabel unitsLabel;
  20. private UnitsComboBoxStrip unitsComboBox;
  21. private int scaleFactorRecursionDepth = 0;
  22. private int suspendEvents = 0;
  23. private int ignoreZoomChanges = 0;
  24. public void SuspendEvents()
  25. {
  26. ++this.suspendEvents;
  27. }
  28. public void ResumeEvents()
  29. {
  30. --this.suspendEvents;
  31. }
  32. public void BeginZoomChanges()
  33. {
  34. ++this.ignoreZoomChanges;
  35. }
  36. public void EndZoomChanges()
  37. {
  38. --this.ignoreZoomChanges;
  39. }
  40. private ZoomBasis zoomBasis;
  41. public ZoomBasis ZoomBasis
  42. {
  43. get
  44. {
  45. return this.zoomBasis;
  46. }
  47. set
  48. {
  49. if (this.zoomBasis != value)
  50. {
  51. this.zoomBasis = value;
  52. OnZoomBasisChanged();
  53. }
  54. }
  55. }
  56. public bool DrawGrid
  57. {
  58. get
  59. {
  60. return true;// gridButton.Checked;
  61. }
  62. set
  63. {
  64. if (gridButton.Checked != value)
  65. {
  66. gridButton.Checked = value;
  67. this.OnDrawGridChanged();
  68. }
  69. }
  70. }
  71. public MeasurementUnit Units
  72. {
  73. get
  74. {
  75. return this.unitsComboBox.Units;
  76. }
  77. set
  78. {
  79. this.unitsComboBox.Units = value;
  80. }
  81. }
  82. public ScaleFactor ScaleFactor
  83. {
  84. get
  85. {
  86. return this.scaleFactor;
  87. }
  88. set
  89. {
  90. if (this.scaleFactor.Ratio != value.Ratio)
  91. {
  92. this.scaleFactor = value;
  93. ++this.scaleFactorRecursionDepth;
  94. // Prevent infinite recursion that was reported by one person.
  95. // This may cause the scale factor to settle on a less than
  96. // desirable value, but this is obviously more desirable than
  97. // a StackOverflow crash.
  98. if (this.scaleFactorRecursionDepth < 100)
  99. {
  100. OnZoomScaleChanged();
  101. }
  102. --this.scaleFactorRecursionDepth;
  103. }
  104. }
  105. }
  106. public ViewConfigStrip()
  107. {
  108. this.SuspendLayout();
  109. InitializeComponent();
  110. this.windowText = EnumLocalizer.EnumValueToLocalizedName(typeof(ZoomBasis), ZoomBasis.FitToWindow);
  111. this.percentageFormat = PdnResources.GetString("ZoomConfigWidget.Percentage.Format");
  112. double[] zoomValues = ScaleFactor.PresetValues;
  113. this.zoomComboBox.ComboBox.SuspendLayout();
  114. string percent100 = null; // ScaleFactor.PresetValues guarantees that 1.0, or "100%" is in the list, but the compiler can't be shown this so we must assign a value here
  115. for (int i = zoomValues.Length - 1; i >= 0; --i)
  116. {
  117. string zoomValueString = (zoomValues[i] * 100.0).ToString();
  118. string zoomItemString = string.Format(this.percentageFormat, zoomValueString);
  119. if (zoomValues[i] == 1.0)
  120. {
  121. percent100 = zoomItemString;
  122. }
  123. this.zoomComboBox.Items.Add(zoomItemString);
  124. }
  125. this.zoomComboBox.Items.Add(this.windowText);
  126. this.zoomComboBox.ComboBox.ResumeLayout(false);
  127. this.zoomComboBox.Size = new Size(UI.ScaleWidth(this.zoomComboBox.Width), zoomComboBox.Height);
  128. this.unitsLabel.Text = PdnResources.GetString("WorkspaceOptionsConfigWidget.UnitsLabel.Text");
  129. this.zoomComboBox.Text = percent100;
  130. this.ScaleFactor = ScaleFactor.OneToOne;
  131. this.zoomOutButton.Image = PdnResources.GetImageResource("Icons.MenuViewZoomOutIcon.png").Reference;
  132. this.zoomInButton.Image = PdnResources.GetImageResource("Icons.MenuViewZoomInIcon.png").Reference;
  133. this.gridButton.Image = PdnResources.GetImageResource("Icons.MenuViewGridIcon.png").Reference;
  134. this.zoomOutButton.ToolTipText = PdnResources.GetString("ZoomConfigWidget.ZoomOutButton.ToolTipText");
  135. this.zoomInButton.ToolTipText = PdnResources.GetString("ZoomConfigWidget.ZoomInButton.ToolTipText");
  136. this.gridButton.ToolTipText = PdnResources.GetString("WorkspaceOptionsConfigWidget.DrawGridToggleButton.ToolTipText");
  137. this.unitsComboBox.Size = new Size(UI.ScaleWidth(this.unitsComboBox.Width), unitsComboBox.Height);
  138. this.zoomBasis = ZoomBasis.ScaleFactor;
  139. ScaleFactor = ScaleFactor.OneToOne;
  140. this.ResumeLayout(false);
  141. }
  142. private void InitializeComponent()
  143. {
  144. this.separator0 = new ToolStripSeparator();
  145. this.zoomOutButton = new ToolStripButton();
  146. this.zoomComboBox = new ToolStripComboBox();
  147. this.zoomInButton = new ToolStripButton();
  148. this.separator1 = new ToolStripSeparator();
  149. this.gridButton = new ToolStripButton();
  150. this.unitsLabel = new ToolStripLabel();
  151. this.unitsComboBox = new UnitsComboBoxStrip();
  152. this.SuspendLayout();
  153. //
  154. // separator0
  155. //
  156. this.separator0.Name = "separator0";
  157. //
  158. // zoomComboBox
  159. //
  160. this.zoomComboBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ZoomComboBox_KeyPress);
  161. this.zoomComboBox.Validating += new System.ComponentModel.CancelEventHandler(this.ZoomComboBox_Validating);
  162. this.zoomComboBox.SelectedIndexChanged += new System.EventHandler(this.ZoomComboBox_SelectedIndexChanged);
  163. this.zoomComboBox.Size = new Size(75, this.zoomComboBox.Height);
  164. this.zoomComboBox.MaxDropDownItems = 99;
  165. //
  166. // unitsComboBox
  167. //
  168. this.unitsComboBox.UnitsChanged += new EventHandler(UnitsComboBox_UnitsChanged);
  169. this.unitsComboBox.LowercaseStrings = false;
  170. this.unitsComboBox.UnitsDisplayType = UnitsDisplayType.Plural;
  171. this.unitsComboBox.Units = MeasurementUnit.Pixel;
  172. this.unitsComboBox.Size = new Size(90, this.unitsComboBox.Height);
  173. //
  174. // ViewConfigStrip
  175. //
  176. this.Items.Add(this.separator0);
  177. this.Items.Add(this.zoomOutButton);
  178. this.Items.Add(this.zoomComboBox);
  179. this.Items.Add(this.zoomInButton);
  180. this.Items.Add(this.separator1);
  181. this.Items.Add(this.gridButton);
  182. this.Items.Add(this.unitsLabel);
  183. this.Items.Add(this.unitsComboBox);
  184. this.ResumeLayout(false);
  185. }
  186. private void UnitsComboBox_UnitsChanged(object sender, EventArgs e)
  187. {
  188. this.OnUnitsChanged();
  189. }
  190. private void SetZoomText()
  191. {
  192. if (this.ignoreZoomChanges == 0)
  193. {
  194. this.zoomComboBox.BackColor = SystemColors.Window;
  195. string newText = zoomComboBox.Text;
  196. switch (zoomBasis)
  197. {
  198. case ZoomBasis.FitToWindow:
  199. newText = this.windowText;
  200. break;
  201. case ZoomBasis.ScaleFactor:
  202. newText = scaleFactor.ToString();
  203. break;
  204. }
  205. if (zoomComboBox.Text != newText)
  206. {
  207. zoomComboBox.Text = newText;
  208. zoomComboBox.ComboBox.Update();
  209. }
  210. }
  211. }
  212. public event EventHandler DrawGridChanged;
  213. private void OnDrawGridChanged()
  214. {
  215. if (DrawGridChanged != null)
  216. {
  217. DrawGridChanged(this, EventArgs.Empty);
  218. }
  219. }
  220. public event EventHandler UnitsChanged;
  221. private void OnUnitsChanged()
  222. {
  223. if (UnitsChanged != null)
  224. {
  225. UnitsChanged(this, EventArgs.Empty);
  226. }
  227. }
  228. public event EventHandler ZoomScaleChanged;
  229. private void OnZoomScaleChanged()
  230. {
  231. if (zoomBasis == ZoomBasis.ScaleFactor)
  232. {
  233. SetZoomText();
  234. if (ZoomScaleChanged != null)
  235. {
  236. ZoomScaleChanged(this, EventArgs.Empty);
  237. }
  238. }
  239. }
  240. public event EventHandler ZoomIn;
  241. private void OnZoomIn()
  242. {
  243. if (ZoomIn != null)
  244. {
  245. ZoomIn(this, EventArgs.Empty);
  246. }
  247. }
  248. public event EventHandler ZoomOut;
  249. private void OnZoomOut()
  250. {
  251. if (ZoomOut != null)
  252. {
  253. ZoomOut(this, EventArgs.Empty);
  254. }
  255. }
  256. public void PerformZoomBasisChanged()
  257. {
  258. OnZoomBasisChanged();
  259. }
  260. public event EventHandler ZoomBasisChanged;
  261. private void OnZoomBasisChanged()
  262. {
  263. SetZoomText();
  264. if (ZoomBasisChanged != null)
  265. {
  266. ZoomBasisChanged(this, EventArgs.Empty);
  267. }
  268. }
  269. public void PerformZoomScaleChanged()
  270. {
  271. OnZoomScaleChanged();
  272. }
  273. private void ZoomComboBox_Validating(object sender, System.ComponentModel.CancelEventArgs e)
  274. {
  275. try
  276. {
  277. int val = 1;
  278. e.Cancel = false;
  279. if (zoomComboBox.Text == this.windowText)
  280. {
  281. ZoomBasis = ZoomBasis.FitToWindow;
  282. }
  283. else
  284. {
  285. try
  286. {
  287. string text = zoomComboBox.Text;
  288. if (text.Length == 0)
  289. {
  290. e.Cancel = true;
  291. }
  292. else
  293. {
  294. if (text[text.Length - 1] == '%')
  295. {
  296. text = text.Substring(0, text.Length - 1);
  297. }
  298. else if (text[0] == '%')
  299. {
  300. text = text.Substring(1);
  301. }
  302. val = (int)Math.Round(double.Parse(text));
  303. ZoomBasis = ZoomBasis.ScaleFactor;
  304. }
  305. }
  306. catch (FormatException)
  307. {
  308. e.Cancel = true;
  309. }
  310. catch (OverflowException)
  311. {
  312. e.Cancel = true;
  313. }
  314. if (e.Cancel)
  315. {
  316. this.zoomComboBox.BackColor = Color.Red;
  317. this.zoomComboBox.ToolTipText = PdnResources.GetString("ZoomConfigWidget.Error.InvalidNumber");
  318. }
  319. else
  320. {
  321. if (val < 1)
  322. {
  323. e.Cancel = true;
  324. this.zoomComboBox.BackColor = Color.Red;
  325. this.zoomComboBox.ToolTipText = PdnResources.GetString("ZoomConfigWidget.Error.TooSmall");
  326. }
  327. else if (val > 3200)
  328. {
  329. e.Cancel = true;
  330. this.zoomComboBox.BackColor = Color.Red;
  331. this.zoomComboBox.ToolTipText = PdnResources.GetString("ZoomConfigWidget.Error.TooLarge");
  332. }
  333. else
  334. {
  335. // Clear the error
  336. e.Cancel = false;
  337. this.zoomComboBox.ToolTipText = string.Empty;
  338. this.zoomComboBox.BackColor = SystemColors.Window;
  339. ScaleFactor = new ScaleFactor(val, 100);
  340. SuspendEvents();
  341. ZoomBasis = ZoomBasis.ScaleFactor;
  342. ResumeEvents();
  343. }
  344. }
  345. }
  346. }
  347. catch (FormatException)
  348. {
  349. }
  350. }
  351. private void ZoomComboBox_SelectedIndexChanged(object sender, EventArgs e)
  352. {
  353. if (this.suspendEvents == 0)
  354. {
  355. ZoomComboBox_Validating(sender, new CancelEventArgs(false));
  356. }
  357. }
  358. private void ZoomComboBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
  359. {
  360. if (e.KeyChar == '\n' || e.KeyChar == '\r')
  361. {
  362. ZoomComboBox_Validating(sender, new CancelEventArgs(false));
  363. zoomComboBox.Select(0, zoomComboBox.Text.Length);
  364. }
  365. }
  366. protected override void OnItemClicked(ToolStripItemClickedEventArgs e)
  367. {
  368. if (e.ClickedItem == this.zoomInButton)
  369. {
  370. Tracing.LogFeature("ViewConfigStrip(ZoomIn)");
  371. OnZoomIn();
  372. }
  373. else if (e.ClickedItem == this.zoomOutButton)
  374. {
  375. Tracing.LogFeature("ViewConfigStrip(ZoomOut)");
  376. OnZoomOut();
  377. }
  378. else if (e.ClickedItem == this.gridButton)
  379. {
  380. Tracing.LogFeature("ViewConfigStrip(Grid)");
  381. this.gridButton.Checked = !this.gridButton.Checked;
  382. this.OnDrawGridChanged();
  383. }
  384. base.OnItemClicked(e);
  385. }
  386. }
  387. }