Centralized object creation. Cleaner notebook handling. Centralized form generation. Some threading improvement. Comments.

This commit is contained in:
Juan Pablo Caram 2014-01-15 22:51:06 -05:00
parent f888775b36
commit c3260802df
2 changed files with 344 additions and 301 deletions

View File

@ -1,8 +1,7 @@
import threading import threading
from gi.repository import Gtk from gi.repository import Gtk, Gdk, GLib, GObject
from gi.repository import Gdk
from gi.repository import GLib
from matplotlib.figure import Figure from matplotlib.figure import Figure
from numpy import arange, sin, pi from numpy import arange, sin, pi
@ -14,6 +13,12 @@ from camlib import *
class CirkuixObj: 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_getters = {}
form_setters = {} form_setters = {}
@ -55,8 +60,42 @@ class CirkuixObj:
for name in self.form_getters: for name in self.form_getters:
self.options[name] = self.form_getters[name]() 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): class CirkuixGerber(CirkuixObj, Gerber):
"""
Represents Gerber code.
"""
def __init__(self, name): def __init__(self, name):
Gerber.__init__(self) Gerber.__init__(self)
@ -75,20 +114,10 @@ class CirkuixGerber(CirkuixObj, Gerber):
} }
def build_ui(self): def build_ui(self):
print "cirkuixgerber.build_ui()" """
osw = self.app.builder.get_object("offscrwindow_gerber") @return: None
#box1 = self.app.builder.get_object("box_gerber") """
#osw.remove(box1) CirkuixObj.build_ui(self, "gerber")
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()
def plot(self, figure): def plot(self, figure):
self.setup_axes(figure) self.setup_axes(figure)
@ -118,6 +147,9 @@ class CirkuixGerber(CirkuixObj, Gerber):
class CirkuixExcellon(CirkuixObj, Excellon): class CirkuixExcellon(CirkuixObj, Excellon):
"""
Represents Excellon code.
"""
def __init__(self, name): def __init__(self, name):
Excellon.__init__(self) Excellon.__init__(self)
@ -130,20 +162,7 @@ class CirkuixExcellon(CirkuixObj, Excellon):
} }
def build_ui(self): def build_ui(self):
print "build_excellon_ui()" CirkuixObj.build_ui(self, "excellon")
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()
def plot(self, figure): def plot(self, figure):
self.setup_axes(figure) self.setup_axes(figure)
@ -159,6 +178,9 @@ class CirkuixExcellon(CirkuixObj, Excellon):
class CirkuixCNCjob(CirkuixObj, CNCjob): class CirkuixCNCjob(CirkuixObj, CNCjob):
"""
Represents G-Code.
"""
def __init__(self, name, units="in", kind="generic", z_move=0.1, def __init__(self, name, units="in", kind="generic", z_move=0.1,
feedrate=3.0, z_cut=-0.002, tooldia=0.0): feedrate=3.0, z_cut=-0.002, tooldia=0.0):
CNCjob.__init__(self, units=units, kind=kind, z_move=z_move, CNCjob.__init__(self, units=units, kind=kind, z_move=z_move,
@ -172,20 +194,7 @@ class CirkuixCNCjob(CirkuixObj, CNCjob):
} }
def build_ui(self): def build_ui(self):
print "build_cncjob_ui()" CirkuixObj.build_ui(self, "cncjob")
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()
def plot(self, figure): def plot(self, figure):
self.setup_axes(figure) self.setup_axes(figure)
@ -193,6 +202,11 @@ class CirkuixCNCjob(CirkuixObj, CNCjob):
class CirkuixGeometry(CirkuixObj, Geometry): class CirkuixGeometry(CirkuixObj, Geometry):
"""
Geometric object not associated with a specific
format.
"""
def __init__(self, name): def __init__(self, name):
CirkuixObj.__init__(self, name) CirkuixObj.__init__(self, name)
self.options = {"plot": True, self.options = {"plot": True,
@ -209,20 +223,7 @@ class CirkuixGeometry(CirkuixObj, Geometry):
} }
def build_ui(self): def build_ui(self):
print "build_geometry_ui()" CirkuixObj.build_ui(self, "geometry")
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()
def plot(self, figure): def plot(self, figure):
self.setup_axes(figure) self.setup_axes(figure)
@ -244,9 +245,20 @@ class CirkuixGeometry(CirkuixObj, Geometry):
class App: class App:
"""
The main application class. The constructor starts the GUI.
"""
def __init__(self): def __init__(self):
"""
Starts the application and the Gtk.main().
@return: app
"""
# Needed to interact with the GUI from other threads. # Needed to interact with the GUI from other threads.
GLib.threads_init() GLib.threads_init()
GObject.threads_init()
#Gdk.threads_init()
######################################## ########################################
## GUI ## ## GUI ##
@ -296,9 +308,17 @@ class App:
## START ## ## START ##
######################################## ########################################
self.window.show_all() self.window.show_all()
Gtk.main() #Gtk.main()
def setup_plot(self): 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.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 = self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label="base", alpha=0.0)
self.axes.set_aspect(1) self.axes.set_aspect(1)
@ -398,7 +418,9 @@ class App:
""" """
List or Tree where whatever has been loaded or created is List or Tree where whatever has been loaded or created is
displayed. displayed.
@return: None
""" """
self.store = Gtk.ListStore(str) self.store = Gtk.ListStore(str)
self.tree = Gtk.TreeView(self.store) self.tree = Gtk.TreeView(self.store)
#self.list = Gtk.ListBox() #self.list = Gtk.ListBox()
@ -407,24 +429,42 @@ class App:
renderer = Gtk.CellRendererText() renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Title", renderer, text=0) column = Gtk.TreeViewColumn("Title", renderer, text=0)
self.tree.append_column(column) 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): 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) box1 = Gtk.Box(Gtk.Orientation.VERTICAL)
label1 = Gtk.Label("Choose an item from Project") label1 = Gtk.Label("Choose an item from Project")
box1.pack_start(label1, False, False, 1) 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): def info(self, text):
""" """
Show text on the status bar. Show text on the status bar.
@return: None
""" """
self.info_label.set_text(text) self.info_label.set_text(text)
def zoom(self, factor, center=None): def zoom(self, factor, center=None):
""" """
Zooms the plot by factor around a given Zooms the plot by factor around a given
center point. Takes care of re-drawing. center point. Takes care of re-drawing.
@return: None
""" """
xmin, xmax = self.axes.get_xlim() xmin, xmax = self.axes.get_xlim()
ymin, ymax = self.axes.get_ylim() ymin, ymax = self.axes.get_ylim()
@ -455,6 +495,11 @@ class App:
self.canvas.queue_draw() self.canvas.queue_draw()
def build_list(self): def build_list(self):
"""
Clears and re-populates the list of objects in tcurrently
in the project.
@return: None
"""
self.store.clear() self.store.clear()
for key in self.stuff: for key in self.stuff:
self.store.append([key]) self.store.append([key])
@ -463,12 +508,19 @@ class App:
""" """
Returns the radio_set[key] if the radiobutton Returns the radio_set[key] if the radiobutton
whose name is key is active. whose name is key is active.
@return: radio_set[key]
""" """
for name in radio_set: for name in radio_set:
if self.builder.get_object(name).get_active(): if self.builder.get_object(name).get_active():
return radio_set[name] return radio_set[name]
def plot_all(self): def plot_all(self):
"""
Re-generates all plots from all objects.
@return: None
"""
self.clear_plots() self.clear_plots()
for i in self.stuff: for i in self.stuff:
@ -479,88 +531,148 @@ class App:
self.canvas.queue_draw() self.canvas.queue_draw()
def clear_plots(self): def clear_plots(self):
"""
Clears self.axes and self.figure.
@return: None
"""
self.axes.cla() self.axes.cla()
self.figure.clf() self.figure.clf()
self.figure.add_axes(self.axes) self.figure.add_axes(self.axes)
self.canvas.queue_draw() self.canvas.queue_draw()
def get_eval(self, widget_name): 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() value = self.builder.get_object(widget_name).get_text()
return eval(value) return eval(value)
def set_list_selection(self, name): 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() iter = self.store.get_iter_first()
while iter is not None and self.store[iter][0] != name: while iter is not None and self.store[iter][0] != name:
iter = self.store.iter_next(iter) iter = self.store.iter_next(iter)
self.tree_select.unselect_all() self.tree_select.unselect_all()
self.tree_select.select_iter(iter) 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 ## ## EVENT HANDLERS ##
######################################## ########################################
def on_gerber_generate_noncopper(self, widget): def on_gerber_generate_noncopper(self, widget):
gerber = self.stuff[self.selected_item_name]
gerber.read_form()
name = self.selected_item_name + "_noncopper" name = self.selected_item_name + "_noncopper"
bounding_box = gerber.solid_geometry.envelope.buffer(gerber.options["noncoppermargin"]) def geo_init(geo_obj, app_obj):
assert isinstance(geo_obj, CirkuixGeometry)
non_copper = bounding_box.difference(gerber.solid_geometry) gerber = app_obj.stuff[self.selected_item_name]
assert isinstance(gerber, CirkuixGerber)
geometry = CirkuixGeometry(name) gerber.read_form()
geometry.solid_geometry = non_copper bounding_box = gerber.solid_geometry.envelope.buffer(gerber.options["noncoppermargin"])
non_copper = bounding_box.difference(gerber.solid_geometry)
self.stuff[name] = geometry geo_obj.solid_geometry = non_copper
self.build_list()
# TODO: Check for None
self.new_object("geometry", name, geo_init)
def on_gerber_generate_cutout(self, widget): 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" 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. def geo_init(geo_obj, app_obj):
self.stuff[name] = geometry # TODO: get from object
self.build_list() 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): def on_eval_update(self, widget):
""" """
@ -573,39 +685,40 @@ class App:
def on_generate_isolation(self, widget): def on_generate_isolation(self, widget):
print "Generating Isolation Geometry:" 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" iso_name = self.selected_item_name + "_iso"
geo = CirkuixGeometry(iso_name)
geo.solid_geometry = iso
# Add to App and update. def iso_init(geo_obj, app_obj):
self.stuff[iso_name] = geo # TODO: Object must be updated on form change and the options
self.build_list() # 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): def on_generate_cncjob(self, widget):
print "Generating CNC job" 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_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) def job_init(job_obj, app_obj):
job.gcode_parse() # TODO: Object must be updated on form change and the options
job.create_geometry() # TODO: read from the object.
z_cut = app_obj.get_eval("entry_geometry_cutz")
# Add to App and update. z_move = app_obj.get_eval("entry_geometry_travelz")
self.stuff[job_name] = job feedrate = app_obj.get_eval("entry_geometry_feedrate")
self.build_list()
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): def on_cncjob_tooldia_activate(self, widget):
job = self.stuff[self.selected_item_name] job = self.stuff[self.selected_item_name]
@ -626,7 +739,7 @@ class App:
self.stuff.pop(self.selected_item_name) self.stuff.pop(self.selected_item_name)
#self.tree.get_selection().disconnect(self.signal_id) #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( #self.signal_id = self.tree.get_selection().connect(
# "changed", self.on_tree_selection_changed) # "changed", self.on_tree_selection_changed)
@ -658,27 +771,17 @@ class App:
if treeiter is not None: if treeiter is not None:
print "You selected", model[treeiter][0] 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: else:
return # TODO: Clear "Selected" page print "Nothing selected"
self.selected_item_name = None
self.selected_item_name = model[treeiter][0] self.setup_component_editor()
# 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)
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): def on_filequit(self, param):
print "quit from menu" print "quit from menu"
self.window.destroy() self.window.destroy()
@ -755,14 +858,18 @@ class App:
self.progress_bar.set_text("Done!") self.progress_bar.set_text("Done!")
self.progress_bar.set_fraction(1.0) 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.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): def clear_bar(bar):
bar.set_text("") bar.set_text("")
bar.set_fraction(0.0) 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) self.file_chooser_action(on_success)
def on_fileopenexcellon(self, param): def on_fileopenexcellon(self, param):
@ -790,10 +897,17 @@ class App:
self.progress_bar.set_text("Done!") self.progress_bar.set_text("Done!")
self.progress_bar.set_fraction(1.0) 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): def clear_bar(bar):
bar.set_text("") bar.set_text("")
bar.set_fraction(0.0) 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) self.file_chooser_action(on_success)
@ -828,10 +942,16 @@ class App:
self.progress_bar.set_text("Done!") self.progress_bar.set_text("Done!")
self.progress_bar.set_fraction(1.0) 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): def clear_bar(bar):
bar.set_text("") bar.set_text("")
bar.set_fraction(0.0) 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) self.file_chooser_action(on_success)
def on_mouse_move_over_plot(self, event): def on_mouse_move_over_plot(self, event):
@ -846,9 +966,12 @@ class App:
def on_click_over_plot(self, event): def on_click_over_plot(self, event):
# For key presses # For key presses
self.canvas.grab_focus() self.canvas.grab_focus()
print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%( try:
event.button, event.x, event.y, event.xdata, event.ydata) 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): def on_zoom_in(self, event):
self.zoom(1.5) self.zoom(1.5)
@ -926,3 +1049,4 @@ class App:
return return
app = App() app = App()
Gtk.main()

View File

@ -1203,6 +1203,7 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="on_file_new" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
@ -1448,6 +1449,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<child> <child>
<object class="GtkNotebook" id="notebook1"> <object class="GtkNotebook" id="notebook1">
<property name="width_request">250</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="margin_left">3</property> <property name="margin_left">3</property>
@ -1456,135 +1458,12 @@
<property name="margin_bottom">3</property> <property name="margin_bottom">3</property>
<property name="scrollable">True</property> <property name="scrollable">True</property>
<child> <child>
<object class="GtkBox" id="box3"> <object class="GtkBox" id="box_project">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">3</property> <property name="hexpand">True</property>
<property name="margin_right">3</property> <property name="vexpand">True</property>
<property name="margin_top">3</property>
<property name="orientation">vertical</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> <child>
<placeholder/> <placeholder/>
</child> </child>
@ -1594,23 +1473,63 @@
<object class="GtkLabel" id="label1"> <object class="GtkLabel" id="label1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Defaults</property> <property name="label" translatable="yes">Project</property>
</object> </object>
<packing> <packing>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
<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>
<child type="tab"> <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>
<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>
<child type="tab"> <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> </child>
</object> </object>
<packing> <packing>