249 lines
7.5 KiB
Python
249 lines
7.5 KiB
Python
|
############################################################
|
||
|
# FlatCAM: 2D Post-processing for Manufacturing #
|
||
|
# http://caram.cl/software/flatcam #
|
||
|
# Author: Juan Pablo Caram (c) #
|
||
|
# Date: 2/5/2014 #
|
||
|
# MIT Licence #
|
||
|
############################################################
|
||
|
|
||
|
import re
|
||
|
from copy import copy
|
||
|
|
||
|
from gi.repository import Gtk
|
||
|
|
||
|
from FlatCAM_GTK import FlatCAMApp
|
||
|
|
||
|
|
||
|
class RadioSet(Gtk.Box):
|
||
|
def __init__(self, choices):
|
||
|
"""
|
||
|
The choices are specified as a list of dictionaries containing:
|
||
|
|
||
|
* 'label': Shown in the UI
|
||
|
* 'value': The value returned is selected
|
||
|
|
||
|
:param choices: List of choices. See description.
|
||
|
:type choices: list
|
||
|
"""
|
||
|
Gtk.Box.__init__(self)
|
||
|
self.choices = copy(choices)
|
||
|
self.group = None
|
||
|
for choice in self.choices:
|
||
|
if self.group is None:
|
||
|
choice['radio'] = Gtk.RadioButton.new_with_label(None, choice['label'])
|
||
|
self.group = choice['radio']
|
||
|
else:
|
||
|
choice['radio'] = Gtk.RadioButton.new_with_label_from_widget(self.group, choice['label'])
|
||
|
self.pack_start(choice['radio'], expand=True, fill=False, padding=2)
|
||
|
choice['radio'].connect('toggled', self.on_toggle)
|
||
|
|
||
|
self.group_toggle_fn = lambda x, y: None
|
||
|
|
||
|
def on_toggle(self, btn):
|
||
|
if btn.get_active():
|
||
|
self.group_toggle_fn(btn, self.get_value)
|
||
|
return
|
||
|
|
||
|
def get_value(self):
|
||
|
for choice in self.choices:
|
||
|
if choice['radio'].get_active():
|
||
|
return choice['value']
|
||
|
FlatCAMApp.App.log.error("No button was toggled in RadioSet.")
|
||
|
return None
|
||
|
|
||
|
def set_value(self, val):
|
||
|
for choice in self.choices:
|
||
|
if choice['value'] == val:
|
||
|
choice['radio'].set_active(True)
|
||
|
return
|
||
|
FlatCAMApp.App.log.error("Value given is not part of this RadioSet: %s" % str(val))
|
||
|
|
||
|
|
||
|
class LengthEntry(Gtk.Entry):
|
||
|
"""
|
||
|
A text entry that interprets its string as a
|
||
|
length, with or without specified units. When the user reads
|
||
|
the value, it is interpreted and replaced by a floating
|
||
|
point representation of the value in the default units. When
|
||
|
the entry is activated, its string is repalced by the interpreted
|
||
|
value.
|
||
|
|
||
|
Example:
|
||
|
Default units are 'IN', input is "1.0 mm", value returned
|
||
|
is 1.0/25.4 = 0.03937.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, output_units='IN'):
|
||
|
"""
|
||
|
|
||
|
:param output_units: The default output units, 'IN' or 'MM'
|
||
|
:return: LengthEntry
|
||
|
"""
|
||
|
|
||
|
Gtk.Entry.__init__(self)
|
||
|
self.output_units = output_units
|
||
|
self.format_re = re.compile(r"^([^\s]+)(?:\s([a-zA-Z]+))?$")
|
||
|
|
||
|
# Unit conversion table OUTPUT-INPUT
|
||
|
self.scales = {
|
||
|
'IN': {'IN': 1.0,
|
||
|
'MM': 1/25.4},
|
||
|
'MM': {'IN': 25.4,
|
||
|
'MM': 1.0}
|
||
|
}
|
||
|
|
||
|
self.connect('activate', self.on_activate)
|
||
|
|
||
|
def on_activate(self, *args):
|
||
|
"""
|
||
|
Entry "activate" callback. Replaces the text in the
|
||
|
entry with the value returned by `get_value()`.
|
||
|
|
||
|
:param args: Ignored.
|
||
|
:return: None.
|
||
|
"""
|
||
|
val = self.get_value()
|
||
|
if val is not None:
|
||
|
self.set_text(str(val))
|
||
|
else:
|
||
|
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
|
||
|
|
||
|
def get_value(self):
|
||
|
"""
|
||
|
Fetches, interprets and returns the value in the entry. The text
|
||
|
is parsed to find the numerical expression and the (input) units (if any).
|
||
|
The numerical expression is interpreted and scaled acording to the
|
||
|
input and output units `self.output_units`.
|
||
|
|
||
|
:return: Floating point representation of the value in the entry.
|
||
|
:rtype: float
|
||
|
"""
|
||
|
|
||
|
raw = self.get_text().strip(' ')
|
||
|
match = self.format_re.search(raw)
|
||
|
if not match:
|
||
|
return None
|
||
|
try:
|
||
|
if match.group(2) is not None and match.group(2).upper() in self.scales:
|
||
|
return float(eval(match.group(1)))*self.scales[self.output_units][match.group(2).upper()]
|
||
|
else:
|
||
|
return float(eval(match.group(1)))
|
||
|
except:
|
||
|
FlatCAMApp.App.log.warning("Could not parse value in entry: %s" % str(raw))
|
||
|
return None
|
||
|
|
||
|
def set_value(self, val):
|
||
|
self.set_text(str(val))
|
||
|
|
||
|
|
||
|
class FloatEntry(Gtk.Entry):
|
||
|
def __init__(self):
|
||
|
Gtk.Entry.__init__(self)
|
||
|
|
||
|
self.connect('activate', self.on_activate)
|
||
|
|
||
|
def on_activate(self, *args):
|
||
|
val = self.get_value()
|
||
|
if val is not None:
|
||
|
self.set_text(str(val))
|
||
|
else:
|
||
|
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
|
||
|
|
||
|
def get_value(self):
|
||
|
raw = self.get_text().strip(' ')
|
||
|
try:
|
||
|
evaled = eval(raw)
|
||
|
except:
|
||
|
FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
|
||
|
return None
|
||
|
|
||
|
return float(evaled)
|
||
|
|
||
|
def set_value(self, val):
|
||
|
self.set_text(str(val))
|
||
|
|
||
|
|
||
|
class IntEntry(Gtk.Entry):
|
||
|
def __init__(self):
|
||
|
Gtk.Entry.__init__(self)
|
||
|
|
||
|
def get_value(self):
|
||
|
return int(self.get_text())
|
||
|
|
||
|
def set_value(self, val):
|
||
|
self.set_text(str(val))
|
||
|
|
||
|
|
||
|
class FCEntry(Gtk.Entry):
|
||
|
def __init__(self):
|
||
|
Gtk.Entry.__init__(self)
|
||
|
|
||
|
def get_value(self):
|
||
|
return self.get_text()
|
||
|
|
||
|
def set_value(self, val):
|
||
|
self.set_text(str(val))
|
||
|
|
||
|
|
||
|
class EvalEntry(Gtk.Entry):
|
||
|
def __init__(self):
|
||
|
Gtk.Entry.__init__(self)
|
||
|
|
||
|
def on_activate(self, *args):
|
||
|
val = self.get_value()
|
||
|
if val is not None:
|
||
|
self.set_text(str(val))
|
||
|
else:
|
||
|
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
|
||
|
|
||
|
def get_value(self):
|
||
|
raw = self.get_text().strip(' ')
|
||
|
try:
|
||
|
return eval(raw)
|
||
|
except:
|
||
|
FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
|
||
|
return None
|
||
|
|
||
|
def set_value(self, val):
|
||
|
self.set_text(str(val))
|
||
|
|
||
|
|
||
|
class FCCheckBox(Gtk.CheckButton):
|
||
|
def __init__(self, label=''):
|
||
|
Gtk.CheckButton.__init__(self, label=label)
|
||
|
|
||
|
def get_value(self):
|
||
|
return self.get_active()
|
||
|
|
||
|
def set_value(self, val):
|
||
|
self.set_active(val)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
class FCTextArea(Gtk.ScrolledWindow):
|
||
|
def __init__(self):
|
||
|
# Gtk.ScrolledWindow.__init__(self)
|
||
|
# FlatCAMApp.App.log.debug('Gtk.ScrolledWindow.__init__(self)')
|
||
|
super(FCTextArea, self).__init__()
|
||
|
FlatCAMApp.App.log.debug('super(FCTextArea, self).__init__()')
|
||
|
self.set_size_request(250, 100)
|
||
|
FlatCAMApp.App.log.debug('self.set_size_request(250, 100)')
|
||
|
textview = Gtk.TextView()
|
||
|
#print textview
|
||
|
#FlatCAMApp.App.log.debug('self.textview = Gtk.TextView()')
|
||
|
#self.textbuffer = self.textview.get_buffer()
|
||
|
#FlatCAMApp.App.log.debug('self.textbuffer = self.textview.get_buffer()')
|
||
|
#self.textbuffer.set_text("(Nothing here!)")
|
||
|
#FlatCAMApp.App.log.debug('self.textbuffer.set_text("(Nothing here!)")')
|
||
|
#self.add(self.textview)
|
||
|
#FlatCAMApp.App.log.debug('self.add(self.textview)')
|
||
|
#self.show()
|
||
|
|
||
|
def set_value(self, val):
|
||
|
#self.textbuffer.set_text(str(val))
|
||
|
return
|
||
|
|
||
|
def get_value(self):
|
||
|
#return self.textbuffer.get_text()
|
||
|
return ""
|