Removed legacy GTK files.

This commit is contained in:
Juan Pablo Caram
2016-09-28 17:40:35 -04:00
parent cd2096934f
commit 2abc9a8faf
13 changed files with 0 additions and 6769 deletions

View File

@@ -1,46 +0,0 @@
from gi.repository import Gtk
class FCNoteBook(Gtk.Notebook):
def __init__(self):
Gtk.Notebook.__init__(self, vexpand=True, vexpand_set=True, valign=1, expand=True)
###############
### Project ###
###############
self.project_contents = Gtk.VBox(vexpand=True, valign=0, vexpand_set=True, expand=True)
sw1 = Gtk.ScrolledWindow(vexpand=True, valign=0, vexpand_set=True, expand=True)
sw1.add_with_viewport(self.project_contents)
self.project_page_num = self.append_page(sw1, Gtk.Label("Project"))
################
### Selected ###
################
self.selected_contents = Gtk.VBox()
sw2 = Gtk.ScrolledWindow()
sw2.add_with_viewport(self.selected_contents)
self.selected_page_num = self.append_page(sw2, Gtk.Label("Selected"))
###############
### Options ###
###############
self.options_contents_super = Gtk.VBox()
sw3 = Gtk.ScrolledWindow()
sw3.add_with_viewport(self.options_contents_super)
self.options_page_num = self.append_page(sw3, Gtk.Label("Options"))
hb = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
ico = Gtk.Image.new_from_file("share/gear32.png")
hb.pack_start(ico, expand=False, fill=False, padding=0)
self.combo_options = Gtk.ComboBoxText()
hb.pack_start(self.combo_options, expand=True, fill=True, padding=0)
self.options_contents_super.pack_start(hb, expand=False, fill=False, padding=0)
self.options_contents = Gtk.VBox()
self.options_contents_super.pack_start(self.options_contents, expand=False, fill=False, padding=0)
############
### Tool ###
############
self.tool_contents = Gtk.VBox()
self.tool_page_num = self.append_page(self.tool_contents, Gtk.Label("Tool"))

View File

@@ -1,15 +0,0 @@
############################################################
# FlatCAM: 2D Post-processing for Manufacturing #
# http://caram.cl/software/flatcam #
# Author: Juan Pablo Caram (c) #
# Date: 2/5/2014 #
# MIT Licence #
############################################################
from gi.repository import Gtk
from FlatCAM_GTK.FlatCAMApp import *
app = App()
Gtk.main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
class FlatCAMException(Exception):
def __init__(self, message="An error occurred", detail=""):
self.message = message
self.detail = detail
def __str__(self):
return "FlatCAM ERROR:", self.message

View File

