Centralized object creation. Cleaner notebook handling. Centralized form generation. Some threading improvement. Comments.
This commit is contained in:
parent
f888775b36
commit
c3260802df
464
cirkuix.py
464
cirkuix.py
|
@ -1,8 +1,7 @@
|
|||
|
||||
import threading
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk, Gdk, GLib, GObject
|
||||
|
||||
|
||||
from matplotlib.figure import Figure
|
||||
from numpy import arange, sin, pi
|
||||
|
@ -14,6 +13,12 @@ from camlib import *
|
|||
|
||||
|
||||
class CirkuixObj:
|
||||
"""
|
||||
Base type of objects handled in Cirkuix. These become interactive
|
||||
in the GUI, can be plotted, and their options can be modified
|
||||
by the user in their respective forms.
|
||||
"""
|
||||
|
||||
form_getters = {}
|
||||
|
||||
form_setters = {}
|
||||
|
@ -55,8 +60,42 @@ class CirkuixObj:
|
|||
for name in self.form_getters:
|
||||
self.options[name] = self.form_getters[name]()
|
||||
|
||||
def build_ui(self, kind):
|
||||
"""
|
||||
Sets up the UI/form for this object.
|
||||
@param kind: Kind of object, i.e. 'gerber'
|
||||
@type kind: str
|
||||
@return: None
|
||||
"""
|
||||
|
||||
# Where to the UI for this object
|
||||
box_selected = self.app.builder.get_object("box_selected")
|
||||
|
||||
# Remove anything else in the box
|
||||
box_children = box_selected.get_children()
|
||||
for child in box_children:
|
||||
box_selected.remove(child)
|
||||
|
||||
osw = self.app.builder.get_object("offscrwindow_" + kind) # offscreenwindow
|
||||
sw = self.app.builder.get_object("sw_" + kind) # scrollwindows
|
||||
osw.remove(sw) # TODO: Is this needed ?
|
||||
vp = self.app.builder.get_object("vp_" + kind) # Viewport
|
||||
vp.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(1, 1, 1, 1))
|
||||
|
||||
# Put in the UI
|
||||
box_selected.pack_start(sw, True, True, 0)
|
||||
|
||||
entry_name = self.app.builder.get_object("entry_" + kind + "name")
|
||||
entry_name.set_text(self.name)
|
||||
entry_name.connect("activate", self.app.on_activate_name)
|
||||
self.to_form()
|
||||
sw.show()
|
||||
|
||||
|
||||
class CirkuixGerber(CirkuixObj, Gerber):
|
||||
"""
|
||||
Represents Gerber code.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
Gerber.__init__(self)
|
||||
|
@ -75,20 +114,10 @@ class CirkuixGerber(CirkuixObj, Gerber):
|
|||
}
|
||||
|
||||
def build_ui(self):
|
||||
print "cirkuixgerber.build_ui()"
|
||||
osw = self.app.builder.get_object("offscrwindow_gerber")
|
||||
#box1 = self.app.builder.get_object("box_gerber")
|
||||
#osw.remove(box1)
|
||||
sw = self.app.builder.get_object("sw_gerber")
|
||||
osw.remove(sw)
|
||||
vp = self.app.builder.get_object("vp_gerber")
|
||||
vp.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(1, 1, 1, 1))
|
||||
self.app.notebook.append_page(sw, Gtk.Label("Selection"))
|
||||
entry_name = self.app.builder.get_object("entry_gerbername")
|
||||
entry_name.set_text(self.name)
|
||||
entry_name.connect("activate", self.app.on_activate_name)
|
||||
self.to_form()
|
||||
sw.show()
|
||||
"""
|
||||
@return: None
|
||||
"""
|
||||
CirkuixObj.build_ui(self, "gerber")
|
||||
|
||||
def plot(self, figure):
|
||||
self.setup_axes(figure)
|
||||
|
@ -118,6 +147,9 @@ class CirkuixGerber(CirkuixObj, Gerber):
|
|||
|
||||
|
||||
class CirkuixExcellon(CirkuixObj, Excellon):
|
||||
"""
|
||||
Represents Excellon code.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
Excellon.__init__(self)
|
||||
|
@ -130,20 +162,7 @@ class CirkuixExcellon(CirkuixObj, Excellon):
|
|||
}
|
||||
|
||||
def build_ui(self):
|
||||
print "build_excellon_ui()"
|
||||
osw = self.app.builder.get_object("offscrwindow_excellon")
|
||||
#box1 = self.app.builder.get_object("box_excellon")
|
||||
#osw.remove(box1)
|
||||
sw = self.app.builder.get_object("sw_excellon")
|
||||
osw.remove(sw)
|
||||
vp = self.app.builder.get_object("vp_excellon")
|
||||
vp.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(1, 1, 1, 1))
|
||||
self.app.notebook.append_page(sw, Gtk.Label("Selection"))
|
||||
entry_name = self.app.builder.get_object("entry_excellonname")
|
||||
entry_name.set_text(self.name)
|
||||
entry_name.connect("activate", self.app.on_activate_name)
|
||||
self.to_form()
|
||||
sw.show()
|
||||
CirkuixObj.build_ui(self, "excellon")
|
||||
|
||||
def plot(self, figure):
|
||||
self.setup_axes(figure)
|
||||
|
@ -159,6 +178,9 @@ class CirkuixExcellon(CirkuixObj, Excellon):
|
|||
|
||||
|
||||
class CirkuixCNCjob(CirkuixObj, CNCjob):
|
||||
"""
|
||||
Represents G-Code.
|
||||
"""
|
||||
def __init__(self, name, units="in", kind="generic", z_move=0.1,
|
||||
feedrate=3.0, z_cut=-0.002, tooldia=0.0):
|
||||
CNCjob.__init__(self, units=units, kind=kind, z_move=z_move,
|
||||
|
@ -172,20 +194,7 @@ class CirkuixCNCjob(CirkuixObj, CNCjob):
|
|||
}
|
||||
|
||||
def build_ui(self):
|
||||
print "build_cncjob_ui()"
|
||||
osw = self.app.builder.get_object("offscrwindow_cncjob")
|
||||
#box1 = self.app.builder.get_object("box_cncjob")
|
||||
#osw.remove(box1)
|
||||
sw = self.app.builder.get_object("sw_cncjob")
|
||||
osw.remove(sw)
|
||||
vp = self.app.builder.get_object("vp_cncjob")
|
||||
vp.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(1, 1, 1, 1))
|
||||
self.app.notebook.append_page(sw, Gtk.Label("Selection"))
|
||||
entry_name = self.app.builder.get_object("entry_cncjobname")
|
||||
entry_name.set_text(self.name)
|
||||
entry_name.connect("activate", self.app.on_activate_name)
|
||||
self.to_form()
|
||||
sw.show()
|
||||
CirkuixObj.build_ui(self, "cncjob")
|
||||
|
||||
def plot(self, figure):
|
||||
self.setup_axes(figure)
|
||||
|
@ -193,6 +202,11 @@ class CirkuixCNCjob(CirkuixObj, CNCjob):
|
|||
|
||||
|
||||
class CirkuixGeometry(CirkuixObj, Geometry):
|
||||
"""
|
||||
Geometric object not associated with a specific
|
||||
format.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
CirkuixObj.__init__(self, name)
|
||||
self.options = {"plot": True,
|
||||
|
@ -209,20 +223,7 @@ class CirkuixGeometry(CirkuixObj, Geometry):
|
|||
}
|
||||
|
||||
def build_ui(self):
|
||||
print "build_geometry_ui()"
|
||||
osw = self.app.builder.get_object("offscrwindow_geometry")
|
||||
#box1 = self.app.builder.get_object("box_geometry")
|
||||
#osw.remove(box1)
|
||||
sw = self.app.builder.get_object("sw_geometry")
|
||||
osw.remove(sw)
|
||||
vp = self.app.builder.get_object("vp_geometry")
|
||||
vp.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(1, 1, 1, 1))
|
||||
self.app.notebook.append_page(sw, Gtk.Label("Selection"))
|
||||
entry_name = self.app.builder.get_object("entry_geometryname")
|
||||
entry_name.set_text(self.name)
|
||||
entry_name.connect("activate", self.app.on_activate_name)
|
||||
self.to_form()
|
||||
sw.show()
|
||||
CirkuixObj.build_ui(self, "geometry")
|
||||
|
||||
def plot(self, figure):
|
||||
self.setup_axes(figure)
|
||||
|
@ -244,9 +245,20 @@ class CirkuixGeometry(CirkuixObj, Geometry):
|
|||
|
||||
|
||||
class App:
|
||||
"""
|
||||
The main application class. The constructor starts the GUI.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Starts the application and the Gtk.main().
|
||||
@return: app
|
||||
"""
|
||||
|
||||
# Needed to interact with the GUI from other threads.
|
||||
GLib.threads_init()
|
||||
GObject.threads_init()
|
||||
#Gdk.threads_init()
|
||||
|
||||
########################################
|
||||
## GUI ##
|
||||
|
@ -296,9 +308,17 @@ class App:
|
|||
## START ##
|
||||
########################################
|
||||
self.window.show_all()
|
||||
Gtk.main()
|
||||
#Gtk.main()
|
||||
|
||||
def setup_plot(self):
|
||||
"""
|
||||
Sets up the main plotting area by creating a matplotlib
|
||||
figure in self.canvas, adding axes and configuring them.
|
||||
These axes should not be ploted on and are just there to
|
||||
display the axes ticks and grid.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
self.figure = Figure(dpi=50)
|
||||
self.axes = self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label="base", alpha=0.0)
|
||||
self.axes.set_aspect(1)
|
||||
|
@ -398,7 +418,9 @@ class App:
|
|||
"""
|
||||
List or Tree where whatever has been loaded or created is
|
||||
displayed.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
self.store = Gtk.ListStore(str)
|
||||
self.tree = Gtk.TreeView(self.store)
|
||||
#self.list = Gtk.ListBox()
|
||||
|
@ -407,24 +429,42 @@ class App:
|
|||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn("Title", renderer, text=0)
|
||||
self.tree.append_column(column)
|
||||
self.builder.get_object("notebook1").append_page(self.tree, Gtk.Label("Project"))
|
||||
#self.builder.get_object("notebook1").append_page(self.tree, Gtk.Label("Project"))
|
||||
self.builder.get_object("box_project").pack_start(self.tree, False, False, 1)
|
||||
|
||||
def setup_component_editor(self):
|
||||
"""
|
||||
Initial configuration of the component editor. Creates
|
||||
a page titled "Selection" on the notebook on the left
|
||||
side of the main window.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
box_selected = self.builder.get_object("box_selected")
|
||||
|
||||
# Remove anything else in the box
|
||||
box_children = box_selected.get_children()
|
||||
for child in box_children:
|
||||
box_selected.remove(child)
|
||||
|
||||
box1 = Gtk.Box(Gtk.Orientation.VERTICAL)
|
||||
label1 = Gtk.Label("Choose an item from Project")
|
||||
box1.pack_start(label1, False, False, 1)
|
||||
self.builder.get_object("notebook1").append_page(box1, Gtk.Label("Selection"))
|
||||
box_selected.pack_start(box1, True, True, 0)
|
||||
|
||||
def info(self, text):
|
||||
"""
|
||||
Show text on the status bar.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
self.info_label.set_text(text)
|
||||
|
||||
def zoom(self, factor, center=None):
|
||||
"""
|
||||
Zooms the plot by factor around a given
|
||||
center point. Takes care of re-drawing.
|
||||
@return: None
|
||||
"""
|
||||
xmin, xmax = self.axes.get_xlim()
|
||||
ymin, ymax = self.axes.get_ylim()
|
||||
|
@ -455,6 +495,11 @@ class App:
|
|||
self.canvas.queue_draw()
|
||||
|
||||
def build_list(self):
|
||||
"""
|
||||
Clears and re-populates the list of objects in tcurrently
|
||||
in the project.
|
||||
@return: None
|
||||
"""
|
||||
self.store.clear()
|
||||
for key in self.stuff:
|
||||
self.store.append([key])
|
||||
|
@ -463,12 +508,19 @@ class App:
|
|||
"""
|
||||
Returns the radio_set[key] if the radiobutton
|
||||
whose name is key is active.
|
||||
@return: radio_set[key]
|
||||
"""
|
||||
|
||||
for name in radio_set:
|
||||
if self.builder.get_object(name).get_active():
|
||||
return radio_set[name]
|
||||
|
||||
def plot_all(self):
|
||||
"""
|
||||
Re-generates all plots from all objects.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
self.clear_plots()
|
||||
|
||||
for i in self.stuff:
|
||||
|
@ -479,88 +531,148 @@ class App:
|
|||
self.canvas.queue_draw()
|
||||
|
||||
def clear_plots(self):
|
||||
"""
|
||||
Clears self.axes and self.figure.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
self.axes.cla()
|
||||
self.figure.clf()
|
||||
self.figure.add_axes(self.axes)
|
||||
self.canvas.queue_draw()
|
||||
|
||||
def get_eval(self, widget_name):
|
||||
"""
|
||||
Runs eval() on the on the text entry of name 'widget_name'
|
||||
and returns the results.
|
||||
@param widget_name: Name of Gtk.Entry
|
||||
@return: Depends on contents of the entry text.
|
||||
"""
|
||||
|
||||
value = self.builder.get_object(widget_name).get_text()
|
||||
return eval(value)
|
||||
|
||||
def set_list_selection(self, name):
|
||||
"""
|
||||
Marks a given object as selected in the list ob objects
|
||||
in the GUI. This selection will in turn trigger
|
||||
self.on_tree_selection_changed().
|
||||
@param name: Name of the object.
|
||||
@return: None
|
||||
"""
|
||||
|
||||
iter = self.store.get_iter_first()
|
||||
while iter is not None and self.store[iter][0] != name:
|
||||
iter = self.store.iter_next(iter)
|
||||
self.tree_select.unselect_all()
|
||||
self.tree_select.select_iter(iter)
|
||||
|
||||
def new_object(self, kind, name, initialize):
|
||||
"""
|
||||
Creates a new specalized CirkuixObj and attaches it to the application,
|
||||
this is, updates the GUI accordingly, any other records and plots it.
|
||||
@param kind: Knd of object to create.
|
||||
@param name: Name for the object.
|
||||
@param initilize: Function to run after the
|
||||
object has been created but before attacing it
|
||||
to the application. Takes the new object and the
|
||||
app as parameters.
|
||||
@return: The object requested
|
||||
@rtype : CirkuixObj extended
|
||||
"""
|
||||
|
||||
# Check for existing name
|
||||
if name in self.stuff:
|
||||
return None
|
||||
|
||||
# Create object
|
||||
classdict = {
|
||||
"gerber": CirkuixGerber,
|
||||
"excellon": CirkuixExcellon,
|
||||
"cncjob": CirkuixCNCjob,
|
||||
"geometry": CirkuixGeometry
|
||||
}
|
||||
obj = classdict[kind](name)
|
||||
|
||||
# Initialize as per user request
|
||||
initialize(obj, self)
|
||||
|
||||
# Add to our records
|
||||
self.stuff[name] = obj
|
||||
|
||||
# Update GUI list and select it
|
||||
self.store.append([name])
|
||||
#self.build_list()
|
||||
self.set_list_selection(name)
|
||||
GLib.timeout_add(100, lambda: self.notebook.set_current_page(1))
|
||||
|
||||
# Plot
|
||||
obj.plot(self.figure)
|
||||
obj.axes.set_alpha(0.0)
|
||||
self.on_zoom_fit(None)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
########################################
|
||||
## EVENT HANDLERS ##
|
||||
########################################
|
||||
def on_gerber_generate_noncopper(self, widget):
|
||||
gerber = self.stuff[self.selected_item_name]
|
||||
gerber.read_form()
|
||||
|
||||
name = self.selected_item_name + "_noncopper"
|
||||
|
||||
bounding_box = gerber.solid_geometry.envelope.buffer(gerber.options["noncoppermargin"])
|
||||
|
||||
non_copper = bounding_box.difference(gerber.solid_geometry)
|
||||
|
||||
geometry = CirkuixGeometry(name)
|
||||
geometry.solid_geometry = non_copper
|
||||
|
||||
self.stuff[name] = geometry
|
||||
self.build_list()
|
||||
def geo_init(geo_obj, app_obj):
|
||||
assert isinstance(geo_obj, CirkuixGeometry)
|
||||
gerber = app_obj.stuff[self.selected_item_name]
|
||||
assert isinstance(gerber, CirkuixGerber)
|
||||
gerber.read_form()
|
||||
bounding_box = gerber.solid_geometry.envelope.buffer(gerber.options["noncoppermargin"])
|
||||
non_copper = bounding_box.difference(gerber.solid_geometry)
|
||||
geo_obj.solid_geometry = non_copper
|
||||
|
||||
# TODO: Check for None
|
||||
self.new_object("geometry", name, geo_init)
|
||||
|
||||
def on_gerber_generate_cutout(self, widget):
|
||||
margin = self.get_eval("entry_gerber_cutout_margin")
|
||||
gap_size = self.get_eval("entry_gerber_cutout_gapsize")
|
||||
gerber = self.stuff[self.selected_item_name]
|
||||
minx, miny, maxx, maxy = gerber.bounds()
|
||||
minx -= margin
|
||||
maxx += margin
|
||||
miny -= margin
|
||||
maxy += margin
|
||||
midx = 0.5 * (minx + maxx)
|
||||
midy = 0.5 * (miny + maxy)
|
||||
hgap = 0.5 * gap_size
|
||||
pts = [[midx-hgap, maxy],
|
||||
[minx, maxy],
|
||||
[minx, midy+hgap],
|
||||
[minx, midy-hgap],
|
||||
[minx, miny],
|
||||
[midx-hgap, miny],
|
||||
[midx+hgap, miny],
|
||||
[maxx, miny],
|
||||
[maxx, midy-hgap],
|
||||
[maxx, midy+hgap],
|
||||
[maxx, maxy],
|
||||
[midx+hgap, maxy]]
|
||||
cases = {"tb": [[pts[0], pts[1], pts[4], pts[5]],
|
||||
[pts[6], pts[7], pts[10], pts[11]]],
|
||||
"lr": [[pts[9], pts[10], pts[1], pts[2]],
|
||||
[pts[3], pts[4], pts[7], pts[8]]],
|
||||
"4": [[pts[0], pts[1], pts[2]],
|
||||
[pts[3], pts[4], pts[5]],
|
||||
[pts[6], pts[7], pts[8]],
|
||||
[pts[9], pts[10], pts[11]]]}
|
||||
name = self.selected_item_name + "_cutout"
|
||||
geometry = CirkuixGeometry(name)
|
||||
cuts = None
|
||||
if self.builder.get_object("rb_2tb").get_active():
|
||||
cuts = cases["tb"]
|
||||
elif self.builder.get_object("rb_2lr").get_active():
|
||||
cuts = cases["lr"]
|
||||
else:
|
||||
cuts = cases["4"]
|
||||
geometry.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
|
||||
|
||||
# Add to App and update.
|
||||
self.stuff[name] = geometry
|
||||
self.build_list()
|
||||
def geo_init(geo_obj, app_obj):
|
||||
# TODO: get from object
|
||||
margin = app_obj.get_eval("entry_gerber_cutout_margin")
|
||||
gap_size = app_obj.get_eval("entry_gerber_cutout_gapsize")
|
||||
gerber = app_obj.stuff[app_obj.selected_item_name]
|
||||
minx, miny, maxx, maxy = gerber.bounds()
|
||||
minx -= margin
|
||||
maxx += margin
|
||||
miny -= margin
|
||||
maxy += margin
|
||||
midx = 0.5 * (minx + maxx)
|
||||
midy = 0.5 * (miny + maxy)
|
||||
hgap = 0.5 * gap_size
|
||||
pts = [[midx-hgap, maxy],
|
||||
[minx, maxy],
|
||||
[minx, midy+hgap],
|
||||
[minx, midy-hgap],
|
||||
[minx, miny],
|
||||
[midx-hgap, miny],
|
||||
[midx+hgap, miny],
|
||||
[maxx, miny],
|
||||
[maxx, midy-hgap],
|
||||
[maxx, midy+hgap],
|
||||
[maxx, maxy],
|
||||
[midx+hgap, maxy]]
|
||||
cases = {"tb": [[pts[0], pts[1], pts[4], pts[5]],
|
||||
[pts[6], pts[7], pts[10], pts[11]]],
|
||||
"lr": [[pts[9], pts[10], pts[1], pts[2]],
|
||||
[pts[3], pts[4], pts[7], pts[8]]],
|
||||
"4": [[pts[0], pts[1], pts[2]],
|
||||
[pts[3], pts[4], pts[5]],
|
||||
[pts[6], pts[7], pts[8]],
|
||||
[pts[9], pts[10], pts[11]]]}
|
||||
cuts = cases[app.get_radio_value({"rb_2tb": "tb", "rb_2lr": "lr", "rb_4": "4"})]
|
||||
geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
|
||||
|
||||
# TODO: Check for None
|
||||
self.new_object("geometry", name, geo_init)
|
||||
|
||||
def on_eval_update(self, widget):
|
||||
"""
|
||||
|
@ -573,39 +685,40 @@ class App:
|
|||
|
||||
def on_generate_isolation(self, widget):
|
||||
print "Generating Isolation Geometry:"
|
||||
# Get required info
|
||||
tooldia = self.builder.get_object("entry_gerberisotooldia").get_text()
|
||||
tooldia = eval(tooldia)
|
||||
print "tooldia:", tooldia
|
||||
|
||||
# Generate
|
||||
iso = self.stuff[self.selected_item_name].isolation_geometry(tooldia/2.0)
|
||||
# TODO: This will break if there is something with this name already
|
||||
iso_name = self.selected_item_name + "_iso"
|
||||
geo = CirkuixGeometry(iso_name)
|
||||
geo.solid_geometry = iso
|
||||
|
||||
# Add to App and update.
|
||||
self.stuff[iso_name] = geo
|
||||
self.build_list()
|
||||
def iso_init(geo_obj, app_obj):
|
||||
# TODO: Object must be updated on form change and the options
|
||||
# TODO: read from the object.
|
||||
tooldia = app_obj.get_eval("entry_gerberisotooldia")
|
||||
geo_obj.solid_geometry = self.stuff[self.selected_item_name].isolation_geometry(tooldia/2.0)
|
||||
|
||||
# TODO: Do something if this is None. Offer changing name?
|
||||
self.new_object("geometry", iso_name, iso_init)
|
||||
|
||||
|
||||
def on_generate_cncjob(self, widget):
|
||||
print "Generating CNC job"
|
||||
# Get required info
|
||||
cutz = self.get_eval("entry_geometry_cutz")
|
||||
travelz = self.get_eval("entry_geometry_travelz")
|
||||
feedrate = self.get_eval("entry_geometry_feedrate")
|
||||
|
||||
geometry = self.stuff[self.selected_item_name]
|
||||
|
||||
job_name = self.selected_item_name + "_cnc"
|
||||
job = CirkuixCNCjob(job_name, z_move=travelz, z_cut=cutz, feedrate=feedrate)
|
||||
job.generate_from_geometry(geometry.solid_geometry)
|
||||
job.gcode_parse()
|
||||
job.create_geometry()
|
||||
|
||||
# Add to App and update.
|
||||
self.stuff[job_name] = job
|
||||
self.build_list()
|
||||
|
||||
def job_init(job_obj, app_obj):
|
||||
# TODO: Object must be updated on form change and the options
|
||||
# TODO: read from the object.
|
||||
z_cut = app_obj.get_eval("entry_geometry_cutz")
|
||||
z_move = app_obj.get_eval("entry_geometry_travelz")
|
||||
feedrate = app_obj.get_eval("entry_geometry_feedrate")
|
||||
|
||||
geometry = app_obj.stuff[app_obj.selected_item_name]
|
||||
assert isinstance(job_obj, CirkuixCNCjob)
|
||||
job_obj.z_cut = z_cut
|
||||
job_obj.z_move = z_move
|
||||
job_obj.feedrate = feedrate
|
||||
job_obj.generate_from_geometry(geometry.solid_geometry)
|
||||
job_obj.gcode_parse()
|
||||
job_obj.create_geometry()
|
||||
|
||||
self.new_object("cncjob", job_name, job_init)
|
||||
|
||||
def on_cncjob_tooldia_activate(self, widget):
|
||||
job = self.stuff[self.selected_item_name]
|
||||
|
@ -626,7 +739,7 @@ class App:
|
|||
self.stuff.pop(self.selected_item_name)
|
||||
|
||||
#self.tree.get_selection().disconnect(self.signal_id)
|
||||
self.build_list() # Update the items list
|
||||
self.build_list() # Update the items list
|
||||
#self.signal_id = self.tree.get_selection().connect(
|
||||
# "changed", self.on_tree_selection_changed)
|
||||
|
||||
|
@ -658,27 +771,17 @@ class App:
|
|||
|
||||
if treeiter is not None:
|
||||
print "You selected", model[treeiter][0]
|
||||
self.selected_item_name = model[treeiter][0]
|
||||
#self.stuff[self.selected_item_name].build_ui()
|
||||
GLib.timeout_add(100, lambda: self.stuff[self.selected_item_name].build_ui())
|
||||
else:
|
||||
return # TODO: Clear "Selected" page
|
||||
|
||||
self.selected_item_name = model[treeiter][0]
|
||||
# Remove the current selection page
|
||||
# from the notebook
|
||||
# TODO: Assuming it was last page or #2. Find the right page
|
||||
self.builder.get_object("notebook1").remove_page(2)
|
||||
print "Nothing selected"
|
||||
self.selected_item_name = None
|
||||
self.setup_component_editor()
|
||||
|
||||
self.stuff[self.selected_item_name].build_ui()
|
||||
def on_file_new(self, param):
|
||||
print "File->New not implemented yet."
|
||||
|
||||
# Determine the kind of item selected
|
||||
#kind = self.stuff[model[treeiter][0]].kind
|
||||
|
||||
# Build the UI
|
||||
# builder = {"gerber": self.build_gerber_ui,
|
||||
# "excellon": self.build_excellon_ui,
|
||||
# "cncjob": self.build_cncjob_ui,
|
||||
# "geometry": self.build_geometry_ui}
|
||||
# builder[kind]()
|
||||
|
||||
def on_filequit(self, param):
|
||||
print "quit from menu"
|
||||
self.window.destroy()
|
||||
|
@ -755,14 +858,18 @@ class App:
|
|||
self.progress_bar.set_text("Done!")
|
||||
self.progress_bar.set_fraction(1.0)
|
||||
|
||||
self.notebook.set_current_page(1)
|
||||
#self.notebook.set_current_page(0)
|
||||
self.set_list_selection(name)
|
||||
#self.notebook.set_current_page(1)
|
||||
GLib.timeout_add(100, lambda: self.notebook.set_current_page(1))
|
||||
|
||||
def clear_bar(bar):
|
||||
bar.set_text("")
|
||||
bar.set_fraction(0.0)
|
||||
return False
|
||||
|
||||
threading.Timer(1, clear_bar, args=(self.progress_bar,)).start()
|
||||
#threading.Timer(1, clear_bar, args=(self.progress_bar,)).start()
|
||||
GLib.timeout_add_seconds(1, clear_bar, self.progress_bar)
|
||||
self.file_chooser_action(on_success)
|
||||
|
||||
def on_fileopenexcellon(self, param):
|
||||
|
@ -790,10 +897,17 @@ class App:
|
|||
self.progress_bar.set_text("Done!")
|
||||
self.progress_bar.set_fraction(1.0)
|
||||
|
||||
#self.notebook.set_current_page(0)
|
||||
self.set_list_selection(name)
|
||||
#self.notebook.set_current_page(1)
|
||||
GLib.timeout_add(100, lambda: self.notebook.set_current_page(1))
|
||||
|
||||
def clear_bar(bar):
|
||||
bar.set_text("")
|
||||
bar.set_fraction(0.0)
|
||||
threading.Timer(1, clear_bar, args=(self.progress_bar,)).start()
|
||||
return False
|
||||
#threading.Timer(1, clear_bar, args=(self.progress_bar,)).start()
|
||||
GLib.timeout_add_seconds(1, clear_bar, self.progress_bar)
|
||||
|
||||
self.file_chooser_action(on_success)
|
||||
|
||||
|
@ -828,10 +942,16 @@ class App:
|
|||
self.progress_bar.set_text("Done!")
|
||||
self.progress_bar.set_fraction(1.0)
|
||||
|
||||
#self.notebook.set_current_page(0)
|
||||
self.set_list_selection(name)
|
||||
#self.notebook.set_current_page(1)
|
||||
|
||||
def clear_bar(bar):
|
||||
bar.set_text("")
|
||||
bar.set_fraction(0.0)
|
||||
threading.Timer(1, clear_bar, args=(self.progress_bar,)).start()
|
||||
return False
|
||||
#threading.Timer(1, clear_bar, args=(self.progress_bar,)).start()
|
||||
GLib.timeout_add_seconds(1, clear_bar, self.progress_bar)
|
||||
self.file_chooser_action(on_success)
|
||||
|
||||
def on_mouse_move_over_plot(self, event):
|
||||
|
@ -846,9 +966,12 @@ class App:
|
|||
def on_click_over_plot(self, event):
|
||||
# For key presses
|
||||
self.canvas.grab_focus()
|
||||
|
||||
print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
|
||||
event.button, event.x, event.y, event.xdata, event.ydata)
|
||||
|
||||
try:
|
||||
print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
|
||||
event.button, event.x, event.y, event.xdata, event.ydata)
|
||||
except:
|
||||
print "Outside plot!"
|
||||
|
||||
def on_zoom_in(self, event):
|
||||
self.zoom(1.5)
|
||||
|
@ -926,3 +1049,4 @@ class App:
|
|||
return
|
||||
|
||||
app = App()
|
||||
Gtk.main()
|
||||
|
|
181
cirkuix.ui
181
cirkuix.ui
|
@ -1203,6 +1203,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_file_new" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1448,6 +1449,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook1">
|
||||
<property name="width_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">3</property>
|
||||
|
@ -1456,135 +1458,12 @@
|
|||
<property name="margin_bottom">3</property>
|
||||
<property name="scrollable">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
<object class="GtkBox" id="box_project">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">3</property>
|
||||
<property name="margin_right">3</property>
|
||||
<property name="margin_top">3</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ypad">4</property>
|
||||
<property name="label" translatable="yes">GERBER</property>
|
||||
<property name="use_underline">True</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="semibold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="cb_mergepolys">
|
||||
<property name="label" translatable="yes">Merge Polygons</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton1">
|
||||
<property name="label" translatable="yes">Solid</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="cb_multicolored">
|
||||
<property name="label" translatable="yes">Multi-colored</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ypad">4</property>
|
||||
<property name="label" translatable="yes">G-CODE</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="semibold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Tool dia: </property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_tooldia">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="text" translatable="yes">0.0</property>
|
||||
<signal name="activate" handler="on_eval_update" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
@ -1594,23 +1473,63 @@
|
|||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Defaults</property>
|
||||
<property name="label" translatable="yes">Project</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
<object class="GtkBox" id="box_selected">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<placeholder/>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Selected</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
<object class="GtkBox" id="box_options">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<placeholder/>
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Options</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
|
Loading…
Reference in New Issue