GUIElements.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. ############################################################
  2. # FlatCAM: 2D Post-processing for Manufacturing #
  3. # http://caram.cl/software/flatcam #
  4. # Author: Juan Pablo Caram (c) #
  5. # Date: 2/5/2014 #
  6. # MIT Licence #
  7. ############################################################
  8. import re
  9. from copy import copy
  10. from gi.repository import Gtk
  11. from FlatCAM_GTK import FlatCAMApp
  12. class RadioSet(Gtk.Box):
  13. def __init__(self, choices):
  14. """
  15. The choices are specified as a list of dictionaries containing:
  16. * 'label': Shown in the UI
  17. * 'value': The value returned is selected
  18. :param choices: List of choices. See description.
  19. :type choices: list
  20. """
  21. Gtk.Box.__init__(self)
  22. self.choices = copy(choices)
  23. self.group = None
  24. for choice in self.choices:
  25. if self.group is None:
  26. choice['radio'] = Gtk.RadioButton.new_with_label(None, choice['label'])
  27. self.group = choice['radio']
  28. else:
  29. choice['radio'] = Gtk.RadioButton.new_with_label_from_widget(self.group, choice['label'])
  30. self.pack_start(choice['radio'], expand=True, fill=False, padding=2)
  31. choice['radio'].connect('toggled', self.on_toggle)
  32. self.group_toggle_fn = lambda x, y: None
  33. def on_toggle(self, btn):
  34. if btn.get_active():
  35. self.group_toggle_fn(btn, self.get_value)
  36. return
  37. def get_value(self):
  38. for choice in self.choices:
  39. if choice['radio'].get_active():
  40. return choice['value']
  41. FlatCAMApp.App.log.error("No button was toggled in RadioSet.")
  42. return None
  43. def set_value(self, val):
  44. for choice in self.choices:
  45. if choice['value'] == val:
  46. choice['radio'].set_active(True)
  47. return
  48. FlatCAMApp.App.log.error("Value given is not part of this RadioSet: %s" % str(val))
  49. class LengthEntry(Gtk.Entry):
  50. """
  51. A text entry that interprets its string as a
  52. length, with or without specified units. When the user reads
  53. the value, it is interpreted and replaced by a floating
  54. point representation of the value in the default units. When
  55. the entry is activated, its string is repalced by the interpreted
  56. value.
  57. Example:
  58. Default units are 'IN', input is "1.0 mm", value returned
  59. is 1.0/25.4 = 0.03937.
  60. """
  61. def __init__(self, output_units='IN'):
  62. """
  63. :param output_units: The default output units, 'IN' or 'MM'
  64. :return: LengthEntry
  65. """
  66. Gtk.Entry.__init__(self)
  67. self.output_units = output_units
  68. self.format_re = re.compile(r"^([^\s]+)(?:\s([a-zA-Z]+))?$")
  69. # Unit conversion table OUTPUT-INPUT
  70. self.scales = {
  71. 'IN': {'IN': 1.0,
  72. 'MM': 1/25.4},
  73. 'MM': {'IN': 25.4,
  74. 'MM': 1.0}
  75. }
  76. self.connect('activate', self.on_activate)
  77. def on_activate(self, *args):
  78. """
  79. Entry "activate" callback. Replaces the text in the
  80. entry with the value returned by `get_value()`.
  81. :param args: Ignored.
  82. :return: None.
  83. """
  84. val = self.get_value()
  85. if val is not None:
  86. self.set_text(str(val))
  87. else:
  88. FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
  89. def get_value(self):
  90. """
  91. Fetches, interprets and returns the value in the entry. The text
  92. is parsed to find the numerical expression and the (input) units (if any).
  93. The numerical expression is interpreted and scaled acording to the
  94. input and output units `self.output_units`.
  95. :return: Floating point representation of the value in the entry.
  96. :rtype: float
  97. """
  98. raw = self.get_text().strip(' ')
  99. match = self.format_re.search(raw)
  100. if not match:
  101. return None
  102. try:
  103. if match.group(2) is not None and match.group(2).upper() in self.scales:
  104. return float(eval(match.group(1)))*self.scales[self.output_units][match.group(2).upper()]
  105. else:
  106. return float(eval(match.group(1)))
  107. except:
  108. FlatCAMApp.App.log.warning("Could not parse value in entry: %s" % str(raw))
  109. return None
  110. def set_value(self, val):
  111. self.set_text(str(val))
  112. class FloatEntry(Gtk.Entry):
  113. def __init__(self):
  114. Gtk.Entry.__init__(self)
  115. self.connect('activate', self.on_activate)
  116. def on_activate(self, *args):
  117. val = self.get_value()
  118. if val is not None:
  119. self.set_text(str(val))
  120. else:
  121. FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
  122. def get_value(self):
  123. raw = self.get_text().strip(' ')
  124. try:
  125. evaled = eval(raw)
  126. except:
  127. FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
  128. return None
  129. return float(evaled)
  130. def set_value(self, val):
  131. self.set_text(str(val))
  132. class IntEntry(Gtk.Entry):
  133. def __init__(self):
  134. Gtk.Entry.__init__(self)
  135. def get_value(self):
  136. return int(self.get_text())
  137. def set_value(self, val):
  138. self.set_text(str(val))
  139. class FCEntry(Gtk.Entry):
  140. def __init__(self):
  141. Gtk.Entry.__init__(self)
  142. def get_value(self):
  143. return self.get_text()
  144. def set_value(self, val):
  145. self.set_text(str(val))
  146. class EvalEntry(Gtk.Entry):
  147. def __init__(self):
  148. Gtk.Entry.__init__(self)
  149. def on_activate(self, *args):
  150. val = self.get_value()
  151. if val is not None:
  152. self.set_text(str(val))
  153. else:
  154. FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
  155. def get_value(self):
  156. raw = self.get_text().strip(' ')
  157. try:
  158. return eval(raw)
  159. except:
  160. FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
  161. return None
  162. def set_value(self, val):
  163. self.set_text(str(val))
  164. class FCCheckBox(Gtk.CheckButton):
  165. def __init__(self, label=''):
  166. Gtk.CheckButton.__init__(self, label=label)
  167. def get_value(self):
  168. return self.get_active()
  169. def set_value(self, val):
  170. self.set_active(val)
  171. class FCTextArea(Gtk.ScrolledWindow):
  172. def __init__(self):
  173. # Gtk.ScrolledWindow.__init__(self)
  174. # FlatCAMApp.App.log.debug('Gtk.ScrolledWindow.__init__(self)')
  175. super(FCTextArea, self).__init__()
  176. FlatCAMApp.App.log.debug('super(FCTextArea, self).__init__()')
  177. self.set_size_request(250, 100)
  178. FlatCAMApp.App.log.debug('self.set_size_request(250, 100)')
  179. textview = Gtk.TextView()
  180. #print textview
  181. #FlatCAMApp.App.log.debug('self.textview = Gtk.TextView()')
  182. #self.textbuffer = self.textview.get_buffer()
  183. #FlatCAMApp.App.log.debug('self.textbuffer = self.textview.get_buffer()')
  184. #self.textbuffer.set_text("(Nothing here!)")
  185. #FlatCAMApp.App.log.debug('self.textbuffer.set_text("(Nothing here!)")')
  186. #self.add(self.textview)
  187. #FlatCAMApp.App.log.debug('self.add(self.textview)')
  188. #self.show()
  189. def set_value(self, val):
  190. #self.textbuffer.set_text(str(val))
  191. return
  192. def get_value(self):
  193. #return self.textbuffer.get_text()
  194. return ""