@@ -1,303 +0,0 @@
from gi.repository import Gtk
from FlatCAM_GTK import FCNoteBook
class FlatCAMGUI(Gtk.Window):
MENU = """
<ui>
<menubar name='MenuBar'>
<menu action='FileMenu'>
<menuitem action='FileNew'>
<separator />
<menuitem action='FileQuit' />
</menu>
</menubar>
<toolbar name='ToolBar'>
<toolitem action='FileNewStandard' />
<toolitem action='FileQuit' />
</toolbar>
</ui>
"""
def __init__(self):
"""
:return: The FlatCAM window.
:rtype: FlatCAM
"""
Gtk.Window.__init__(self, title="FlatCAM - 0.5")
self.set_default_size(200, 200)
vbox1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
### Menu
# action_group = Gtk.ActionGroup("my_actions")
# self.add_file_menu_actions(action_group)
# #self.add_edit_menu_actions(action_group)
# #self.add_choices_menu_actions(action_group)
#
# uimanager = self.create_ui_manager()
# uimanager.insert_action_group(action_group)
#
# menubar = uimanager.get_widget("/MenuBar")
# vbox1.pack_start(menubar, False, False, 0)
#
# toolbar = uimanager.get_widget("/ToolBar")
# vbox1.pack_start(toolbar, False, False, 0)
menu = Gtk.MenuBar()
## File
menufile = Gtk.MenuItem.new_with_label('File')
menufile_menu = Gtk.Menu()
menufile.set_submenu(menufile_menu)
# New
self.menufilenew = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_NEW, None)
menufile_menu.append(self.menufilenew)
menufile_menu.append(Gtk.SeparatorMenuItem())
# Open recent
self.menufilerecent = Gtk.ImageMenuItem("Open Recent", image=Gtk.Image(stock=Gtk.STOCK_OPEN))
menufile_menu.append(self.menufilerecent)
menufile_menu.append(Gtk.SeparatorMenuItem())
# Open Gerber ...
self.menufileopengerber = Gtk.ImageMenuItem("Open Gerber ...", image=Gtk.Image(stock=Gtk.STOCK_OPEN))
menufile_menu.append(self.menufileopengerber)
# Open Excellon ...
self.menufileopenexcellon = Gtk.ImageMenuItem("Open Excellon ...", image=Gtk.Image(stock=Gtk.STOCK_OPEN))
menufile_menu.append(self.menufileopenexcellon)
# Open G-Code ...
self.menufileopengcode = Gtk.ImageMenuItem("Open G-Code ...", image=Gtk.Image(stock=Gtk.STOCK_OPEN))
menufile_menu.append(self.menufileopengcode)
menufile_menu.append(Gtk.SeparatorMenuItem())
# Open Project ...
self.menufileopenproject = Gtk.ImageMenuItem("Open Project ...", image=Gtk.Image(stock=Gtk.STOCK_OPEN))
menufile_menu.append(self.menufileopenproject)
menufile_menu.append(Gtk.SeparatorMenuItem())
# Save Project
self.menufilesaveproject = Gtk.ImageMenuItem("Save Project", image=Gtk.Image(stock=Gtk.STOCK_SAVE))
menufile_menu.append(self.menufilesaveproject)
# Save Project As ...
self.menufilesaveprojectas = Gtk.ImageMenuItem("Save Project As ...", image=Gtk.Image(stock=Gtk.STOCK_SAVE_AS))
menufile_menu.append(self.menufilesaveprojectas)
# Save Project Copy ...
self.menufilesaveprojectcopy = Gtk.ImageMenuItem("Save Project Copy ...", image=Gtk.Image(stock=Gtk.STOCK_SAVE_AS))
menufile_menu.append(self.menufilesaveprojectcopy)
menufile_menu.append(Gtk.SeparatorMenuItem())
# Save Defaults
self.menufilesavedefaults = Gtk.ImageMenuItem("Save Defaults", image=Gtk.Image(stock=Gtk.STOCK_SAVE))
menufile_menu.append(self.menufilesavedefaults)
menufile_menu.append(Gtk.SeparatorMenuItem())
# Quit
self.menufilequit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
menufile_menu.append(self.menufilequit)
menu.append(menufile)
## Edit
menuedit = Gtk.MenuItem.new_with_label('Edit')
menu.append(menuedit)
menuedit_menu = Gtk.Menu()
menuedit.set_submenu(menuedit_menu)
# Delete
self.menueditdelete = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_DELETE, None)
menuedit_menu.append(self.menueditdelete)
## View
menuview = Gtk.MenuItem.new_with_label('View')
menu.append(menuview)
menuview_menu = Gtk.Menu()
menuview.set_submenu(menuview_menu)
# Disable all plots
self.menuviewdisableall = Gtk.ImageMenuItem("Disable all plots", image=Gtk.Image.new_from_file('share/clear_plot16.png'))
menuview_menu.append(self.menuviewdisableall)
self.menuviewdisableallbutthis = Gtk.ImageMenuItem("Disable all plots but this one", image=Gtk.Image.new_from_file('share/clear_plot16.png'))
menuview_menu.append(self.menuviewdisableallbutthis)
self.menuviewenableall = Gtk.ImageMenuItem("Enable all plots", image=Gtk.Image.new_from_file('share/replot16.png'))
menuview_menu.append(self.menuviewenableall)
## Options
menuoptions = Gtk.MenuItem.new_with_label('Options')
menu.append(menuoptions)
menuoptions_menu = Gtk.Menu()
menuoptions.set_submenu(menuoptions_menu)
# Transfer Options
menutransferoptions = Gtk.ImageMenuItem("Transfer Options", image=Gtk.Image.new_from_file('share/copy16.png'))
menuoptions_menu.append(menutransferoptions)
menutransferoptions_menu = Gtk.Menu()
menutransferoptions.set_submenu(menutransferoptions_menu)
self.menutransferoptions_p2a = Gtk.ImageMenuItem("Project to App", image=Gtk.Image.new_from_file('share/copy16.png'))
menutransferoptions_menu.append(self.menutransferoptions_p2a)
self.menutransferoptions_a2p = Gtk.ImageMenuItem("App to Project", image=Gtk.Image.new_from_file('share/copy16.png'))
menutransferoptions_menu.append(self.menutransferoptions_a2p)
self.menutransferoptions_o2p = Gtk.ImageMenuItem("Object to Project", image=Gtk.Image.new_from_file('share/copy16.png'))
menutransferoptions_menu.append(self.menutransferoptions_o2p)
self.menutransferoptions_o2a = Gtk.ImageMenuItem("Object to App", image=Gtk.Image.new_from_file('share/copy16.png'))
menutransferoptions_menu.append(self.menutransferoptions_o2a)
self.menutransferoptions_p2o = Gtk.ImageMenuItem("Project to Object", image=Gtk.Image.new_from_file('share/copy16.png'))
menutransferoptions_menu.append(self.menutransferoptions_p2o)
self.menutransferoptions_a2o = Gtk.ImageMenuItem("App to Object", image=Gtk.Image.new_from_file('share/copy16.png'))
menutransferoptions_menu.append(self.menutransferoptions_a2o)
## Tools
menutools = Gtk.MenuItem.new_with_label('Tools')
menu.append(menutools)
menutools_menu = Gtk.Menu()
menutools.set_submenu(menutools_menu)
# Double Sided PCB tool
self.menutools_dblsided = Gtk.ImageMenuItem("Double-Sided PCB Tool", image=Gtk.Image(stock=Gtk.STOCK_PREFERENCES))
menutools_menu.append(self.menutools_dblsided)
## Help
menuhelp = Gtk.MenuItem.new_with_label('Help')
menu.append(menuhelp)
menuhelp_menu = Gtk.Menu()
menuhelp.set_submenu(menuhelp_menu)
# About
self.menuhelpabout = Gtk.ImageMenuItem("About", image=Gtk.Image(stock=Gtk.STOCK_ABOUT))
menuhelp_menu.append(self.menuhelpabout)
# Updates
self.menuhelpupdates = Gtk.ImageMenuItem("Check for updates", image=Gtk.Image(stock=Gtk.STOCK_DIALOG_INFO))
menuhelp_menu.append(self.menuhelpupdates)
vbox1.pack_start(menu, False, False, 0)
### End of menu
###############
### Toolbar ###
###############
self.toolbar = Gtk.Toolbar(toolbar_style=Gtk.ToolbarStyle.ICONS)
vbox1.pack_start(self.toolbar, False, False, 0)
# Zoom fit
zf_ico = Gtk.Image.new_from_file('share/zoom_fit32.png')
self.zoom_fit_btn = Gtk.ToolButton.new(zf_ico, "")
#zoom_fit.connect("clicked", self.on_zoom_fit)
self.zoom_fit_btn.set_tooltip_markup("Zoom Fit.\n(Click on plot and hit <b>1</b>)")
self.toolbar.insert(self.zoom_fit_btn, -1)
# Zoom out
zo_ico = Gtk.Image.new_from_file('share/zoom_out32.png')
self.zoom_out_btn = Gtk.ToolButton.new(zo_ico, "")
#zoom_out.connect("clicked", self.on_zoom_out)
self.zoom_out_btn.set_tooltip_markup("Zoom Out.\n(Click on plot and hit <b>2</b>)")
self.toolbar.insert(self.zoom_out_btn, -1)
# Zoom in
zi_ico = Gtk.Image.new_from_file('share/zoom_in32.png')
self.zoom_in_btn = Gtk.ToolButton.new(zi_ico, "")
#zoom_in.connect("clicked", self.on_zoom_in)
self.zoom_in_btn.set_tooltip_markup("Zoom In.\n(Click on plot and hit <b>3</b>)")
self.toolbar.insert(self.zoom_in_btn, -1)
# Clear plot
cp_ico = Gtk.Image.new_from_file('share/clear_plot32.png')
self.clear_plot_btn = Gtk.ToolButton.new(cp_ico, "")
#clear_plot.connect("clicked", self.on_clear_plots)
self.clear_plot_btn.set_tooltip_markup("Clear Plot")
self.toolbar.insert(self.clear_plot_btn, -1)
# Replot
rp_ico = Gtk.Image.new_from_file('share/replot32.png')
self.replot_btn = Gtk.ToolButton.new(rp_ico, "")
#replot.connect("clicked", self.on_toolbar_replot)
self.replot_btn.set_tooltip_markup("Re-plot all")
self.toolbar.insert(self.replot_btn, -1)
# Delete item
del_ico = Gtk.Image.new_from_file('share/delete32.png')
self.delete_btn = Gtk.ToolButton.new(del_ico, "")
#delete.connect("clicked", self.on_delete)
self.delete_btn.set_tooltip_markup("Delete selected\nobject.")
self.toolbar.insert(self.delete_btn, -1)
#############
### Paned ###
#############
hpane = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
vbox1.pack_start(hpane, expand=True, fill=True, padding=0)
################
### Notebook ###
################
self.notebook = FCNoteBook()
hpane.pack1(self.notebook)
#################
### Plot area ###
#################
# self.plotarea = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.plotarea = Gtk.Grid()
self.plotarea_super = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.plotarea_super.pack_start(self.plotarea, expand=True, fill=True, padding=0)
hpane.pack2(self.plotarea_super)
################
### Info bar ###
################
infobox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
vbox1.pack_start(infobox, expand=False, fill=True, padding=0)
## Frame
frame = Gtk.Frame(margin=2, hexpand=True, halign=0)
infobox.pack_start(frame, expand=True, fill=True, padding=0)
self.info_label = Gtk.Label("Not started.", margin=2, hexpand=True)
frame.add(self.info_label)
## Coordinate Label
self.position_label = Gtk.Label("X: 0.0 Y: 0.0", margin_left=4, margin_right=4)
infobox.pack_start(self.position_label, expand=False, fill=False, padding=0)
## Units label
self.units_label = Gtk.Label("[in]", margin_left=4, margin_right=4)
infobox.pack_start(self.units_label, expand=False, fill=False, padding=0)
## Progress bar
self.progress_bar = Gtk.ProgressBar(margin=2)
infobox.pack_start(self.progress_bar, expand=False, fill=False, padding=0)
self.add(vbox1)
self.show_all()
# def create_ui_manager(self):
# uimanager = Gtk.UIManager()
#
# # Throws exception if something went wrong
# uimanager.add_ui_from_string(FlatCAM.MENU)
#
# # Add the accelerator group to the toplevel window
# accelgroup = uimanager.get_accel_group()
# self.add_accel_group(accelgroup)
# return uimanager
#
# def add_file_menu_actions(self, action_group):
# action_filemenu = Gtk.Action("FileMenu", "File", None, None)
# action_group.add_action(action_filemenu)
#
# action_filenewmenu = Gtk.Action("FileNew", None, None, Gtk.STOCK_NEW)
# action_group.add_action(action_filenewmenu)
#
# action_new = Gtk.Action("FileNewStandard", "_New",
# "Create a new file", Gtk.STOCK_NEW)
# action_new.connect("activate", self.on_menu_file_new_generic)
# action_group.add_action_with_accel(action_new, None)
#
# action_group.add_actions([
# ("FileNewFoo", None, "New Foo", None, "Create new foo",
# self.on_menu_file_new_generic),
# ("FileNewGoo", None, "_New Goo", None, "Create new goo",
# self.on_menu_file_new_generic),
# ])
#
# action_filequit = Gtk.Action("FileQuit", None, None, Gtk.STOCK_QUIT)
# action_filequit.connect("activate", self.on_menu_file_quit)
# action_group.add_action(action_filequit)
#
# def on_menu_file_new_generic(self, widget):
# print("A File|New menu item was selected.")
#
# def on_menu_file_quit(self, widget):
# Gtk.main_quit()
if __name__ == "__main__":
flatcam = FlatCAMGUI()
Gtk.main()

