OptionUI.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. from typing import Union, Sequence
  2. from PyQt5 import QtWidgets
  3. from flatcamGUI.GUIElements import RadioSet, FCCheckBox, FCButton, FCComboBox, FCEntry, FCSpinner, FCColorEntry, \
  4. FCSliderWithSpinner, FCDoubleSpinner
  5. import gettext
  6. import FlatCAMTranslation as fcTranslate
  7. import builtins
  8. fcTranslate.apply_language('strings')
  9. if '_' not in builtins.__dict__:
  10. _ = gettext.gettext
  11. class OptionUI:
  12. def __init__(self, option: str):
  13. self.option = option
  14. def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
  15. """
  16. Adds the necessary widget to the grid, starting at the supplied row.
  17. Returns the number of rows used (normally 1)
  18. """
  19. raise NotImplementedError()
  20. def get_field(self):
  21. raise NotImplementedError()
  22. class BasicOptionUI(OptionUI):
  23. """Abstract OptionUI that has a label on the left then some other widget on the right"""
  24. def __init__(self, option: str, label_text: str, label_tooltip: str):
  25. super().__init__(option=option)
  26. self.label_text = label_text
  27. self.label_tooltip = label_tooltip
  28. self.label_widget = self.build_label_widget()
  29. self.entry_widget = self.build_entry_widget()
  30. def build_label_widget(self) -> QtWidgets.QLabel:
  31. label_widget = QtWidgets.QLabel('%s:' % _(self.label_text))
  32. if self.label_tooltip is not None:
  33. label_widget.setToolTip(_(self.label_tooltip))
  34. return label_widget
  35. def build_entry_widget(self) -> QtWidgets.QWidget:
  36. raise NotImplementedError()
  37. def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
  38. grid.addWidget(self.label_widget, row, 0)
  39. grid.addWidget(self.entry_widget, row, 1)
  40. return 1
  41. def get_field(self):
  42. return self.entry_widget
  43. class RadioSetOptionUI(BasicOptionUI):
  44. def __init__(self, option: str, label_text: str, label_tooltip: str, choices: list, orientation='horizontal'):
  45. self.choices = choices
  46. self.orientation = orientation
  47. super().__init__(option=option, label_text=label_text, label_tooltip=label_tooltip)
  48. def build_entry_widget(self) -> QtWidgets.QWidget:
  49. return RadioSet(choices=self.choices, orientation=self.orientation)
  50. class CheckboxOptionUI(OptionUI):
  51. def __init__(self, option: str, label_text: str, label_tooltip: str):
  52. super().__init__(option=option)
  53. self.label_text = label_text
  54. self.label_tooltip = label_tooltip
  55. self.checkbox_widget = self.build_checkbox_widget()
  56. def build_checkbox_widget(self):
  57. checkbox = FCCheckBox('%s' % _(self.label_text))
  58. checkbox.setToolTip(_(self.label_tooltip))
  59. return checkbox
  60. def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
  61. grid.addWidget(self.checkbox_widget, row, 0, 1, 3)
  62. return 1
  63. def get_field(self):
  64. return self.checkbox_widget
  65. class ComboboxOptionUI(BasicOptionUI):
  66. def __init__(self, option: str, label_text: str, label_tooltip: str, choices: Sequence):
  67. self.choices = choices
  68. super().__init__(option=option, label_text=label_text, label_tooltip=label_tooltip)
  69. def build_entry_widget(self):
  70. combo = FCComboBox()
  71. for choice in self.choices:
  72. # don't translate the QCombo items as they are used in QSettings and identified by name
  73. combo.addItem(choice)
  74. return combo
  75. class ColorOptionUI(BasicOptionUI):
  76. def build_entry_widget(self) -> QtWidgets.QWidget:
  77. entry = FCColorEntry()
  78. return entry
  79. class SliderWithSpinnerOptionUI(BasicOptionUI):
  80. def __init__(self, option: str, label_text: str, label_tooltip: str, min_value=0, max_value=100, step=1):
  81. self.min_value = min_value
  82. self.max_value = max_value
  83. self.step = step
  84. super().__init__(option=option, label_text=label_text, label_tooltip=label_tooltip)
  85. def build_entry_widget(self) -> QtWidgets.QWidget:
  86. entry = FCSliderWithSpinner(min=self.min_value, max=self.max_value, step=self.step)
  87. return entry
  88. class SpinnerOptionUI(BasicOptionUI):
  89. def __init__(self, option: str, label_text: str, label_tooltip: str, min_value: int, max_value: int, step: int = 1):
  90. self.min_value = min_value
  91. self.max_value = max_value
  92. self.step = step
  93. super().__init__(option=option, label_text=label_text, label_tooltip=label_tooltip)
  94. def build_entry_widget(self) -> QtWidgets.QWidget:
  95. entry = FCSpinner()
  96. entry.set_range(self.min_value, self.max_value)
  97. entry.set_step(self.step)
  98. entry.setWrapping(True)
  99. return entry
  100. class DoubleSpinnerOptionUI(BasicOptionUI):
  101. def __init__(self, option: str, label_text: str, label_tooltip: str, step: float, decimals: int, min_value=None, max_value=None):
  102. self.min_value = min_value
  103. self.max_value = max_value
  104. self.step = step
  105. self.decimals = decimals
  106. super().__init__(option=option, label_text=label_text, label_tooltip=label_tooltip)
  107. def build_entry_widget(self) -> QtWidgets.QWidget:
  108. entry = FCDoubleSpinner()
  109. entry.set_precision(self.decimals)
  110. entry.setSingleStep(self.step)
  111. if self.min_value is None:
  112. self.min_value = entry.minimum()
  113. else:
  114. entry.setMinimum(self.min_value)
  115. if self.max_value is None:
  116. self.max_value = entry.maximum()
  117. else:
  118. entry.setMaximum(self.max_value)
  119. return entry
  120. class HeadingOptionUI(OptionUI):
  121. def __init__(self, label_text: str, label_tooltip: Union[str, None]):
  122. super().__init__(option="__heading")
  123. self.label_text = label_text
  124. self.label_tooltip = label_tooltip
  125. def build_heading_widget(self):
  126. heading = QtWidgets.QLabel('<b>%s</b>' % _(self.label_text))
  127. heading.setToolTip(_(self.label_tooltip))
  128. return heading
  129. def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
  130. grid.addWidget(self.build_heading_widget(), row, 0, 1, 2)
  131. return 1
  132. def get_field(self):
  133. return None
  134. class SeparatorOptionUI(OptionUI):
  135. def __init__(self):
  136. super().__init__(option="__separator")
  137. def build_separator_widget(self):
  138. separator = QtWidgets.QFrame()
  139. separator.setFrameShape(QtWidgets.QFrame.HLine)
  140. separator.setFrameShadow(QtWidgets.QFrame.Sunken)
  141. return separator
  142. def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
  143. grid.addWidget(self.build_separator_widget(), row, 0, 1, 2)
  144. return 1
  145. def get_field(self):
  146. return None
  147. class FullWidthButtonOptionUI(OptionUI):
  148. def __init__(self, option: str, label_text: str, label_tooltip: str):
  149. super().__init__(option=option)
  150. self.label_text = label_text
  151. self.label_tooltip = label_tooltip
  152. self.button_widget = self.build_button_widget()
  153. def build_button_widget(self):
  154. button = FCButton(_(self.label_text))
  155. button.setToolTip(_(self.label_tooltip))
  156. return button
  157. def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
  158. grid.addWidget(self.button_widget, row, 0, 1, 3)
  159. return 1
  160. def get_field(self):
  161. return self.button_widget