From 36ff2bf354d4ee02728565d3e151daf4abbc739f Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 01/13] replace fc and browser_model instances Creating objects as a side effect of importing a module creates a new object each time and can lead to unexpected behaviour. Remove attempted workaround. --- fract4d/browser_model.py | 2 -- fract4d/cache.py | 1 - fract4d/fc.py | 3 --- fract4d/test_fc.py | 3 ++- fract4dgui/browser.py | 2 +- fract4dgui/main_window.py | 3 ++- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/fract4d/browser_model.py b/fract4d/browser_model.py index aec6c7eed..e017e2806 100644 --- a/fract4d/browser_model.py +++ b/fract4d/browser_model.py @@ -157,5 +157,3 @@ def get_contents(self): r = self.compiler.get_text(fname) return r - -instance = T(fc.instance) diff --git a/fract4d/cache.py b/fract4d/cache.py index 80c3a8e91..9ac82f21d 100644 --- a/fract4d/cache.py +++ b/fract4d/cache.py @@ -33,7 +33,6 @@ def save(self): self.createPickledFile(self._indexName(), self.files) def clear(self): - if not os: return # get 'NoneType not callable' sometimes otherwise, which seems weird for f in os.listdir(self.dir): try: os.remove(os.path.join(self.dir,f)) diff --git a/fract4d/fc.py b/fract4d/fc.py index 5db95a807..68a43e490 100755 --- a/fract4d/fc.py +++ b/fract4d/fc.py @@ -493,9 +493,6 @@ def __del__(self): if not self.leave_dirty: self.clear_cache() -instance = Compiler() -instance.update_from_prefs(fractconfig.instance) - def usage(): print("FC : a compiler from Fractint .frm files to C code") print("fc.py -o [outfile] -f [formula] infile") diff --git a/fract4d/test_fc.py b/fract4d/test_fc.py index 9d1d1bfa3..149e09747 100755 --- a/fract4d/test_fc.py +++ b/fract4d/test_fc.py @@ -247,7 +247,8 @@ def testPrefs(self): self.assertEqual(["wibble"], compiler.path_lists[3]) def testInstance(self): - compiler = fc.instance + compiler = fc.Compiler() + compiler.update_from_prefs(fractconfig.instance) self.assertNotEqual(None, compiler) self.assertEqual( compiler.flags, fractconfig.instance.get("compiler", "options")) diff --git a/fract4dgui/browser.py b/fract4dgui/browser.py index 0b362982d..b895aa655 100755 --- a/fract4dgui/browser.py +++ b/fract4dgui/browser.py @@ -38,7 +38,7 @@ def __init__(self,main_window,f): self.set_default_response(Gtk.ResponseType.OK) - self.model = browser_model.instance + self.model = browser_model.T(main_window.compiler) self.model.type_changed += self.on_type_changed self.model.file_changed += self.on_file_changed self.model.formula_changed += self.on_formula_changed diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index 7061c1ec2..8950c1566 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -66,7 +66,8 @@ def __init__(self, extra_paths=[]): # create fractal compiler and load standard formula and # coloring algorithm files - self.compiler = fc.instance + self.compiler = fc.Compiler() + self.compiler.update_from_prefs(fractconfig.instance) for path in extra_paths: self.compiler.add_func_path(path) From 25d1434f4582fda6527bdd4c5392d11f5f0a5142 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 02/13] convert SettingsDialog to SettingsPane Simplify the layout using Gtk.Paned and reduce the number of Gtk.Boxes. Allows user to expand the settings. --- fract4dgui/dialog.py | 9 ++++----- fract4dgui/main_window.py | 22 ++++++++++++---------- fract4dgui/settings.py | 30 +++++++++++------------------- fract4dgui/test_settings.py | 2 +- 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/fract4dgui/dialog.py b/fract4dgui/dialog.py index b5f649768..64deef70a 100644 --- a/fract4dgui/dialog.py +++ b/fract4dgui/dialog.py @@ -4,18 +4,17 @@ _dialogs = {} -def make_container(title): +def make_label_box(parent, title): label_box = Gtk.HBox() label_box.set_name('dialog_label_box') label = Gtk.Label(label=title) label_box.pack_start(label, False, False, 0) close = Gtk.Button.new_from_stock(Gtk.STOCK_CLOSE) label_box.pack_end(close, False, False, 0) - frame = Gtk.VBox() - frame.pack_start(label_box, False, False, 1) + label_box.show_all() - close.connect('clicked', lambda x : frame.hide()) - return frame + close.connect('clicked', lambda x : parent.hide()) + return label_box class T(Gtk.Dialog): def __init__(self, title=None, parent=None, buttons=None,**kwds): diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index 8950c1566..a751bf5b3 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -103,16 +103,24 @@ def __init__(self, extra_paths=[]): self.create_ui() self.create_toolbar() - self.create_fractal(self.f) + self.panes = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL) + self.vbox.add(self.panes) self.create_status_bar() + self.create_fractal(self.f) + self.panes.pack1(self.swindow, resize=True, shrink=True) + + # show everything apart from the settings pane + self.window.show_all() + + self.settingsPane = settings.SettingsPane(self, self.f) + self.panes.pack2(self.settingsPane, resize=False, shrink=False) + # create these properly later to avoid 'end from FAM server connection' messages self.saveas_fs = None self.saveimage_fs = None self.hires_image_fs = None self.open_fs = None - - self.window.show_all() self.update_subfract_visibility(False) self.populate_warpmenu(self.f) @@ -384,12 +392,6 @@ def create_fractal(self,f): f.connect('status_changed',self.status_changed) f.connect('stats-changed', self.stats_changed) - hbox = Gtk.HBox() - hbox.pack_start(self.swindow, True, True, 0) - self.control_box = Gtk.VBox() - hbox.pack_start(self.control_box, False, False, 0) - self.vbox.pack_start(hbox, True, True, 0) - def draw(self): nt = preferences.userPrefs.getint("general","threads") self.f.set_nthreads(nt) @@ -1216,7 +1218,7 @@ def save_image_file(self,filename): def settings(self,*args): """Show fractal settings controls.""" - settings.show_settings(self.window, self.control_box, self.f, False) + self.settingsPane.show() def preferences(self,*args): """Change current preferences.""" diff --git a/fract4dgui/settings.py b/fract4dgui/settings.py index ab9ed4453..6d17a3e0a 100644 --- a/fract4dgui/settings.py +++ b/fract4dgui/settings.py @@ -14,30 +14,20 @@ from fract4d import browser_model from fract4d.fc import FormulaTypes -def show_settings(parent,alt_parent, f,dialog_mode): - SettingsDialog.show(parent,alt_parent, f,dialog_mode) - -class SettingsDialog(dialog.T): - def show(parent, alt_parent, f,dialog_mode): - dialog.T.reveal(SettingsDialog,dialog_mode, parent, alt_parent, f) - - show = staticmethod(show) - +class SettingsPane(Gtk.Box): def __init__(self, main_window, f): - dialog.T.__init__( - self, - _("Fractal Settings"), - main_window, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True) + Gtk.Box.__init__(self) + self.set_orientation(Gtk.Orientation.VERTICAL) self.main_window = main_window self.f = f + + label_box = dialog.make_label_box(self, _("Fractal Settings")) self.notebook = Gtk.Notebook() self.notebook.set_name("settings_notebook") - self.controls = Gtk.VBox() - self.controls.pack_start(self.notebook, True, True, 0) - self.vbox.pack_start(self.controls, True, True, 0) + self.pack_start(label_box, False, False, 0) + self.pack_start(self.notebook, True, True, 0) + self.tables = [None,None,None,None] self.selected_transform = None @@ -49,6 +39,8 @@ def __init__(self, main_window, f): self.create_location_page() self.create_colors_page() + self.notebook.show_all() + def gradarea_mousedown(self, widget, event): pass @@ -549,7 +541,7 @@ def show_error_message(self,message,exception=None): d = hig.ErrorAlert( primary=message, secondary=secondary_message, - parent=self.main_window) + parent=self.main_window.window) d.run() d.destroy() diff --git a/fract4dgui/test_settings.py b/fract4dgui/test_settings.py index abc680141..9778c7da4 100755 --- a/fract4dgui/test_settings.py +++ b/fract4dgui/test_settings.py @@ -29,7 +29,7 @@ def setUp(self): self.compiler.add_func_path("../fract4d") self.f = gtkfractal.T(self.compiler) - self.settings = settings.SettingsDialog(None,self.f) + self.settings = settings.SettingsPane(None,self.f) def tearDown(self): pass From 81e29738a56dec65d8a22cc93eb67518697a1352 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 03/13] ensure we are using dialog objects that go cleanly out of scope Fix strange behaviour from partially initialised dialogs by replacing global management code with straightforward use of objects. --- fract4dgui/autozoom.py | 13 +++------ fract4dgui/dialog.py | 48 +++++----------------------------- fract4dgui/main_window.py | 8 ++++-- fract4dgui/preferences.py | 16 ++++-------- fract4dgui/test_main_window.py | 2 -- 5 files changed, 20 insertions(+), 67 deletions(-) diff --git a/fract4dgui/autozoom.py b/fract4dgui/autozoom.py index 2cd9e9e90..86a67046f 100644 --- a/fract4dgui/autozoom.py +++ b/fract4dgui/autozoom.py @@ -7,17 +7,13 @@ from . import dialog -def show_autozoom(parent,f): - AutozoomDialog.show(parent,f) - class AutozoomDialog(dialog.T): def __init__(self,main_window,f): dialog.T.__init__( self, _("Autozoom"), main_window, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True + (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) ) self.f = f @@ -58,11 +54,8 @@ def change_entry(*args): self.table.attach(self.minsize_entry, 1,2,1,2, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 2, 2) - - def show(parent, f): - dialog.T.reveal(AutozoomDialog, True, parent, None, f) - - show = staticmethod(show) + + self.vbox.show_all() def onResponse(self,widget,id): self.zoombutton.set_active(False) diff --git a/fract4dgui/dialog.py b/fract4dgui/dialog.py index 64deef70a..676b46b43 100644 --- a/fract4dgui/dialog.py +++ b/fract4dgui/dialog.py @@ -2,8 +2,6 @@ from gi.repository import Gtk -_dialogs = {} - def make_label_box(parent, title): label_box = Gtk.HBox() label_box.set_name('dialog_label_box') @@ -17,8 +15,12 @@ def make_label_box(parent, title): return label_box class T(Gtk.Dialog): - def __init__(self, title=None, parent=None, buttons=None,**kwds): - Gtk.Dialog.__init__(self, title=title, transient_for=parent, **kwds) + def __init__(self, title=None, parent=None, buttons=None, modal=True): + Gtk.Dialog.__init__(self, + title=title, + transient_for=parent, + modal=modal, + destroy_with_parent=True) if buttons: self.add_buttons(*buttons) @@ -26,40 +28,6 @@ def __init__(self, title=None, parent=None, buttons=None,**kwds): self.set_default_response(Gtk.ResponseType.CLOSE) self.connect('response',self.onResponse) - self.connect('destroy-event', self.clear_global) - self.connect('delete-event', self.clear_global) - - def clear_global(self,*args): - global _dialogs - _dialogs[self.__class__] = None - - def reveal(type, dialog_mode, parent, alt_parent, *args): - global _dialogs - if not _dialogs.get(type): - _dialogs[type] = type(parent, *args) - if dialog_mode: - _dialogs[type].show_all() - _dialogs[type].present() - else: - if not hasattr(alt_parent, "dialogs"): - alt_parent.dialogs = {} - container = alt_parent.dialogs.get(type) - if not container: - dialog = _dialogs[type] - box = dialog.controls - title = dialog.get_title() - container = make_container(title) - box.reparent(container) - alt_parent.pack_start(container,True,True,0) - alt_parent.dialogs[type] = container - - container.show_all() - _dialogs[type].hide() - - return _dialogs[type] - - reveal = staticmethod(reveal) - def onResponse(self,widget,id): if id == Gtk.ResponseType.CLOSE or \ id == Gtk.ResponseType.NONE or \ @@ -67,7 +35,3 @@ def onResponse(self,widget,id): self.hide() else: print("unexpected response %d" % id) - -def get(type): - global _dialogs - return _dialogs.get(type) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index a751bf5b3..005c0cfb1 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -1222,7 +1222,9 @@ def settings(self,*args): def preferences(self,*args): """Change current preferences.""" - preferences.show_preferences(self.window, self.f) + dialog = preferences.PrefsDialog(self.window, self.f) + dialog.run() + dialog.destroy() def undo(self,*args): """Undo the last operation.""" @@ -1272,7 +1274,9 @@ def set_wy_plane(self,*args): def autozoom(self,*args): """Display AutoZoom dialog.""" - autozoom.show_autozoom(self.window, self.f) + dialog = autozoom.AutozoomDialog(self.window, self.f) + dialog.run() + dialog.destroy() def contents(self,*args): """Show help file contents page.""" diff --git a/fract4dgui/preferences.py b/fract4dgui/preferences.py index 1702c0494..a6b8fbeee 100644 --- a/fract4dgui/preferences.py +++ b/fract4dgui/preferences.py @@ -67,10 +67,8 @@ def save(self): GObject.type_register(Preferences) userPrefs = Preferences(fractconfig.instance) - -def show_preferences(parent,f): - PrefsDialog.show(parent,f) - + + class PrefsDialog(dialog.T): def __init__(self,main_window,f): global userPrefs @@ -78,8 +76,8 @@ def __init__(self,main_window,f): self, _("Gnofract 4D Preferences"), main_window, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True) + (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) + ) self.dirchooser = utils.get_directory_chooser( _("Select a Formula Directory"), @@ -94,14 +92,10 @@ def __init__(self,main_window,f): self.create_compiler_options_page() self.create_general_page() self.create_helper_options_page() + self.vbox.show_all() self.set_size_request(500,-1) - def show(parent, f): - dialog.T.reveal(PrefsDialog, True, parent, None, f) - - show = staticmethod(show) - def show_error(self,message): d = Gtk.MessageDialog(self, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, diff --git a/fract4dgui/test_main_window.py b/fract4dgui/test_main_window.py index ad7579536..498c77dab 100755 --- a/fract4dgui/test_main_window.py +++ b/fract4dgui/test_main_window.py @@ -142,8 +142,6 @@ def testPreview(self): def testDialogs(self): self.mw.director(None,None) self.mw.settings(None,None) - self.mw.preferences(None,None) - self.mw.autozoom(None,None) self.mw.contents(None,None) self.mw.browser(None,None) self.mw.painter(None,None) From ff6585d8a8cd6986a8f9057e637125c9fd3aeaa4 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 04/13] use a PainterDialog object in MainWindow PainterDialog needs to be non-modal to allow the user to click on the fractal. --- fract4dgui/main_window.py | 4 +++- fract4dgui/painter.py | 12 ++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index 005c0cfb1..dedc76f91 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -137,6 +137,8 @@ def __init__(self, extra_paths=[]): self.f.set_saved(True) + self.painterDialog = painter.PainterDialog(self.window, self.f) + def create_rtd_widgets(self): table = Gtk.Table(n_rows=2,n_columns=3,homogeneous=False) table.width = width = Gtk.Entry() @@ -726,7 +728,7 @@ def randomize_colors(self,*args): self.f.make_random_colors(8) def painter(self,*args): - painter.show(self.window,self.f) + self.painterDialog.show() def add_to_queue(self,name,w,h): renderqueue.show(self.window,None,self.f) diff --git a/fract4dgui/painter.py b/fract4dgui/painter.py index a988946e2..5a9be5ef6 100644 --- a/fract4dgui/painter.py +++ b/fract4dgui/painter.py @@ -6,24 +6,16 @@ from . import browser from . import utils -def show(parent,f): - PainterDialog.show(parent,f) - class PainterDialog(dialog.T): - def show(parent, f): - dialog.T.reveal(PainterDialog, True, parent, None, f) - - show = staticmethod(show) - def __init__(self,main_window,f): dialog.T.__init__( self, _("Painter"), main_window, (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True) + modal=False + ) - self.main_window = main_window self.f = f self.paint_toggle = Gtk.ToggleButton(_("Painting")) self.paint_toggle.set_active(True) From 460d697295da0500d0edb280794016063b7f2b85 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 05/13] use renderqueue.QueueDialog and renderqueue.T objects in MainWindow --- fract4dgui/main_window.py | 13 ++++++++----- fract4dgui/renderqueue.py | 20 ++++---------------- fract4dgui/test_renderqueue.py | 5 +++-- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index dedc76f91..18f874549 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -120,7 +120,9 @@ def __init__(self, extra_paths=[]): self.saveas_fs = None self.saveimage_fs = None self.hires_image_fs = None - self.open_fs = None + self.open_fs = None + + self.renderQueue = renderqueue.T() self.update_subfract_visibility(False) self.populate_warpmenu(self.f) @@ -138,6 +140,7 @@ def __init__(self, extra_paths=[]): self.f.set_saved(True) self.painterDialog = painter.PainterDialog(self.window, self.f) + self.renderqueueDialog = renderqueue.QueueDialog(self.window, self.f, self.renderQueue) def create_rtd_widgets(self): table = Gtk.Table(n_rows=2,n_columns=3,homogeneous=False) @@ -731,9 +734,9 @@ def painter(self,*args): self.painterDialog.show() def add_to_queue(self,name,w,h): - renderqueue.show(self.window,None,self.f) - renderqueue.instance.add(self.f.f,name,w,h) - renderqueue.instance.start() + self.renderqueueDialog.show() + self.renderQueue.add(self.f.f,name,w,h) + self.renderQueue.start() def toggle_explorer(self, action): """Enter (or leave) Explorer mode.""" @@ -1398,7 +1401,7 @@ def check_save_fractal(self): elif response == hig.SaveConfirmationAlert.NOSAVE: break - while not renderqueue.instance.empty(): + while not self.renderQueue.empty(): d = hig.ConfirmationAlert( primary=_("Render queue still processing."), secondary=_("If you proceed, queued images will not be saved"), diff --git a/fract4dgui/renderqueue.py b/fract4dgui/renderqueue.py index 096926158..5b463db6e 100644 --- a/fract4dgui/renderqueue.py +++ b/fract4dgui/renderqueue.py @@ -78,34 +78,21 @@ def onProgressChanged(self,f,progress): # explain our existence to GTK's object system GObject.type_register(T) -def show(parent, alt_parent, f): - QueueDialog.show(parent, alt_parent, f) - -instance = T() - class CellRendererProgress(Gtk.CellRendererProgress): def __init__(self): Gtk.CellRendererProgress.__init__(self) self.set_property("text", "Progress") class QueueDialog(dialog.T): - def show(parent, alt_parent, f): - dialog.T.reveal(QueueDialog,True, parent, alt_parent, f) - - show = staticmethod(show) - - def __init__(self, main_window, f): + def __init__(self, main_window, f, renderQueue): dialog.T.__init__( self, _("Render Queue"), main_window, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True + (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) ) - self.main_window = main_window - - self.q = instance + self.q = renderQueue self.q.connect('changed', self.onQueueChanged) self.q.connect('progress-changed', self.onProgressChanged) @@ -130,6 +117,7 @@ def __init__(self, main_window, f): self.controls.add(self.view) self.vbox.add(self.controls) + self.vbox.show_all() def onQueueChanged(self,q): self.store.clear() diff --git a/fract4dgui/test_renderqueue.py b/fract4dgui/test_renderqueue.py index bc1147db2..343b3f2d8 100755 --- a/fract4dgui/test_renderqueue.py +++ b/fract4dgui/test_renderqueue.py @@ -66,13 +66,14 @@ def testRQ(self): def testQueueDialog(self): f = fractal.T(g_comp) - renderqueue.show(None,None,f) - rq = renderqueue.instance + rq = renderqueue.T() rq.add(f,"foo.png",124,276) rq.add(f,"foo2.png",204,153) rq.add(f,"foo3.png",80,40) rq.connect('done', self.quitloop) rq.start() + d = renderqueue.QueueDialog(None, f, rq) + d.show() self.wait() os.remove("foo.png"); os.remove("foo2.png"); os.remove("foo3.png") From ddca1e92f1482174056948fdb7401aa1aaa071e2 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 06/13] use BrowserDialog objects in MainWindow BrowserDialog objects are parentless to allow the user to reposition away from the fractal and see applied changes. Current formula and file are selected when the dialog is opened. A new dialog is created on each use. Converting to an object level dialog that is hidden between uses would require a review of the dialog and browser_model. --- fract4d/browser_model.py | 4 +-- fract4d/test_browser_model.py | 21 +++++++++---- fract4dgui/browser.py | 55 ++++++++++++++++------------------ fract4dgui/main_window.py | 15 +++++----- fract4dgui/settings.py | 4 ++- fract4dgui/test_browser.py | 40 +++++++++++++++---------- fract4dgui/test_main_window.py | 12 -------- 7 files changed, 78 insertions(+), 73 deletions(-) diff --git a/fract4d/browser_model.py b/fract4d/browser_model.py index e017e2806..167864cfd 100644 --- a/fract4d/browser_model.py +++ b/fract4d/browser_model.py @@ -99,12 +99,12 @@ def __init__(self,compiler): TypeInfo(self, compiler, fc.FormulaTypes.TRANSFORM), TypeInfo(self, compiler, fc.FormulaTypes.GRADIENT) ] + self.current = None self.current_type = -1 self.type_changed = event.T() self.file_changed = event.T() self.formula_changed = event.T() - self.set_type(FRACTAL) - + def formula_type_to_browser_type(self,t): if t == fc.FormulaTypes.FRACTAL: return FRACTAL diff --git a/fract4d/test_browser_model.py b/fract4d/test_browser_model.py index 495702f8f..5e015ffd1 100755 --- a/fract4d/test_browser_model.py +++ b/fract4d/test_browser_model.py @@ -65,7 +65,8 @@ def testFuncMapping(self): def testSetType(self): bm = Wrapper() - self.assertEqual([], bm.type_changelist) + bm.set_type(browser_model.FRACTAL) + self.assertEqual([browser_model.FRACTAL], bm.type_changelist) self.assertEqual(browser_model.FRACTAL, bm.current_type) self.assertEqual( bm.typeinfo[bm.current_type], bm.current) @@ -73,11 +74,12 @@ def testSetType(self): bm.set_type(browser_model.INNER) self.assertEqual(browser_model.INNER, bm.current_type) self.assertEqual( - [browser_model.INNER], + [browser_model.FRACTAL, browser_model.INNER], bm.type_changelist) def testFileList(self): bm = browser_model.T(g_comp) + bm.set_type(browser_model.FRACTAL) self.assertNotEqual(bm.current.files, []) self.assertListSorted(bm.current.files) @@ -91,6 +93,7 @@ def testSetTypeTwice(self): def testSetTypeUpdatesFnames(self): bm = browser_model.T(g_comp) + bm.set_type(browser_model.FRACTAL) bm.current.fname = "fish" bm.current.formula = "haddock" @@ -107,6 +110,7 @@ def testSetTypeUpdatesFnames(self): def testSetFile(self): bm = Wrapper() + bm.set_type(browser_model.FRACTAL) bm.set_file("gf4d.frm") self.assertEqual("gf4d.frm",bm.current.fname) self.assertEqual( @@ -116,6 +120,7 @@ def testSetFile(self): def testSetBadFile(self): bm = browser_model.T(g_comp) + bm.set_type(browser_model.FRACTAL) self.assertRaises(IOError,bm.set_file,"nonexistent.frm") def assertListSorted(self,l): @@ -126,6 +131,7 @@ def assertListSorted(self,l): def testFormulasSorted(self): bm = browser_model.T(g_comp) + bm.set_type(browser_model.FRACTAL) bm.set_file("gf4d.frm") self.assertListSorted(bm.current.formulas) @@ -141,6 +147,7 @@ def testExcludeList(self): def testSetFormula(self): bm = Wrapper() + bm.set_type(browser_model.FRACTAL) bm.set_file("gf4d.frm") bm.set_formula("Mandelbrot") self.assertEqual("Mandelbrot",bm.current.formula) @@ -149,6 +156,7 @@ def testSetFormula(self): def testSetFileResetsFormula(self): bm = Wrapper() + bm.set_type(browser_model.FRACTAL) bm.set_file("gf4d.frm") bm.set_formula("Mandelbrot") bm.set_file("fractint-g4.frm") @@ -158,7 +166,9 @@ def testSetFileResetsFormula(self): def testUpdate(self): bm = Wrapper() - bm.update("gf4d.frm","Mandelbrot") + bm.set_type(browser_model.FRACTAL) + bm.set_file("gf4d.frm") + bm.set_formula("Mandelbrot") self.assertEqual("gf4d.frm",bm.current.fname) self.assertEqual("Mandelbrot", bm.current.formula) @@ -172,6 +182,7 @@ def testUpdate(self): def testApplyStatus(self): bm = browser_model.T(g_comp) + bm.set_type(browser_model.FRACTAL) self.assertEqual(False, bm.current.can_apply) bm.set_file("gf4d.frm") @@ -198,9 +209,7 @@ def testUgrPresent(self): files = bm.current.files self.assertEqual(1,files.count("blatte1.ugr")) - def testInstance(self): - x = browser_model.instance - + def suite(): return unittest.makeSuite(Test,'test') diff --git a/fract4dgui/browser.py b/fract4dgui/browser.py index b895aa655..0e3c43417 100755 --- a/fract4dgui/browser.py +++ b/fract4dgui/browser.py @@ -2,39 +2,27 @@ # a browser to examine fractal functions -from gi.repository import Gtk +from gi.repository import Gtk, GObject from fract4d import browser_model from . import dialog, utils, gtkfractal -def show(parent, f, type=browser_model.FRACTAL): - BrowserDialog.show(parent,f,type) - -def update(file=None, formula=None): - browser_model.instance.update(file,formula) - -def set_type(type): - browser_model.instance.set_type(type) - -def guess_type(file): - return browser_model.instance.guess_type(file) - class BrowserDialog(dialog.T): RESPONSE_EDIT = 1 RESPONSE_REFRESH = 2 RESPONSE_COMPILE = 3 - def __init__(self,main_window,f): + def __init__(self,main_window,f,type=browser_model.FRACTAL): dialog.T.__init__( self, _("Formula Browser"), - main_window, + None, (#_("Co_mpile"), BrowserDialog.RESPONSE_COMPILE, Gtk.STOCK_REFRESH, BrowserDialog.RESPONSE_REFRESH, Gtk.STOCK_APPLY, Gtk.ResponseType.APPLY, Gtk.STOCK_OK, Gtk.ResponseType.OK, - Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True) + Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) + ) self.set_default_response(Gtk.ResponseType.OK) @@ -52,20 +40,14 @@ def __init__(self,main_window,f): self.compiler = f.compiler self.ir = None - self.main_window = main_window self.set_size_request(600,500) self.preview = gtkfractal.Preview(self.compiler) self.preview.f.auto_tolerance = False self.create_panes() - self.on_file_changed() + self.vbox.show_all() - def show(parent, f, type): - _browser = dialog.T.reveal(BrowserDialog,True, parent, None, f) - _browser.set_type(type) - _browser.populate_file_list() - - show = staticmethod(show) + self.set_type(type) def onResponse(self,widget,id): if id == Gtk.ResponseType.CLOSE or \ @@ -74,6 +56,8 @@ def onResponse(self,widget,id): self.hide() elif id == Gtk.ResponseType.APPLY: self.onApply() + # prevent dialog closing if being run + GObject.signal_stop_emission_by_name(self, "response") elif id == Gtk.ResponseType.OK: self.onApply() self.hide() @@ -100,6 +84,14 @@ def set_type_cb(self,optmenu): def on_type_changed(self): utils.set_selected(self.funcTypeMenu, self.model.current_type) + try: + self.set_file(self.f.forms[self.model.current_type].funcFile) + except IndexError: + pass + try: + self.set_formula(self.f.forms[self.model.current_type].funcName) + except IndexError: + pass self.populate_file_list() def set_type(self,type): @@ -154,10 +146,9 @@ def populate_file_list(self): # re-select current file, if any if current_iter: self.filetreeview.scroll_to_cell(index) - if sel: - sel.unselect_all() - sel.select_iter(current_iter) - self.populate_formula_list(self.model.current.fname) + sel.unselect_all() + sel.select_iter(current_iter) + self.populate_formula_list(self.model.current.fname) else: self.formula_list.clear() self.formula_selection_changed(None) @@ -284,6 +275,12 @@ def create_panes(self): panes1.add2(notebook) + def load_file(self, fname): + type = self.model.guess_type(fname) + self.set_type(type) + self.set_file(fname) + self.populate_file_list() + def file_selection_changed(self,selection): self.model.current.formula = None (model,iter) = selection.get_selected() diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index 18f874549..e201cbb2a 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -99,8 +99,6 @@ def __init__(self, extra_paths=[]): 'image-preferences-changed', self.on_prefs_changed) - browser.update(self.f.forms[0].funcFile, self.f.forms[0].funcName) - self.create_ui() self.create_toolbar() self.panes = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL) @@ -724,7 +722,9 @@ def director(self,*args): def browser(self,*args): """Display formula browser.""" - browser.show(self.window,self.f) + dialog = browser.BrowserDialog(self, self.f) + dialog.run() + dialog.destroy() def randomize_colors(self,*args): """Create a new random color scheme.""" @@ -1366,7 +1366,6 @@ def load(self,file): fh.close() self.update_recent_files(file) self.set_filename(file) - browser.update(self.f.forms[0].funcFile, self.f.forms[0].funcName) return True except Exception as err: self.show_error_message(_("Error opening %s") % file,err) @@ -1375,10 +1374,10 @@ def load(self,file): def load_formula(self,file): try: self.compiler.load_formula_file(file) - type = browser.guess_type(file) - browser.set_type(type) - browser.update(file) - browser.show(self.window, self.f, type) + dialog = browser.BrowserDialog(self, self.f) + dialog.load_file(file) + dialog.run() + dialog.destroy() return True except Exception as err: diff --git a/fract4dgui/settings.py b/fract4dgui/settings.py index 6d17a3e0a..9efc3756f 100644 --- a/fract4dgui/settings.py +++ b/fract4dgui/settings.py @@ -688,7 +688,9 @@ def update_all_widgets(self, fractal, container): self.update_all_widgets(fractal,widget) # recurse def show_browser(self,button,type): - browser.show(self.main_window, self.f, type) + dialog = browser.BrowserDialog(self.main_window, self.f, type) + dialog.run() + dialog.destroy() def create_param_entry(self,table, row, text, param): label = Gtk.Label(label=text) diff --git a/fract4dgui/test_browser.py b/fract4dgui/test_browser.py index 93a3f42ef..e5ae4231b 100755 --- a/fract4dgui/test_browser.py +++ b/fract4dgui/test_browser.py @@ -20,14 +20,17 @@ from fract4d import fc, fractal, browser_model from fract4dgui import browser +class MockMainWindow: + def __init__(self): + self.window = None + self.compiler = fc.Compiler() + self.compiler.add_func_path("../formulas") + self.compiler.add_func_path("../fract4d") class Test(unittest.TestCase): def setUp(self): - self.compiler = fc.instance - self.compiler.add_func_path("../formulas") - self.compiler.add_func_path("../fract4d") - - self.f = fractal.T(self.compiler,self) + self.mainWindow = MockMainWindow() + self.f = fractal.T(self.mainWindow.compiler,self) def tearDown(self): browser._model = None @@ -40,17 +43,17 @@ def quitloop(self,f,status): Gtk.main_quit() def testCreate(self): - b = browser.BrowserDialog(None,self.f) + b = browser.BrowserDialog(self.mainWindow, self.f) self.assertNotEqual(b,None) - def testLoadFormula(self): - b = browser.BrowserDialog(None,self.f) + def testSetFormula(self): + b = browser.BrowserDialog(self.mainWindow, self.f) b.set_file('gf4d.frm') b.set_formula('Newton') self.assertEqual(b.ir.errors,[]) def testBadFormula(self): - b = browser.BrowserDialog(None,self.f) + b = browser.BrowserDialog(self.mainWindow, self.f) #print b.model.compiler.path_lists[0] b.set_file('test.frm') b.set_formula('parse_error') @@ -63,13 +66,20 @@ def testBadFormula(self): self.assertNotEqual(all_text,"") self.assertEqual(all_text[0:7],"Errors:") - def test_update(self): - b = browser.BrowserDialog(None,self.f) - b = browser.update(None) - m = browser_model.instance - self.assertEqual(None, m.current.fname) - self.assertEqual(None, m.current.formula) + def test_init(self): + b = browser.BrowserDialog(self.mainWindow, self.f) + m = b.model + self.assertEqual('gf4d.frm', m.current.fname) + self.assertEqual('Mandelbrot', m.current.formula) + def testLoadFormula(self): + b = browser.BrowserDialog(self.mainWindow, self.f) + m = b.model + # load good formula file + b.load_file("../formulas/fractint.cfrm") + self.assertEqual('fractint.cfrm', m.current.fname, "failed to load formula") + #load missing file + self.assertRaises(OSError, b.load_file, "/no_such_dir/wibble.frm") def suite(): return unittest.makeSuite(Test,'test') diff --git a/fract4dgui/test_main_window.py b/fract4dgui/test_main_window.py index 498c77dab..cfe296834 100755 --- a/fract4dgui/test_main_window.py +++ b/fract4dgui/test_main_window.py @@ -116,17 +116,6 @@ def testSaveImage(self): finally: if os.path.exists("mygood.png"): os.remove("mygood.png") - - def testLoadFormula(self): - # load good formula file - result = self.mw.load_formula("../formulas/fractint.cfrm") - self.assertEqual(result, True, "failed to load formula") - - #load missing file - result = self.mw.load_formula("/no_such_dir/wibble.frm") - self.assertEqual(result, False, "load bad formula succeeded") - self.assertEqual( - self.mw.errors[0][0], "Error opening /no_such_dir/wibble.frm") def testPreview(self): 'Check for problem where preview differs from main image' @@ -143,7 +132,6 @@ def testDialogs(self): self.mw.director(None,None) self.mw.settings(None,None) self.mw.contents(None,None) - self.mw.browser(None,None) self.mw.painter(None,None) def testFileDialogs(self): From f7f9e638ade2284055be2fe741f11d069abb23f0 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 07/13] use DirectorDialog objects in MainWindow --- fract4dgui/director.py | 18 ++++-------------- fract4dgui/main_window.py | 4 +++- fract4dgui/test_director.py | 2 +- fract4dgui/test_main_window.py | 1 - 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/fract4dgui/director.py b/fract4dgui/director.py index 6b0999994..cb376be12 100644 --- a/fract4dgui/director.py +++ b/fract4dgui/director.py @@ -20,9 +20,6 @@ from . import PNGGen,AVIGen,DlgAdvOpt,director_prefs -def show(parent,alt_parent, f,dialog_mode,conf_file=""): - DirectorDialog.show(parent,alt_parent, f,dialog_mode,conf_file) - class UserCancelledError(Exception): pass @@ -33,11 +30,6 @@ def __init__(self,msg): class DirectorDialog(dialog.T,hig.MessagePopper): RESPONSE_RENDER=1 - def show(parent, alt_parent, f,dialog_mode,conf_file): - dialog.T.reveal(DirectorDialog, dialog_mode, - parent, alt_parent, f,conf_file) - - show = staticmethod(show) def check_for_keyframe_clash(self,keyframe,fct_dir): keydir=os.path.dirname(keyframe) @@ -445,22 +437,19 @@ def preferences_clicked(self,widget,data=None): res=dlg.show() #creating window... - def __init__(self, main_window, f,conf_file): + def __init__(self, main_window, f, conf_file=""): dialog.T.__init__( self, _("Director"), main_window, (_("_Render"), DirectorDialog.RESPONSE_RENDER, - Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE), - destroy_with_parent=True) + Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) + ) hig.MessagePopper.__init__(self) self.animation=animation.T(f.compiler) self.f=f self.compiler = f.compiler - self.realize() - - self.main_window = main_window #main VBox self.box_main=Gtk.VBox(False,0) @@ -706,6 +695,7 @@ def __init__(self, main_window, f,conf_file): #--------------showing all------------------------------- self.vbox.add(self.box_main) + self.vbox.show_all() self.controls = self.vbox if conf_file!="": self.load_configuration(conf_file) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index e201cbb2a..a7cc743f4 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -718,7 +718,9 @@ def create_ui(self): def director(self,*args): """Display the Director (animation) window.""" - director.show(self.window,self.control_box, self.f, True) + dialog = director.DirectorDialog(self.window, self.f) + dialog.run() + dialog.destroy() def browser(self,*args): """Display formula browser.""" diff --git a/fract4dgui/test_director.py b/fract4dgui/test_director.py index e0351e426..0a90606a2 100755 --- a/fract4dgui/test_director.py +++ b/fract4dgui/test_director.py @@ -47,7 +47,7 @@ def testDirectorDialog(self): f = fractal.T(g_comp) dd=director.DirectorDialog(None,f,"") - dd.show(None,None,f,True,"") + dd.show() dd.animation.set_png_dir("./") dd.animation.set_fct_enabled(False) dd.animation.add_keyframe("../testdata/director1.fct",1,10,animation.INT_LOG) diff --git a/fract4dgui/test_main_window.py b/fract4dgui/test_main_window.py index cfe296834..4cc1c139e 100755 --- a/fract4dgui/test_main_window.py +++ b/fract4dgui/test_main_window.py @@ -129,7 +129,6 @@ def testPreview(self): self.assertEqual(fct1, fct2) def testDialogs(self): - self.mw.director(None,None) self.mw.settings(None,None) self.mw.contents(None,None) self.mw.painter(None,None) From 10418947eddbcff9f85ef5eeb5325fc34e311b2b Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 08/13] fix angle and fourway issues by making them widgets Ensure they remain fully in scope after adding to the MainWindow toolbar. --- fract4dgui/angle.py | 43 +++++++++++++------------------------- fract4dgui/fourway.py | 35 +++++++++---------------------- fract4dgui/gtkfractal.py | 4 ++-- fract4dgui/main_window.py | 8 +++---- fract4dgui/test_fourway.py | 2 +- 5 files changed, 31 insertions(+), 61 deletions(-) diff --git a/fract4dgui/angle.py b/fract4dgui/angle.py index 24737d31b..46981ab56 100644 --- a/fract4dgui/angle.py +++ b/fract4dgui/angle.py @@ -1,14 +1,10 @@ -# Sort of a widget which controls an angle of the fractal -# I say sort of, because this doesn't actually inherit from Gtk.Widget, -# so it's not really a widget. This is because if I attempt to do that -# pygtk crashes. Hence I delegate to a member which actually is a widget -# with some stuff drawn on it - basically an ungodly hack. +# A widget which controls an angle of the fractal import math from gi.repository import Gtk, Gdk, GObject, Pango -class T(GObject.GObject): +class T(Gtk.DrawingArea): __gsignals__ = { 'value-changed' : ( (GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.NO_RECURSE), @@ -30,12 +26,11 @@ def __init__(self,text): self.adjustment.connect('value-changed', self.onAdjustmentValueChanged) - GObject.GObject.__init__(self) + Gtk.DrawingArea.__init__(self) - self.widget = Gtk.DrawingArea() - self.widget.set_size_request(40,40) + self.set_size_request(40,40) - self.widget.set_events( + self.set_events( Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.BUTTON1_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK | @@ -46,18 +41,18 @@ def __init__(self,text): ) self.notice_mouse = False - self.widget.connect('motion_notify_event', self.onMotionNotify) - self.widget.connect('button_release_event', self.onButtonRelease) - self.widget.connect('button_press_event', self.onButtonPress) - self.widget.connect('draw',self.onDraw) + self.connect('motion_notify_event', self.onMotionNotify) + self.connect('button_release_event', self.onButtonRelease) + self.connect('button_press_event', self.onButtonPress) + self.connect('draw',self.onDraw) def set_value(self,val): val = math.fmod(val + math.pi, 2.0 * math.pi) - math.pi self.adjustment.set_value(val) - self.widget.queue_draw() + self.queue_draw() def update_from_mouse(self,x,y): - (w,h) = (self.widget.get_allocated_width(), self.widget.get_allocated_height()) + (w,h) = (self.get_allocated_width(), self.get_allocated_height()) xc = w//2 yc = h//2 @@ -73,7 +68,7 @@ def angle_from_xy(self,x,y): def onAdjustmentValueChanged(self,adjustment): val = adjustment.get_value() if val != self.old_value: - self.widget.queue_draw() + self.queue_draw() self.emit('value-slightly-changed', val) def onMotionNotify(self,widget,event): @@ -91,21 +86,14 @@ def onButtonRelease(self,widget,event): self.old_value = current_value self.emit('value-changed',current_value) - self.widget.set_state(Gtk.StateType.NORMAL) + self.set_state(Gtk.StateType.NORMAL) def onButtonPress(self,widget,event): if event.button == 1: self.notice_mouse = True self.update_from_mouse(event.x, event.y) - self.widget.set_state(Gtk.StateType.ACTIVE) - - - def __del__(self): - #This is truly weird. If I don't have this method, when you use - # one fourway widget, it fucks up the other. Having this fixes it. - # *even though it doesn't do anything*. Disturbing. - pass + self.set_state(Gtk.StateType.ACTIVE) def get_current_angle(self): value = self.adjustment.get_value() @@ -164,6 +152,3 @@ def redraw_rect(self, widget, cairo_ctx): self.two_pi) cairo_ctx.fill() cairo_ctx.stroke() - -# explain our existence to GTK's object system -GObject.type_register(T) diff --git a/fract4dgui/fourway.py b/fract4dgui/fourway.py index 05c4c7962..419ae6d22 100644 --- a/fract4dgui/fourway.py +++ b/fract4dgui/fourway.py @@ -1,12 +1,8 @@ -# Sort of a widget which controls 2 linear dimensions of the fractal -# I say sort of, because this doesn't actually inherit from Gtk.Widget, -# so it's not really a widget. This is because if I attempt to do that -# pygtk crashes. Hence I delegate to a member which actually is a widget -# with some stuff drawn on it - basically an ungodly hack. +# A widget which controls 2 linear dimensions of the fractal from gi.repository import Gtk, Gdk, GObject, Pango -class T(GObject.GObject): +class T(Gtk.DrawingArea): __gsignals__ = { 'value-changed' : ( (GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.NO_RECURSE), @@ -22,12 +18,11 @@ def __init__(self,text): self.last_x = 0 self.last_y = 0 self.text=text - GObject.GObject.__init__(self) - - self.widget = Gtk.DrawingArea() - self.widget.set_size_request(53,53) + Gtk.DrawingArea.__init__(self) + + self.set_size_request(53,53) - self.widget.set_events( + self.set_events( Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.BUTTON1_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK | @@ -38,10 +33,10 @@ def __init__(self,text): ) self.notice_mouse = False - self.widget.connect('motion_notify_event', self.onMotionNotify) - self.widget.connect('button_release_event', self.onButtonRelease) - self.widget.connect('button_press_event', self.onButtonPress) - self.widget.connect('draw',self.onDraw) + self.connect('motion_notify_event', self.onMotionNotify) + self.connect('button_release_event', self.onButtonRelease) + self.connect('button_press_event', self.onButtonPress) + self.connect('draw',self.onDraw) def update_from_mouse(self,x,y): dx = self.last_x - x @@ -73,12 +68,6 @@ def onButtonPress(self,widget,event): self.last_y = widget.get_allocated_height()/2 self.update_from_mouse(event.x, event.y) - def __del__(self): - #This is truly weird. If I don't have this method, when you use - # one fourway widget, it fucks up the other. Having this fixes it. - # *even though it doesn't do anything*. Disturbing. - pass - def onDraw(self, widget, cairo_ctx): self.redraw_rect(widget, cairo_ctx) @@ -156,7 +145,3 @@ def triangle(points): xc - text_width//2, yc - text_height//2, layout) - - -# explain our existence to GTK's object system -GObject.type_register(T) diff --git a/fract4dgui/gtkfractal.py b/fract4dgui/gtkfractal.py index e95a219c5..e7c29d164 100644 --- a/fract4dgui/gtkfractal.py +++ b/fract4dgui/gtkfractal.py @@ -690,7 +690,7 @@ def add_complex_formula_setting( name = self.param_display_name(name,param) fway = fourway.T(name) tip = self.param_tip(name,param) - fway.widget.set_tooltip_text(tip) + fway.set_tooltip_text(tip) fway.connect('value-changed',self.fourway_released, order, form) @@ -699,7 +699,7 @@ def add_complex_formula_setting( 'value-slightly-changed', self.parent.on_drag_param_fourway, order, param_type) - table.attach(fway.widget,0,1,i,i+2, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL,0, 0,0) + table.attach(fway,0,1,i,i+2, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL,0, 0,0) def fourway_released(self,widget,x,y,order,form): form.nudge_param(order, x,y) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index a7cc743f4..15d2e827f 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -1002,12 +1002,12 @@ def create_angle_widget(self,name,tip,axis, is4dsensitive): my_angle.axis = axis self.toolbar.add_widget( - my_angle.widget, + my_angle, tip, tip) if is4dsensitive: - self.four_d_sensitives.append(my_angle.widget) + self.four_d_sensitives.append(my_angle) def update_angle_widget(self,f,widget): widget.set_value(f.get_param(widget.axis)) @@ -1074,7 +1074,7 @@ def update_warp_param(menu, f): def add_fourway(self, name, tip, axis, is4dsensitive): my_fourway = fourway.T(name) self.toolbar.add_widget( - my_fourway.widget, + my_fourway, tip, None) @@ -1084,7 +1084,7 @@ def add_fourway(self, name, tip, axis, is4dsensitive): my_fourway.connect('value-changed', self.on_release_fourway) if is4dsensitive: - self.four_d_sensitives.append(my_fourway.widget) + self.four_d_sensitives.append(my_fourway) def update_recent_files(self, file): self.recent_files = preferences.userPrefs.update_list("recent_files",file,4) diff --git a/fract4dgui/test_fourway.py b/fract4dgui/test_fourway.py index caccf3669..30693e5b7 100755 --- a/fract4dgui/test_fourway.py +++ b/fract4dgui/test_fourway.py @@ -38,7 +38,7 @@ def testCreate(self): def testAddToWindow(self): w = Gtk.Window() f = fourway.T("wibble") - w.add(f.widget) + w.add(f) w.show() Gtk.main_iteration() From 335c9bd24285e82071a1d59f39d7daba79eef0e0 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 09/13] Revert "[?] fix pan fourway not initialised properly" This reverts commit a89e39cb8a8990e12ef674f6ed3d24363ece0ef0. A workaround no longer needed now that fourway is a widget. --- fract4dgui/main_window.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index 15d2e827f..87a63a090 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -849,7 +849,7 @@ def create_toolbar(self): self.add_fourway( _("pan"), - _("Pan around the image"), 0, True) + _("Pan around the image"), 0, False) self.add_fourway( _("warp"), _("Mutate the image by moving along the other 2 axes"), 2, True) From a979a006957d3f4a48ca56c3b69589cdd002247b Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 10/13] tidy angle.py and fourway.py --- fract4dgui/angle.py | 9 +++------ fract4dgui/fourway.py | 33 +++++++++++++++------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/fract4dgui/angle.py b/fract4dgui/angle.py index 46981ab56..936913804 100644 --- a/fract4dgui/angle.py +++ b/fract4dgui/angle.py @@ -35,7 +35,7 @@ def __init__(self,text): Gdk.EventMask.BUTTON1_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK | Gdk.EventMask.ENTER_NOTIFY_MASK | - Gdk.EventMask.LEAVE_NOTIFY_MASK | + Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.EXPOSURE_MASK ) @@ -51,7 +51,7 @@ def set_value(self,val): self.adjustment.set_value(val) self.queue_draw() - def update_from_mouse(self,x,y): + def update_from_mouse(self,x,y): (w,h) = (self.get_allocated_width(), self.get_allocated_height()) xc = w//2 @@ -74,13 +74,11 @@ def onAdjustmentValueChanged(self,adjustment): def onMotionNotify(self,widget,event): if not self.notice_mouse: return - dummy = widget.get_pointer() self.update_from_mouse(event.x, event.y) def onButtonRelease(self,widget,event): - if event.button==1: + if event.button == 1: self.notice_mouse = False - (xc,yc) = (widget.get_allocated_width()//2, widget.get_allocated_height()//2) current_value = self.adjustment.get_value() if self.old_value != current_value: self.old_value = current_value @@ -88,7 +86,6 @@ def onButtonRelease(self,widget,event): self.set_state(Gtk.StateType.NORMAL) - def onButtonPress(self,widget,event): if event.button == 1: self.notice_mouse = True diff --git a/fract4dgui/fourway.py b/fract4dgui/fourway.py index 419ae6d22..1703968db 100644 --- a/fract4dgui/fourway.py +++ b/fract4dgui/fourway.py @@ -12,12 +12,12 @@ class T(Gtk.DrawingArea): None, (GObject.TYPE_INT, GObject.TYPE_INT)) } - def __init__(self,text): + def __init__(self,text): self.button = 0 self.radius = 0 self.last_x = 0 - self.last_y = 0 - self.text=text + self.last_y = 0 + self.text = text Gtk.DrawingArea.__init__(self) self.set_size_request(53,53) @@ -49,11 +49,10 @@ def update_from_mouse(self,x,y): def onMotionNotify(self,widget,event): if not self.notice_mouse: return - dummy = widget.get_pointer() self.update_from_mouse(event.x, event.y) def onButtonRelease(self,widget,event): - if event.button==1: + if event.button == 1: self.notice_mouse = False (xc,yc) = (widget.get_allocated_width()//2, widget.get_allocated_height()//2) dx = xc - self.last_x @@ -74,12 +73,10 @@ def onDraw(self, widget, cairo_ctx): def redraw_rect(self, widget, cairo_ctx): style_ctx = widget.get_style_context() (w,h) = (widget.get_allocated_width(), widget.get_allocated_height()) - Gtk.render_background(style_ctx, - cairo_ctx, 0, 0, w-1, h-1) + Gtk.render_background(style_ctx, cairo_ctx, 0, 0, w-1, h-1) xc = w//2 yc = h//2 - radius = min(w,h)//2 -1 # Consider using gtk_render_arrow def triangle(points): @@ -93,7 +90,7 @@ def triangle(points): th = 8 tw = 6 - # Triangle pointing left + # Triangle pointing left points = [ (1, yc), (1+th, yc-tw), @@ -102,23 +99,23 @@ def triangle(points): # pointing right points = [ - (w -2, yc), - (w -2 -th, yc-tw), - (w -2 -th, yc+tw)] + (w-2, yc), + (w-2-th, yc-tw), + (w-2-th, yc+tw)] triangle(points) # pointing up points = [ (xc, 1), - (xc - tw, th), - (xc + tw, th)] + (xc-tw, th), + (xc+tw, th)] triangle(points) # pointing down points = [ - (xc, h - 2), - (xc - tw, h - 2 - th), - (xc + tw, h - 2 - th)] + (xc, h-2), + (xc-tw, h-2-th), + (xc+tw, h-2-th)] triangle(points) pango_ctx = widget.get_pango_context() @@ -135,7 +132,7 @@ def triangle(points): (text_width, text_height) = layout.get_pixel_size() # truncate text if it's too long - if text_width < (w - th *2) or len(drawtext) < 3: + if text_width < (w-th*2) or len(drawtext) < 3: break drawtext = drawtext[:-1] From df703751c987cddc79c3d2637f7f99bb51b08188 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 11/13] add missing Gtk versions to test scripts --- fract4dgui/test_main_window.py | 4 ++++ fract4dgui/test_painter.py | 4 ++++ fract4dgui/test_preferences.py | 3 +++ 3 files changed, 11 insertions(+) diff --git a/fract4dgui/test_main_window.py b/fract4dgui/test_main_window.py index 4cc1c139e..b56f556ec 100755 --- a/fract4dgui/test_main_window.py +++ b/fract4dgui/test_main_window.py @@ -9,10 +9,14 @@ import sys import random +import gi +gi.require_version('Gtk', '3.0') from gi.repository import Gtk + import gettext os.environ.setdefault('LANG', 'en') gettext.install('gnofract4d') + if sys.path[1] != "..": sys.path.insert(1, "..") from fract4d import fractal diff --git a/fract4dgui/test_painter.py b/fract4dgui/test_painter.py index c9ee1790e..cf0fad35f 100755 --- a/fract4dgui/test_painter.py +++ b/fract4dgui/test_painter.py @@ -8,10 +8,14 @@ import os import sys +import gi +gi.require_version('Gtk', '3.0') from gi.repository import Gtk + import gettext os.environ.setdefault('LANG', 'en') gettext.install('gnofract4d') + if sys.path[1] != "..": sys.path.insert(1, "..") from fract4d import fc, fractal diff --git a/fract4dgui/test_preferences.py b/fract4dgui/test_preferences.py index 56d0391b2..26dd5cc64 100755 --- a/fract4dgui/test_preferences.py +++ b/fract4dgui/test_preferences.py @@ -6,6 +6,9 @@ import sys import os +import gi +gi.require_version('Gtk', '3.0') + if sys.path[1] != "..": sys.path.insert(1, "..") from fract4dgui import preferences from fract4d import fractconfig From d0308e5ae1c1b788dfba2ea4cc2ad382df126c77 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 12/13] tidy main_window.py --- fract4dgui/main_window.py | 143 +++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 79 deletions(-) diff --git a/fract4dgui/main_window.py b/fract4dgui/main_window.py index 87a63a090..d31d4d094 100644 --- a/fract4dgui/main_window.py +++ b/fract4dgui/main_window.py @@ -2,22 +2,18 @@ import sys import os -import signal -import copy import math import re -import urllib.request, urllib.parse, urllib.error from gi.repository import Gdk, Gtk -# If we haven't been installed (we're running from the dir we +# If we haven't been installed (we're running from the dir we # were unpacked in) this is where fract4d is. -from fract4d import fractal,fc,fract4dc,image, fracttypes, fractconfig - +from fract4d import fractal, fc, image, fracttypes, fractconfig from . import gtkfractal, model, preferences, autozoom, settings, toolbar -from . import undo, browser, fourway, angle, utils, hig, painter +from . import browser, fourway, angle, utils, hig, painter from . import icons, renderqueue, director re_ends_with_num = re.compile(r'\d+\Z') @@ -25,17 +21,15 @@ class MainWindow: def __init__(self, extra_paths=[]): - self.quit_when_done =False + self.quit_when_done = False self.save_filename = None self.compress_saves = True self.f = None self.use_preview = True self.four_d_sensitives = [] - # window widget - self.set_icon() - + # window widget self.window = Gtk.Window() self.window.set_default_size(900,700) self.window.connect('delete-event', self.quit) @@ -77,7 +71,7 @@ def __init__(self, extra_paths=[]): self.vbox = Gtk.VBox() self.window.add(self.vbox) - self.f = gtkfractal.T(self.compiler,self) + self.f = gtkfractal.T(self.compiler,self) self.f.freeze() # create frozen - main prog will thaw us self.create_subfracts(self.f) @@ -171,7 +165,7 @@ def create_rtd_widgets(self): 1, 2, 1, 2, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, - 1,1) + 1,1) return table def get_file_save_chooser(self, title, parent, patterns=[]): @@ -200,14 +194,14 @@ def get_filter(self,name,patterns): return filter def add_filters(self,chooser): - param_patterns = [ "*.fct" ] + param_patterns = ["*.fct"] param_filter = self.get_filter( _("Parameter Files"), param_patterns) chooser.add_filter(param_filter) formula_patterns = ["*.frm", "*.ufm", "*.ucl", "*.cfrm", "*.uxf"] - formula_filter = self.get_filter( + formula_filter = self.get_filter( _("Formula Files"), formula_patterns) chooser.add_filter(formula_filter) @@ -217,7 +211,7 @@ def add_filters(self,chooser): chooser.add_filter(gradient_filter) all_filter = self.get_filter( - _("All Gnofract 4D Files"), + _("All Gnofract 4D Files"), param_patterns + formula_patterns + gradient_patterns) chooser.add_filter(all_filter) @@ -227,7 +221,7 @@ def add_filters(self,chooser): def get_file_open_chooser(self, parent): chooser = Gtk.FileChooserDialog( title, parent, Gtk.FileChooserAction.OPEN, - (Gtk.STOCK_OK, Gtk.ResponseType.OK, + (Gtk.STOCK_OK, Gtk.ResponseType.OK, Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)) self.add_filters(chooser) @@ -235,7 +229,7 @@ def get_file_open_chooser(self, parent): return chooser def get_save_as_fs(self): - if self.saveas_fs == None: + if self.saveas_fs is None: self.saveas_fs = self.get_file_save_chooser( _("Save Parameters"), self.window, @@ -243,7 +237,7 @@ def get_save_as_fs(self): return self.saveas_fs def get_save_image_as_fs(self): - if self.saveimage_fs == None: + if self.saveimage_fs is None: self.saveimage_fs = self.get_file_save_chooser( _("Save Image"), self.window, @@ -251,7 +245,7 @@ def get_save_image_as_fs(self): return self.saveimage_fs def get_save_hires_image_as_fs(self): - if self.hires_image_fs == None: + if self.hires_image_fs is None: self.saveimage_fs = self.get_file_save_chooser( _("Save High Resolution Image"), self.window, @@ -263,15 +257,15 @@ def get_save_hires_image_as_fs(self): return self.saveimage_fs def get_open_fs(self): - if self.open_fs != None: + if self.open_fs is not None: return self.open_fs self.open_fs = Gtk.FileChooserDialog( - title=_("Open File"), transient_for=self.window, + title=_("Open File"), transient_for=self.window, action=Gtk.FileChooserAction.OPEN) self.open_fs.add_buttons( - Gtk.STOCK_OK, Gtk.ResponseType.OK, + Gtk.STOCK_OK, Gtk.ResponseType.OK, Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) self.add_filters(self.open_fs) @@ -283,9 +277,9 @@ def on_update_preview(chooser, preview): try: preview.loadFctFile(open(filename)) preview.draw_image(False, False) - active=True + active = True except Exception as err: - active=False + active = False chooser.set_preview_widget_active(active) self.open_fs.set_preview_widget(self.open_preview.widget) @@ -293,16 +287,7 @@ def on_update_preview(chooser, preview): 'update-preview', on_update_preview, self.open_preview) return self.open_fs - - def set_icon(self): - return # can't get this to work - try: - Gtk.window_set_default_icon_list([icons.logo.pixbuf]) - except Exception as err: - print(err) - # not supported in this pyGtk. Oh well... - pass - + def update_subfract_visibility(self,visible): if visible: for f in self.subfracts: @@ -334,7 +319,7 @@ def update_subfracts(self): f.draw_image(aa,auto_deepen) def create_subfracts(self,f): - self.subfracts = [ None ] * 12 + self.subfracts = [None] * 12 for i in range(12): self.subfracts[i] = gtkfractal.SubFract( self.compiler,f.width//4,f.height//4) @@ -395,8 +380,8 @@ def create_fractal(self,f): f.connect('status_changed',self.status_changed) f.connect('stats-changed', self.stats_changed) - def draw(self): - nt = preferences.userPrefs.getint("general","threads") + def draw(self): + nt = preferences.userPrefs.getint("general","threads") self.f.set_nthreads(nt) self.f.draw_image() @@ -412,10 +397,12 @@ def update_image_prefs(self,prefs): (w,h) = (prefs.getint("display","width"), prefs.getint("display","height")) if self.show_subfracts: - w = w //2 ; h = h // 2 + w = w // 2 + h = h // 2 for f in self.subfracts: f.set_size(w//2, h//2) - w += 2; h += 2 + w += 2 + h += 2 self.f.set_size(w,h) self.f.set_antialias( @@ -433,13 +420,13 @@ def on_prefs_changed(self,prefs): self.draw() def display_filename(self): - if self.filename == None: + if self.filename is None: return _("(Untitled %s)") % self.f.get_func_name() else: return self.filename def base_filename(self, extension): - if self.filename == None: + if self.filename is None: base_name = self.f.get_func_name() base_name = re_cleanup.sub("_", base_name) + extension else: @@ -531,7 +518,7 @@ def status_changed(self,f,status): text = self.statuses[status] % self.f.maxiter elif status == 0: # done - text = self.statuses[status] + text = self.statuses[status] if self.save_filename: self.save_image_file(self.save_filename) if self.quit_when_done: @@ -579,7 +566,7 @@ def get_all_actions(self): def get_toggle_actions(self): return [ ('ToolsExplorerAction', icons.explorer.stock_name, _('_Explorer'), - 'E', _('Create random fractals similar to this one'), + 'E', _('Create random fractals similar to this one'), self.toggle_explorer) ] @@ -588,32 +575,32 @@ def get_main_actions(self): ('FileMenuAction', None, _('_File')), ('FileOpenAction', Gtk.STOCK_OPEN, _('_Open...'), None, _('Open a Parameter or Formula File'), self.open), - ('FileSaveAction', Gtk.STOCK_SAVE, None, + ('FileSaveAction', Gtk.STOCK_SAVE, None, None, _("Save current parameters"), self.save), ('FileSaveAsAction', Gtk.STOCK_SAVE_AS, None, 'S', _("Save current parameters in a new location"), self.saveas), ('FileSaveImageAction', None, _('Save Current _Image'), 'I', _('Save the current image'), self.save_image), ('FileSaveHighResImageAction', None, _('Save _High-Res Image...'), - 'I', _('Save a higher-resolution version of the current image'), + 'I', _('Save a higher-resolution version of the current image'), self.save_hires_image), # FIXME: UI merging would seem to be better, but it's a bit bloody complicated # There's a special widget in pygtk 2.10 for this but that's too new, not all # interesting distributions have it - ('FileRecent1Action', None, _('_1'), None, None, + ('FileRecent1Action', None, _('_1'), None, None, lambda *args : self.load_recent_file(1)), - ('FileRecent2Action', None, _('_2'), None, None, + ('FileRecent2Action', None, _('_2'), None, None, lambda *args : self.load_recent_file(2)), - ('FileRecent3Action', None, _('_3'), None, None, + ('FileRecent3Action', None, _('_3'), None, None, lambda *args : self.load_recent_file(3)), - ('FileRecent4Action', None, _('_4'), None, None, + ('FileRecent4Action', None, _('_4'), None, None, lambda *args : self.load_recent_file(4)), - ('FileQuitAction', Gtk.STOCK_QUIT, None, + ('FileQuitAction', Gtk.STOCK_QUIT, None, None, _('Quit'), self.quit), - ('EditMenuAction', None, _('_Edit')), + ('EditMenuAction', None, _('_Edit')), ('EditFractalSettingsAction', Gtk.STOCK_PROPERTIES, _('_Fractal Settings...'), 'F', _('Edit the fractal\'s settings'), self.settings), ('EditPreferencesAction', Gtk.STOCK_PREFERENCES, None, @@ -650,11 +637,11 @@ def get_main_actions(self): ('HelpCommandReferenceAction', None, _('Command _Reference'), None, _('A list of keyboard and mouse shortcuts'), self.command_reference), ('HelpFormulaReferenceAction', None, _('_Formula Reference'), - None, _('Reference for functions and objects in the formula compiler'), + None, _('Reference for functions and objects in the formula compiler'), self.formula_reference), ('HelpReportBugAction', icons.face_sad.stock_name, _('_Report a Bug'), '', _('Report a bug you\'ve found'), self.report_bug), - ('HelpAboutAction', Gtk.STOCK_ABOUT, _('_About'), + ('HelpAboutAction', Gtk.STOCK_ABOUT, _('_About'), None, _('About Gnofract 4D'), self.about) ] @@ -715,7 +702,6 @@ def create_ui(self): self.manager.get_widget("/MenuBar/FileMenu/Recent3"), self.manager.get_widget("/MenuBar/FileMenu/Recent4")] - def director(self,*args): """Display the Director (animation) window.""" dialog = director.DirectorDialog(self.window, self.f) @@ -869,7 +855,7 @@ def create_toolbar(self): self.toolbar.add_widget( res_menu, _("Resolution"), - _("Change fractal's resolution")) + _("Change fractal's resolution")) # undo/redo self.toolbar.add_space() @@ -942,12 +928,12 @@ def create_resolution_menu(self): self.resolutions = [ (320,240), (640,480), (800,600), (1024, 768), - (1280, 800), (1280, 960), (1280,1024), + (1280, 800), (1280, 960), (1280,1024), (1400, 1050), (1440, 900), - (1600,1200), (1680, 1050), + (1600,1200), (1680, 1050), (1920, 1200), (2560, 1600)] - res_names= [ "%dx%d" % (w,h) for (w,h) in self.resolutions] + res_names= ["%dx%d" % (w,h) for (w,h) in self.resolutions] res_menu = utils.create_option_menu(res_names) @@ -1037,7 +1023,6 @@ def on_drag_param_fourway(self, widget, dx, dy, order, param_type): def on_release_fourway(self,widget,dx,dy): self.f.nudge(dx/10.0, dy/10.0, widget.axis) - def populate_warpmenu(self,f): params = f.forms[0].params_of_type(fracttypes.Complex, True) if params == []: @@ -1045,9 +1030,10 @@ def populate_warpmenu(self,f): else: utils.set_menu_from_list(self.warpmenu, ["None"] + params) p = f.warp_param - if p == None: p = "None" + if p is None: + p = "None" utils.set_selected_value(self.warpmenu, p) - self.warpmenu.show() + self.warpmenu.show() def add_warpmenu(self,tip): self.warpmenu = utils.create_option_menu(["None"]) @@ -1057,7 +1043,7 @@ def update_warp_param(menu, f): if param == "None": param = None - f.set_warp_param(param) + f.set_warp_param(param) self.on_formula_change(f) #self.populate_warpmenu(self.f,warpmenu) @@ -1106,10 +1092,10 @@ def load_recent_file(self, file_num, *args): self.load(self.recent_files[file_num-1]) def save_file(self,file): - fileHandle=None + fileHandle = None try: comp = preferences.userPrefs.getboolean("general","compress_fct") - fileHandle = open(file,'w') + fileHandle = open(file,'w') self.f.save(fileHandle,compress=comp) self.set_filename(file) self.update_recent_files(file) @@ -1119,12 +1105,12 @@ def save_file(self,file): _("Error saving to file %s") % file, err) return False finally: - if fileHandle != None: + if fileHandle is not None: fileHandle.close() def save(self,action): """Save the current parameters.""" - if self.filename == None: + if self.filename is None: self.saveas(action) else: self.save_file(self.filename) @@ -1160,7 +1146,7 @@ def confirm(self,name): transient_for=self.window, proceed_button=_("Overwrite")) - response = d.run() + response = d.run() d.destroy() return response == Gtk.ResponseType.ACCEPT else: @@ -1174,7 +1160,7 @@ def show_warning(self,message): d.destroy() def show_error_message(self,message,exception=None): - if exception == None: + if exception is None: secondary_message = "" else: if isinstance(exception,EnvironmentError): @@ -1296,7 +1282,7 @@ def formula_reference(self, *args): self.display_help("formref") def report_bug(self, *args): - url="https://github.com/edyoung/gnofract4d/issues" + url = "https://github.com/edyoung/gnofract4d/issues" utils.launch_browser( preferences.userPrefs, url, @@ -1326,7 +1312,7 @@ def display_help(self,section=None): _("Can't find help file '%s'") % abs_file) return - if section == None: + if section is None: anchor = "" else: anchor = "#" + section @@ -1334,20 +1320,19 @@ def display_help(self,section=None): if yelp_path: os.system("yelp ghelp://%s%s >/dev/null 2>&1 &" % (abs_file, anchor)) else: - url="file://%s%s" % (abs_file, anchor) + url = "file://%s%s" % (abs_file, anchor) utils.launch_browser( preferences.userPrefs, url, self.window) - - + def open(self,action): """Open a parameter or formula file.""" fs = self.get_open_fs() fs.show_all() while True: - result = fs.run() + result = fs.run() if result == Gtk.ResponseType.OK: if self.load(fs.get_filename()): break @@ -1387,13 +1372,13 @@ def load_formula(self,file): return False def check_save_fractal(self): - "Prompt user to save if necessary. Return whether to quit" + "Prompt user to save if necessary. Return whether to quit" while not self.f.is_saved(): d = hig.SaveConfirmationAlert( document_name=self.display_filename(), parent=self.window) - response = d.run() + response = d.run() d.destroy() if response == Gtk.ResponseType.ACCEPT: self.save(None) @@ -1408,7 +1393,7 @@ def check_save_fractal(self): secondary=_("If you proceed, queued images will not be saved"), proceed_button=_("Close anyway")) - response = d.run() + response = d.run() d.destroy() if response == Gtk.ResponseType.ACCEPT: break @@ -1439,7 +1424,7 @@ def quit(self,action,widget=None): finally: Gtk.main_quit() if 'win' == sys.platform[:3]: - exit(0); + exit(0) # return False def apply_options(self,opts): From 2c0d546345728523d5816e30b8750f712318c666 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 16 Feb 2018 19:15:12 +0000 Subject: [PATCH 13/13] tidy painter, preferences and renderqueue dialogs --- fract4dgui/painter.py | 6 ++---- fract4dgui/preferences.py | 38 +++++++++++++++----------------------- fract4dgui/renderqueue.py | 16 ++++++---------- 3 files changed, 23 insertions(+), 37 deletions(-) diff --git a/fract4dgui/painter.py b/fract4dgui/painter.py index 5a9be5ef6..2e6bf392f 100644 --- a/fract4dgui/painter.py +++ b/fract4dgui/painter.py @@ -3,8 +3,6 @@ from gi.repository import Gtk from . import dialog -from . import browser -from . import utils class PainterDialog(dialog.T): def __init__(self,main_window,f): @@ -17,7 +15,7 @@ def __init__(self,main_window,f): ) self.f = f - self.paint_toggle = Gtk.ToggleButton(_("Painting")) + self.paint_toggle = Gtk.ToggleButton.new_with_label(_("Painting")) self.paint_toggle.set_active(True) self.paint_toggle.connect('toggled',self.onChangePaintMode) self.csel = Gtk.ColorSelection() @@ -34,4 +32,4 @@ def onResponse(self,widget,id): id == Gtk.ResponseType.NONE or \ id == Gtk.ResponseType.DELETE_EVENT: self.hide() - self.f.set_paint_mode(False,None) + self.f.set_paint_mode(False,None) diff --git a/fract4dgui/preferences.py b/fract4dgui/preferences.py index a6b8fbeee..3793dbeb2 100644 --- a/fract4dgui/preferences.py +++ b/fract4dgui/preferences.py @@ -1,14 +1,8 @@ # GUI for user settings -import os -import sys - -from gi.repository import Gtk -from gi.repository import GObject - -from . import dialog -from . import utils +from gi.repository import Gtk, GObject +from . import dialog, utils from fract4d import fractconfig class Preferences(GObject.GObject): @@ -119,7 +113,7 @@ def set_prefs(*args): except ValueError: Gtk.idle_add( self.show_error, - "Invalid value for width: '%s'. Must be an integer" % \ + "Invalid value for width: '%s'. Must be an integer" % entry.get_text()) return False @@ -151,7 +145,7 @@ def set_prefs(*args): except ValueError: utils.idle_add( self.show_error, - "Invalid value for height: '%s'. Must be an integer" % \ + "Invalid value for height: '%s'. Must be an integer" % entry.get_text()) return False @@ -229,11 +223,11 @@ def create_directory_list(self, section_name): self.path_list = Gtk.ListStore( GObject.TYPE_STRING) - path_treeview = Gtk.TreeView (model=self.path_list) + path_treeview = Gtk.TreeView(model=self.path_list) - renderer = Gtk.CellRendererText () - column = Gtk.TreeViewColumn (_('_Directory'), renderer, text=0) - path_treeview.append_column (column) + renderer = Gtk.CellRendererText() + column = Gtk.TreeViewColumn(_('_Directory'), renderer, text=0) + path_treeview.append_column(column) path_treeview.set_headers_visible(False) paths = self.prefs.get_list(section_name) @@ -241,7 +235,7 @@ def create_directory_list(self, section_name): iter = self.path_list.append() self.path_list.set(iter,0,path) - return path_treeview + return path_treeview def update_prefs(self,name, model): list = [] @@ -259,7 +253,7 @@ def browse_for_dir(self, widget, name, pathlist): if result == Gtk.ResponseType.OK: path = self.dirchooser.get_filename() - model = pathlist.get_model() + model = pathlist.get_model() iter = model.append() model.set(iter,0,path) @@ -299,10 +293,10 @@ def create_compiler_options_page(self): table.attach(flags_label,0,1,1,2,0,0,2,2) flags_label.set_mnemonic_widget(entry) - sw = Gtk.ScrolledWindow () - sw.set_shadow_type (Gtk.ShadowType.ETCHED_IN) - sw.set_policy (Gtk.PolicyType.NEVER, - Gtk.PolicyType.AUTOMATIC) + sw = Gtk.ScrolledWindow() + sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + sw.set_policy(Gtk.PolicyType.NEVER, + Gtk.PolicyType.AUTOMATIC) form_path_section = "formula_path" @@ -325,8 +319,7 @@ def create_compiler_options_page(self): remove_button = Gtk.Button.new_from_stock(Gtk.STOCK_REMOVE) remove_button.connect('clicked', self.remove_dir, form_path_section, pathlist) table.attach(remove_button,0,1,4,5,Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 2, 2) - - + def create_helper_options_page(self): table = Gtk.Table(n_rows=5,n_columns=2,homogeneous=False) label = Gtk.Label(label=_("_Helpers")) @@ -454,4 +447,3 @@ def create_image_options_page(self): aalabel.set_use_underline(True) aalabel.set_mnemonic_widget(optMenu) table.attach(aalabel,0,1,5,6,0,0,2,2) - diff --git a/fract4dgui/renderqueue.py b/fract4dgui/renderqueue.py index 5b463db6e..57aea0103 100644 --- a/fract4dgui/renderqueue.py +++ b/fract4dgui/renderqueue.py @@ -4,12 +4,9 @@ import copy -from gi.repository import GObject -from gi.repository import Gtk +from gi.repository import Gtk, GObject -from . import gtkfractal -from . import dialog -from . import preferences +from . import dialog, gtkfractal, preferences class QueueEntry: def __init__(self, f, name, w, h): @@ -43,7 +40,7 @@ def add(self,f,name,w,h): self.emit('changed') def start(self): - if self.current == None: + if self.current is None: next(self) def empty(self): @@ -99,9 +96,9 @@ def __init__(self, main_window, f, renderQueue): self.controls = Gtk.VBox() self.store = Gtk.ListStore( - GObject.TYPE_STRING, # name - GObject.TYPE_STRING, # size - GObject.TYPE_FLOAT, # % complete + str, # name + str, # size + float # % complete ) self.view = Gtk.TreeView.new_with_model(self.store) @@ -128,4 +125,3 @@ def onProgressChanged(self,f,progress): iter = self.store.get_iter_first() if iter: self.store.set_value(iter,2,progress) -