File diff suppressed because it is too large Load Diff

View File

@@ -1,43 +0,0 @@
############################################################
# FlatCAM: 2D Post-processing for Manufacturing #
# http://caram.cl/software/flatcam #
# Author: Juan Pablo Caram (c) #
# Date: 2/5/2014 #
# MIT Licence #
############################################################
import threading
import Queue
class Worker(threading.Thread):
"""
Implements a queue of tasks to be carried out in order
in a single independent thread.
"""
def __init__(self):
super(Worker, self).__init__()
self.queue = Queue.Queue()
self.stoprequest = threading.Event()
def run(self):
while not self.stoprequest.isSet():
try:
task = self.queue.get(True, 0.05)
self.do_task(task)
except Queue.Empty:
continue
@staticmethod
def do_task(task):
task['fcn'](*task['params'])
return
def add_task(self, target, params=list()):
self.queue.put({'fcn': target, 'params': params})
return
def join(self, timeout=None):
self.stoprequest.set()
super(Worker, self).join()

View File

@@ -1,249 +0,0 @@
############################################################
# 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 ""

View File

@@ -1,261 +0,0 @@
############################################################
# FlatCAM: 2D Post-processing for Manufacturing #
# http://caram.cl/software/flatcam #
# Author: Juan Pablo Caram (c) #
# Date: 4/20/2014 #
# MIT Licence #
############################################################
import inspect # TODO: Remove
from gi.repository import Gtk, GdkPixbuf, GLib
from FlatCAMObj import *
from FlatCAM_GTK import FlatCAMApp
class ObjectCollection:
classdict = {
"gerber": FlatCAMGerber,
"excellon": FlatCAMExcellon,
"cncjob": FlatCAMCNCjob,
"geometry": FlatCAMGeometry
}
icon_files = {
"gerber": "share/flatcam_icon16.png",
"excellon": "share/drill16.png",
"cncjob": "share/cnc16.png",
"geometry": "share/geometry16.png"
}
def __init__(self):
### Icons for the list view
self.icons = {}
for kind in ObjectCollection.icon_files:
self.icons[kind] = GdkPixbuf.Pixbuf.new_from_file(ObjectCollection.icon_files[kind])
### GUI List components
## Model
self.store = Gtk.ListStore(FlatCAMObj)
## View
self.view = Gtk.TreeView(model=self.store)
#self.view.connect("row_activated", self.on_row_activated)
self.tree_selection = self.view.get_selection()
self.change_subscription = self.tree_selection.connect("changed", self.on_list_selection_change)
## Renderers
# Icon
renderer_pixbuf = Gtk.CellRendererPixbuf()
column_pixbuf = Gtk.TreeViewColumn("Type", renderer_pixbuf)
def _set_cell_icon(column, cell, model, it, data):
obj = model.get_value(it, 0)
cell.set_property('pixbuf', self.icons[obj.kind])
column_pixbuf.set_cell_data_func(renderer_pixbuf, _set_cell_icon)
self.view.append_column(column_pixbuf)
# Name
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Name", renderer_text)
def _set_cell_text(column, cell, model, it, data):
obj = model.get_value(it, 0)
cell.set_property('text', obj.options["name"])
column_text.set_cell_data_func(renderer_text, _set_cell_text)
self.view.append_column(column_text)
def print_list(self):
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
print obj
iterat = self.store.iter_next(iterat)
def delete_all(self):
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.delete_all()")
self.store.clear()
def delete_active(self):
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.delete_active()")
try:
model, treeiter = self.tree_selection.get_selected()
self.store.remove(treeiter)
except:
pass
def on_list_selection_change(self, selection):
"""
Callback for change in selection on the objects' list.
Instructs the new selection to build the UI for its options.
:param selection: Ignored.
:return: None
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.on_list_selection_change()")
active = self.get_active()
active.build_ui()
def set_active(self, name):
"""
Sets an object as the active object in the program. Same
as `set_list_selection()`.
:param name: Name of the object.
:type name: str
:return: None
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.set_active()")
self.set_list_selection(name)
def get_active(self):
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_active()")
try:
model, treeiter = self.tree_selection.get_selected()
return model[treeiter][0]
except (TypeError, ValueError):
return None
def set_list_selection(self, name):
"""
Sets which object should be selected in the list.
:param name: Name of the object.
:rtype name: str
:return: None
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.set_list_selection()")
iterat = self.store.get_iter_first()
while iterat is not None and self.store[iterat][0].options["name"] != name:
iterat = self.store.iter_next(iterat)
self.tree_selection.select_iter(iterat)
def append(self, obj, active=False):
"""
Add a FlatCAMObj the the collection. This method is thread-safe.
:param obj: FlatCAMObj to append
:type obj: FlatCAMObj
:param active: If it is to become the active object after appending
:type active: bool
:return: None
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.append()")
def guitask():
self.store.append([obj])
if active:
self.set_list_selection(obj.options["name"])
GLib.idle_add(guitask)
def get_names(self):
"""
Gets a list of the names of all objects in the collection.
:return: List of names.
:rtype: list
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_names()")
names = []
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
names.append(obj.options["name"])
iterat = self.store.iter_next(iterat)
return names
def get_bounds(self):
"""
Finds coordinates bounding all objects in the collection.
:return: [xmin, ymin, xmax, ymax]
:rtype: list
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_bounds()")
# TODO: Move the operation out of here.
xmin = Inf
ymin = Inf
xmax = -Inf
ymax = -Inf
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
try:
gxmin, gymin, gxmax, gymax = obj.bounds()
xmin = min([xmin, gxmin])
ymin = min([ymin, gymin])
xmax = max([xmax, gxmax])
ymax = max([ymax, gymax])
except:
FlatCAMApp.App.log.warning("DEV WARNING: Tried to get bounds of empty geometry.")
iterat = self.store.iter_next(iterat)
return [xmin, ymin, xmax, ymax]
def get_list(self):
"""
Returns a list with all FlatCAMObj.
:return: List with all FlatCAMObj.
:rtype: list
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_list()")
collection_list = []
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
collection_list.append(obj)
iterat = self.store.iter_next(iterat)
return collection_list
def get_by_name(self, name):
"""
Fetches the FlatCAMObj with the given `name`.
:param name: The name of the object.
:type name: str
:return: The requested object or None if no such object.
:rtype: FlatCAMObj or None
"""
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_by_name()")
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
if obj.options["name"] == name:
return obj
iterat = self.store.iter_next(iterat)
return None
# def change_name(self, old_name, new_name):
# """
# Changes the name of `FlatCAMObj` named `old_name` to `new_name`.
#
# :param old_name: Name of the object to change.
# :type old_name: str
# :param new_name: New name.
# :type new_name: str
# :return: True if name change succeeded, False otherwise. Will fail
# if no object with `old_name` is found.
# :rtype: bool
# """
# print inspect.stack()[1][3], "--> OC.change_name()"
# iterat = self.store.get_iter_first()
# while iterat is not None:
# obj = self.store[iterat][0]
# if obj.options["name"] == old_name:
# obj.options["name"] = new_name
# self.store.row_changed(0, iterat)
# return True
# iterat = self.store.iter_next(iterat)
# return False

View File

@@ -1,627 +0,0 @@
############################################################
# FlatCAM: 2D Post-processing for Manufacturing #
# http://caram.cl/software/flatcam #
# Author: Juan Pablo Caram (c) #
# Date: 2/5/2014 #
# MIT Licence #
############################################################
from gi.repository import Gtk
from FlatCAM_GTK.GUIElements import *
class ObjectUI(Gtk.VBox):
"""
Base class for the UI of FlatCAM objects. Deriving classes should
put UI elements in ObjectUI.custom_box (Gtk.VBox).
"""
def __init__(self, icon_file='share/flatcam_icon32.png', title='FlatCAM Object'):
Gtk.VBox.__init__(self, spacing=3, margin=5, vexpand=False)
## Page Title box (spacing between children)
self.title_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 2)
self.pack_start(self.title_box, expand=False, fill=False, padding=2)
## Page Title icon
self.icon = Gtk.Image.new_from_file(icon_file)
self.title_box.pack_start(self.icon, expand=False, fill=False, padding=2)
## Title label
self.title_label = Gtk.Label()
self.title_label.set_markup("<b>" + title + "</b>")
self.title_label.set_justify(Gtk.Justification.CENTER)
self.title_box.pack_start(self.title_label, expand=False, fill=False, padding=2)
## Object name
self.name_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 2)
self.pack_start(self.name_box, expand=False, fill=False, padding=2)
name_label = Gtk.Label('Name:')
name_label.set_justify(Gtk.Justification.RIGHT)
self.name_box.pack_start(name_label,
expand=False, fill=False, padding=2)
self.name_entry = FCEntry()
self.name_box.pack_start(self.name_entry, expand=True, fill=False, padding=2)
## Box box for custom widgets
self.custom_box = Gtk.VBox(spacing=3, margin=0, vexpand=False)
self.pack_start(self.custom_box, expand=False, fill=False, padding=0)
## Common to all objects
## Scale
self.scale_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.scale_label.set_markup('<b>Scale:</b>')
self.scale_label.set_tooltip_markup(
"Change the size of the object."
)
self.pack_start(self.scale_label, expand=False, fill=False, padding=2)
grid5 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.pack_start(grid5, expand=False, fill=False, padding=2)
# Factor
l10 = Gtk.Label('Factor:', xalign=1)
l10.set_tooltip_markup(
"Factor by which to multiply\n"
"geometric features of this object."
)
grid5.attach(l10, 0, 0, 1, 1)
self.scale_entry = FloatEntry()
self.scale_entry.set_text("1.0")
grid5.attach(self.scale_entry, 1, 0, 1, 1)
# GO Button
self.scale_button = Gtk.Button(label='Scale')
self.scale_button.set_tooltip_markup(
"Perform scaling operation."
)
self.pack_start(self.scale_button, expand=False, fill=False, padding=2)
## Offset
self.offset_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.offset_label.set_markup('<b>Offset:</b>')
self.offset_label.set_tooltip_markup(
"Change the position of this object."
)
self.pack_start(self.offset_label, expand=False, fill=False, padding=2)
grid6 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.pack_start(grid6, expand=False, fill=False, padding=2)
# Vector
l11 = Gtk.Label('Offset Vector:', xalign=1)
l11.set_tooltip_markup(
"Amount by which to move the object\n"
"in the x and y axes in (x, y) format."
)
grid6.attach(l11, 0, 0, 1, 1)
self.offsetvector_entry = EvalEntry()
self.offsetvector_entry.set_text("(0.0, 0.0)")
grid6.attach(self.offsetvector_entry, 1, 0, 1, 1)
self.offset_button = Gtk.Button(label='Scale')
self.offset_button.set_tooltip_markup(
"Perform the offset operation."
)
self.pack_start(self.offset_button, expand=False, fill=False, padding=2)
def set_field(self, name, value):
getattr(self, name).set_value(value)
def get_field(self, name):
return getattr(self, name).get_value()
class CNCObjectUI(ObjectUI):
"""
User interface for CNCJob objects.
"""
def __init__(self):
ObjectUI.__init__(self, title='CNC Job Object', icon_file='share/cnc32.png')
## Plot options
self.plot_options_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.plot_options_label.set_markup("<b>Plot Options:</b>")
self.custom_box.pack_start(self.plot_options_label, expand=False, fill=True, padding=2)
grid0 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid0, expand=False, fill=False, padding=2)
# Plot CB
self.plot_cb = FCCheckBox(label='Plot')
self.plot_cb.set_tooltip_markup(
"Plot (show) this object."
)
grid0.attach(self.plot_cb, 0, 0, 2, 1)
# Tool dia for plot
l1 = Gtk.Label('Tool dia:', xalign=1)
l1.set_tooltip_markup(
"Diameter of the tool to be\n"
"rendered in the plot."
)
grid0.attach(l1, 0, 1, 1, 1)
self.tooldia_entry = LengthEntry()
grid0.attach(self.tooldia_entry, 1, 1, 1, 1)
# Update plot button
self.updateplot_button = Gtk.Button(label='Update Plot')
self.updateplot_button.set_tooltip_markup(
"Update the plot."
)
self.custom_box.pack_start(self.updateplot_button, expand=False, fill=False, padding=2)
## Export G-Code
self.export_gcode_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.export_gcode_label.set_markup("<b>Export G-Code:</b>")
self.export_gcode_label.set_tooltip_markup(
"Export and save G-Code to\n"
"make this object to a file."
)
self.custom_box.pack_start(self.export_gcode_label, expand=False, fill=False, padding=2)
# Append text to Gerber
l2 = Gtk.Label('Append to G-Code:')
l2.set_tooltip_markup(
"Type here any G-Code commands you would\n"
"like to append to the generated file.\n"
"I.e.: M2 (End of program)"
)
self.custom_box.pack_start(l2, expand=False, fill=False, padding=2)
#self.append_gtext = FCTextArea()
#self.custom_box.pack_start(self.append_gtext, expand=False, fill=False, padding=2)
# GO Button
self.export_gcode_button = Gtk.Button(label='Export G-Code')
self.export_gcode_button.set_tooltip_markup(
"Opens dialog to save G-Code\n"
"file."
)
self.custom_box.pack_start(self.export_gcode_button, expand=False, fill=False, padding=2)
class GeometryObjectUI(ObjectUI):
"""
User interface for Geometry objects.
"""
def __init__(self):
ObjectUI.__init__(self, title='Geometry Object', icon_file='share/geometry32.png')
## Plot options
self.plot_options_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.plot_options_label.set_markup("<b>Plot Options:</b>")
self.custom_box.pack_start(self.plot_options_label, expand=False, fill=True, padding=2)
grid0 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid0, expand=True, fill=False, padding=2)
# Plot CB
self.plot_cb = FCCheckBox(label='Plot')
self.plot_cb.set_tooltip_markup(
"Plot (show) this object."
)
grid0.attach(self.plot_cb, 0, 0, 1, 1)
## Create CNC Job
self.cncjob_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.cncjob_label.set_markup('<b>Create CNC Job:</b>')
self.cncjob_label.set_tooltip_markup(
"Create a CNC Job object\n"
"tracing the contours of this\n"
"Geometry object."
)
self.custom_box.pack_start(self.cncjob_label, expand=True, fill=False, padding=2)
grid1 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid1, expand=True, fill=False, padding=2)
# Cut Z
l1 = Gtk.Label('Cut Z:', xalign=1)
l1.set_tooltip_markup(
"Cutting depth (negative)\n"
"below the copper surface."
)
grid1.attach(l1, 0, 0, 1, 1)
self.cutz_entry = LengthEntry()
grid1.attach(self.cutz_entry, 1, 0, 1, 1)
# Travel Z
l2 = Gtk.Label('Travel Z:', xalign=1)
l2.set_tooltip_markup(
"Height of the tool when\n"
"moving without cutting."
)
grid1.attach(l2, 0, 1, 1, 1)
self.travelz_entry = LengthEntry()
grid1.attach(self.travelz_entry, 1, 1, 1, 1)
l3 = Gtk.Label('Feed rate:', xalign=1)
l3.set_tooltip_markup(
"Cutting speed in the XY\n"
"plane in units per minute"
)
grid1.attach(l3, 0, 2, 1, 1)
self.cncfeedrate_entry = LengthEntry()
grid1.attach(self.cncfeedrate_entry, 1, 2, 1, 1)
l4 = Gtk.Label('Tool dia:', xalign=1)
l4.set_tooltip_markup(
"The diameter of the cutting\n"
"tool (just for display)."
)
grid1.attach(l4, 0, 3, 1, 1)
self.cnctooldia_entry = LengthEntry()
grid1.attach(self.cnctooldia_entry, 1, 3, 1, 1)
self.generate_cnc_button = Gtk.Button(label='Generate')
self.generate_cnc_button.set_tooltip_markup(
"Generate the CNC Job object."
)
self.custom_box.pack_start(self.generate_cnc_button, expand=True, fill=False, padding=2)
## Paint Area
self.paint_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.paint_label.set_markup('<b>Paint Area:</b>')
self.paint_label.set_tooltip_markup(
"Creates tool paths to cover the\n"
"whole area of a polygon (remove\n"
"all copper). You will be asked\n"
"to click on the desired polygon."
)
self.custom_box.pack_start(self.paint_label, expand=True, fill=False, padding=2)
grid2 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid2, expand=True, fill=False, padding=2)
# Tool dia
l5 = Gtk.Label('Tool dia:', xalign=1)
l5.set_tooltip_markup(
"Diameter of the tool to\n"
"be used in the operation."
)
grid2.attach(l5, 0, 0, 1, 1)
self.painttooldia_entry = LengthEntry()
grid2.attach(self.painttooldia_entry, 1, 0, 1, 1)
# Overlap
l6 = Gtk.Label('Overlap:', xalign=1)
l6.set_tooltip_markup(
"How much (fraction) of the tool\n"
"width to overlap each tool pass."
)
grid2.attach(l6, 0, 1, 1, 1)
self.paintoverlap_entry = LengthEntry()
grid2.attach(self.paintoverlap_entry, 1, 1, 1, 1)
# Margin
l7 = Gtk.Label('Margin:', xalign=1)
l7.set_tooltip_markup(
"Distance by which to avoid\n"
"the edges of the polygon to\n"
"be painted."
)
grid2.attach(l7, 0, 2, 1, 1)
self.paintmargin_entry = LengthEntry()
grid2.attach(self.paintmargin_entry, 1, 2, 1, 1)
# GO Button
self.generate_paint_button = Gtk.Button(label='Generate')
self.generate_paint_button.set_tooltip_markup(
"After clicking here, click inside\n"
"the polygon you wish to be painted.\n"
"A new Geometry object with the tool\n"
"paths will be created."
)
self.custom_box.pack_start(self.generate_paint_button, expand=True, fill=False, padding=2)
class ExcellonObjectUI(ObjectUI):
"""
User interface for Excellon objects.
"""
def __init__(self):
ObjectUI.__init__(self, title='Excellon Object', icon_file='share/drill32.png')
## Plot options
self.plot_options_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.plot_options_label.set_markup("<b>Plot Options:</b>")
self.custom_box.pack_start(self.plot_options_label, expand=False, fill=True, padding=2)
grid0 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid0, expand=True, fill=False, padding=2)
self.plot_cb = FCCheckBox(label='Plot')
self.plot_cb.set_tooltip_markup(
"Plot (show) this object."
)
grid0.attach(self.plot_cb, 0, 0, 1, 1)
self.solid_cb = FCCheckBox(label='Solid')
self.solid_cb.set_tooltip_markup(
"Solid circles."
)
grid0.attach(self.solid_cb, 1, 0, 1, 1)
## Create CNC Job
self.cncjob_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.cncjob_label.set_markup('<b>Create CNC Job</b>')
self.cncjob_label.set_tooltip_markup(
"Create a CNC Job object\n"
"for this drill object."
)
self.custom_box.pack_start(self.cncjob_label, expand=True, fill=False, padding=2)
grid1 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid1, expand=True, fill=False, padding=2)
l1 = Gtk.Label('Cut Z:', xalign=1)
l1.set_tooltip_markup(
"Drill depth (negative)\n"
"below the copper surface."
)
grid1.attach(l1, 0, 0, 1, 1)
self.cutz_entry = LengthEntry()
grid1.attach(self.cutz_entry, 1, 0, 1, 1)
l2 = Gtk.Label('Travel Z:', xalign=1)
l2.set_tooltip_markup(
"Tool height when travelling\n"
"across the XY plane."
)
grid1.attach(l2, 0, 1, 1, 1)
self.travelz_entry = LengthEntry()
grid1.attach(self.travelz_entry, 1, 1, 1, 1)
l3 = Gtk.Label('Feed rate:', xalign=1)
l3.set_tooltip_markup(
"Tool speed while drilling\n"
"(in units per minute)."
)
grid1.attach(l3, 0, 2, 1, 1)
self.feedrate_entry = LengthEntry()
grid1.attach(self.feedrate_entry, 1, 2, 1, 1)
l4 = Gtk.Label('Tools:', xalign=1)
l4.set_tooltip_markup(
"Which tools to include\n"
"in the CNC Job."
)
grid1.attach(l4, 0, 3, 1, 1)
boxt = Gtk.Box()
grid1.attach(boxt, 1, 3, 1, 1)
self.tools_entry = FCEntry()
boxt.pack_start(self.tools_entry, expand=True, fill=False, padding=2)
self.choose_tools_button = Gtk.Button(label='Choose...')
self.choose_tools_button.set_tooltip_markup(
"Choose the tools\n"
"from a list."
)
boxt.pack_start(self.choose_tools_button, expand=True, fill=False, padding=2)
self.generate_cnc_button = Gtk.Button(label='Generate')
self.generate_cnc_button.set_tooltip_markup(
"Generate the CNC Job."
)
self.custom_box.pack_start(self.generate_cnc_button, expand=True, fill=False, padding=2)
class GerberObjectUI(ObjectUI):
"""
User interface for Gerber objects.
"""
def __init__(self):
ObjectUI.__init__(self, title='Gerber Object')
## Plot options
self.plot_options_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.plot_options_label.set_markup("<b>Plot Options:</b>")
self.custom_box.pack_start(self.plot_options_label, expand=False, fill=True, padding=2)
grid0 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid0, expand=True, fill=False, padding=2)
# Plot CB
self.plot_cb = FCCheckBox(label='Plot')
self.plot_cb.set_tooltip_markup(
"Plot (show) this object."
)
grid0.attach(self.plot_cb, 0, 0, 1, 1)
# Solid CB
self.solid_cb = FCCheckBox(label='Solid')
self.solid_cb.set_tooltip_markup(
"Solid color polygons."
)
grid0.attach(self.solid_cb, 1, 0, 1, 1)
# Multicolored CB
self.multicolored_cb = FCCheckBox(label='Multicolored')
self.multicolored_cb.set_tooltip_markup(
"Draw polygons in different colors."
)
grid0.attach(self.multicolored_cb, 2, 0, 1, 1)
## Isolation Routing
self.isolation_routing_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.isolation_routing_label.set_markup("<b>Isolation Routing:</b>")
self.isolation_routing_label.set_tooltip_markup(
"Create a Geometry object with\n"
"toolpaths to cut outside polygons."
)
self.custom_box.pack_start(self.isolation_routing_label, expand=True, fill=False, padding=2)
grid = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid, expand=True, fill=False, padding=2)
l1 = Gtk.Label('Tool diam:', xalign=1)
l1.set_tooltip_markup(
"Diameter of the cutting tool."
)
grid.attach(l1, 0, 0, 1, 1)
self.iso_tool_dia_entry = LengthEntry()
grid.attach(self.iso_tool_dia_entry, 1, 0, 1, 1)
l2 = Gtk.Label('Width (# passes):', xalign=1)
l2.set_tooltip_markup(
"Width of the isolation gap in\n"
"number (integer) of tool widths."
)
grid.attach(l2, 0, 1, 1, 1)
self.iso_width_entry = IntEntry()
grid.attach(self.iso_width_entry, 1, 1, 1, 1)
l3 = Gtk.Label('Pass overlap:', xalign=1)
l3.set_tooltip_markup(
"How much (fraction of tool width)\n"
"to overlap each pass."
)
grid.attach(l3, 0, 2, 1, 1)
self.iso_overlap_entry = FloatEntry()
grid.attach(self.iso_overlap_entry, 1, 2, 1, 1)
self.generate_iso_button = Gtk.Button(label='Generate Geometry')
self.generate_iso_button.set_tooltip_markup(
"Create the Geometry Object\n"
"for isolation routing."
)
self.custom_box.pack_start(self.generate_iso_button, expand=True, fill=False, padding=2)
## Board cuttout
self.board_cutout_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.board_cutout_label.set_markup("<b>Board cutout:</b>")
self.board_cutout_label.set_tooltip_markup(
"Create toolpaths to cut around\n"
"the PCB and separate it from\n"
"the original board."
)
self.custom_box.pack_start(self.board_cutout_label, expand=True, fill=False, padding=2)
grid2 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid2, expand=True, fill=False, padding=2)
l4 = Gtk.Label('Tool dia:', xalign=1)
l4.set_tooltip_markup(
"Diameter of the cutting tool."
)
grid2.attach(l4, 0, 0, 1, 1)
self.cutout_tooldia_entry = LengthEntry()
grid2.attach(self.cutout_tooldia_entry, 1, 0, 1, 1)
l5 = Gtk.Label('Margin:', xalign=1)
l5.set_tooltip_markup(
"Distance from objects at which\n"
"to draw the cutout."
)
grid2.attach(l5, 0, 1, 1, 1)
self.cutout_margin_entry = LengthEntry()
grid2.attach(self.cutout_margin_entry, 1, 1, 1, 1)
l6 = Gtk.Label('Gap size:', xalign=1)
l6.set_tooltip_markup(
"Size of the gaps in the toolpath\n"
"that will remain to hold the\n"
"board in place."
)
grid2.attach(l6, 0, 2, 1, 1)
self.cutout_gap_entry = LengthEntry()
grid2.attach(self.cutout_gap_entry, 1, 2, 1, 1)
l7 = Gtk.Label('Gaps:', xalign=1)
l7.set_tooltip_markup(
"Where to place the gaps, Top/Bottom\n"
"Left/Rigt, or on all 4 sides."
)
grid2.attach(l7, 0, 3, 1, 1)
self.gaps_radio = RadioSet([{'label': '2 (T/B)', 'value': 'tb'},
{'label': '2 (L/R)', 'value': 'lr'},
{'label': '4', 'value': '4'}])
grid2.attach(self.gaps_radio, 1, 3, 1, 1)
self.generate_cutout_button = Gtk.Button(label='Generate Geometry')
self.generate_cutout_button.set_tooltip_markup(
"Generate the geometry for\n"
"the board cutout."
)
self.custom_box.pack_start(self.generate_cutout_button, expand=True, fill=False, padding=2)
## Non-copper regions
self.noncopper_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.noncopper_label.set_markup("<b>Non-copper regions:</b>")
self.noncopper_label.set_tooltip_markup(
"Create polygons covering the\n"
"areas without copper on the PCB.\n"
"Equivalent to the inverse of this\n"
"object. Can be used to remove all\n"
"copper from a specified region."
)
self.custom_box.pack_start(self.noncopper_label, expand=True, fill=False, padding=2)
grid3 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid3, expand=True, fill=False, padding=2)
l8 = Gtk.Label('Boundary margin:', xalign=1)
l8.set_tooltip_markup(
"Specify the edge of the PCB\n"
"by drawing a box around all\n"
"objects with this minimum\n"
"distance."
)
grid3.attach(l8, 0, 0, 1, 1)
self.noncopper_margin_entry = LengthEntry()
grid3.attach(self.noncopper_margin_entry, 1, 0, 1, 1)
self.noncopper_rounded_cb = FCCheckBox(label="Rounded corners")
self.noncopper_rounded_cb.set_tooltip_markup(
"If the boundary of the board\n"
"is to have rounded corners\n"
"their radius is equal to the margin."
)
grid3.attach(self.noncopper_rounded_cb, 0, 1, 2, 1)
self.generate_noncopper_button = Gtk.Button(label='Generate Geometry')
self.generate_noncopper_button.set_tooltip_markup(
"Creates a Geometry objects with polygons\n"
"covering the copper-free areas of the PCB."
)
self.custom_box.pack_start(self.generate_noncopper_button, expand=True, fill=False, padding=2)
## Bounding box
self.boundingbox_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
self.boundingbox_label.set_markup('<b>Bounding Box:</b>')
self.boundingbox_label.set_tooltip_markup(
"Create a Geometry object with a rectangle\n"
"enclosing all polygons at a given distance."
)
self.custom_box.pack_start(self.boundingbox_label, expand=True, fill=False, padding=2)
grid4 = Gtk.Grid(column_spacing=3, row_spacing=2)
self.custom_box.pack_start(grid4, expand=True, fill=False, padding=2)
l9 = Gtk.Label('Boundary Margin:', xalign=1)
l9.set_tooltip_markup(
"Distance of the edges of the box\n"
"to the nearest polygon."
)
grid4.attach(l9, 0, 0, 1, 1)
self.bbmargin_entry = LengthEntry()
grid4.attach(self.bbmargin_entry, 1, 0, 1, 1)
self.bbrounded_cb = FCCheckBox(label="Rounded corners")
self.bbrounded_cb.set_tooltip_markup(
"If the bounding box is \n"
"to have rounded corners\n"
"their radius is equal to\n"
"the margin."
)
grid4.attach(self.bbrounded_cb, 0, 1, 2, 1)
self.generate_bb_button = Gtk.Button(label='Generate Geometry')
self.generate_bb_button.set_tooltip_markup(
"Genrate the Geometry object."
)
self.custom_box.pack_start(self.generate_bb_button, expand=True, fill=False, padding=2)

View File

@@ -1,318 +0,0 @@
############################################################
# FlatCAM: 2D Post-processing for Manufacturing #
# http://caram.cl/software/flatcam #
# Author: Juan Pablo Caram (c) #
# Date: 2/5/2014 #
# MIT Licence #
############################################################
from gi.repository import Gdk
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
#from FlatCAMApp import *
from FlatCAM_GTK import FlatCAMApp
class PlotCanvas:
"""
Class handling the plotting area in the application.
"""
def __init__(self, container):
"""
The constructor configures the Matplotlib figure that
will contain all plots, creates the base axes and connects
events to the plotting area.
:param container: The parent container in which to draw plots.
:rtype: PlotCanvas
"""
# Options
self.x_margin = 15 # pixels
self.y_margin = 25 # Pixels
# Parent container
self.container = container
# Plots go onto a single matplotlib.figure
self.figure = Figure(dpi=50) # TODO: dpi needed?
self.figure.patch.set_visible(False)
# These axes show the ticks and grid. No plotting done here.
# New axes must have a label, otherwise mpl returns an existing one.
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.grid(True)
# The canvas is the top level container (Gtk.DrawingArea)
self.canvas = FigureCanvas(self.figure)
self.canvas.set_hexpand(1)
self.canvas.set_vexpand(1)
self.canvas.set_can_focus(True) # For key press
# Attach to parent
self.container.attach(self.canvas, 0, 0, 600, 400) # TODO: Height and width are num. columns??
# Events
self.canvas.mpl_connect('motion_notify_event', self.on_mouse_move)
self.canvas.connect('configure-event', self.auto_adjust_axes)
self.canvas.add_events(Gdk.EventMask.SMOOTH_SCROLL_MASK)
self.canvas.connect("scroll-event", self.on_scroll)
self.canvas.mpl_connect('key_press_event', self.on_key_down)
self.canvas.mpl_connect('key_release_event', self.on_key_up)
self.mouse = [0, 0]
self.key = None
def on_key_down(self, event):
"""
:param event:
:return:
"""
self.key = event.key
def on_key_up(self, event):
"""
:param event:
:return:
"""
self.key = None
def mpl_connect(self, event_name, callback):
"""
Attach an event handler to the canvas through the Matplotlib interface.
:param event_name: Name of the event
:type event_name: str
:param callback: Function to call
:type callback: func
:return: Connection id
:rtype: int
"""
return self.canvas.mpl_connect(event_name, callback)
def mpl_disconnect(self, cid):
"""
Disconnect callback with the give id.
:param cid: Callback id.
:return: None
"""
self.canvas.mpl_disconnect(cid)
def connect(self, event_name, callback):
"""
Attach an event handler to the canvas through the native GTK interface.
:param event_name: Name of the event
:type event_name: str
:param callback: Function to call
:type callback: function
:return: Nothing
"""
self.canvas.connect(event_name, callback)
def clear(self):
"""
Clears axes and figure.
:return: None
"""
# Clear
self.axes.cla()
try:
self.figure.clf()
except KeyError:
FlatCAMApp.App.log.warning("KeyError in MPL figure.clf()")
# Re-build
self.figure.add_axes(self.axes)
self.axes.set_aspect(1)
self.axes.grid(True)
# Re-draw
self.canvas.queue_draw()
def adjust_axes(self, xmin, ymin, xmax, ymax):
"""
Adjusts all axes while maintaining the use of the whole canvas
and an aspect ratio to 1:1 between x and y axes. The parameters are an original
request that will be modified to fit these restrictions.
:param xmin: Requested minimum value for the X axis.
:type xmin: float
:param ymin: Requested minimum value for the Y axis.
:type ymin: float
:param xmax: Requested maximum value for the X axis.
:type xmax: float
:param ymax: Requested maximum value for the Y axis.
:type ymax: float
:return: None
"""
FlatCAMApp.App.log.debug("PC.adjust_axes()")
width = xmax - xmin
height = ymax - ymin
try:
r = width / height
except ZeroDivisionError:
FlatCAMApp.App.log.error("Height is %f" % height)
return
canvas_w, canvas_h = self.canvas.get_width_height()
canvas_r = float(canvas_w) / canvas_h
x_ratio = float(self.x_margin) / canvas_w
y_ratio = float(self.y_margin) / canvas_h
if r > canvas_r:
ycenter = (ymin + ymax) / 2.0
newheight = height * r / canvas_r
ymin = ycenter - newheight / 2.0
ymax = ycenter + newheight / 2.0
else:
xcenter = (xmax + xmin) / 2.0
newwidth = width * canvas_r / r
xmin = xcenter - newwidth / 2.0
xmax = xcenter + newwidth / 2.0
# Adjust axes
for ax in self.figure.get_axes():
if ax._label != 'base':
ax.set_frame_on(False) # No frame
ax.set_xticks([]) # No tick
ax.set_yticks([]) # No ticks
ax.patch.set_visible(False) # No background
ax.set_aspect(1)
ax.set_xlim((xmin, xmax))
ax.set_ylim((ymin, ymax))
ax.set_position([x_ratio, y_ratio, 1 - 2 * x_ratio, 1 - 2 * y_ratio])
# Re-draw
self.canvas.queue_draw()
def auto_adjust_axes(self, *args):
"""
Calls ``adjust_axes()`` using the extents of the base axes.
:rtype : None
:return: None
"""
xmin, xmax = self.axes.get_xlim()
ymin, ymax = self.axes.get_ylim()
self.adjust_axes(xmin, ymin, xmax, ymax)
def zoom(self, factor, center=None):
"""
Zooms the plot by factor around a given
center point. Takes care of re-drawing.
:param factor: Number by which to scale the plot.
:type factor: float
:param center: Coordinates [x, y] of the point around which to scale the plot.
:type center: list
:return: None
"""
xmin, xmax = self.axes.get_xlim()
ymin, ymax = self.axes.get_ylim()
width = xmax - xmin
height = ymax - ymin
if center is None or center == [None, None]:
center = [(xmin + xmax) / 2.0, (ymin + ymax) / 2.0]
# For keeping the point at the pointer location
relx = (xmax - center[0]) / width
rely = (ymax - center[1]) / height
new_width = width / factor
new_height = height / factor
xmin = center[0] - new_width * (1 - relx)
xmax = center[0] + new_width * relx
ymin = center[1] - new_height * (1 - rely)
ymax = center[1] + new_height * rely
# Adjust axes
for ax in self.figure.get_axes():
ax.set_xlim((xmin, xmax))
ax.set_ylim((ymin, ymax))
# Re-draw
self.canvas.queue_draw()
def pan(self, x, y):
xmin, xmax = self.axes.get_xlim()
ymin, ymax = self.axes.get_ylim()
width = xmax - xmin
height = ymax - ymin
# Adjust axes
for ax in self.figure.get_axes():
ax.set_xlim((xmin + x*width, xmax + x*width))
ax.set_ylim((ymin + y*height, ymax + y*height))
# Re-draw
self.canvas.queue_draw()
def new_axes(self, name):
"""
Creates and returns an Axes object attached to this object's Figure.
:param name: Unique label for the axes.
:return: Axes attached to the figure.
:rtype: Axes
"""
return self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label=name)
def on_scroll(self, canvas, event):
"""
Scroll event handler.
:param canvas: The widget generating the event. Ignored.
:param event: Event object containing the event information.
:return: None
"""
# So it can receive key presses
self.canvas.grab_focus()
# Event info
z, direction = event.get_scroll_direction()
if self.key is None:
if direction is Gdk.ScrollDirection.UP:
self.zoom(1.5, self.mouse)
else:
self.zoom(1/1.5, self.mouse)
return
if self.key == 'shift':
if direction is Gdk.ScrollDirection.UP:
self.pan(0.3, 0)
else:
self.pan(-0.3, 0)
return
if self.key == 'ctrl+control':
if direction is Gdk.ScrollDirection.UP:
self.pan(0, 0.3)
else:
self.pan(0, -0.3)
return
def on_mouse_move(self, event):
"""
Mouse movement event hadler. Stores the coordinates.
:param event: Contains information about the event.
:return: None
"""
self.mouse = [event.xdata, event.ydata]

View File

@@ -1,13 +0,0 @@
#!/bin/sh
apt-get install libpng-dev
apt-get install libfreetype6 libfreetype6-dev
apt-get install python-dev
apt-get install python-gi
apt-get install libgtk-3-devel
apt-get install python-numpy python-scipy python-matplotlib
apt-get install libgeos-dev
apt-get install python-shapely
easy_install -U distribute
apt-get install python-pip
pip install --upgrade matplotlib
pip install --upgrade Shapely