diff --git a/fluents b/fluents index 77e73d8..cb25aa2 100755 --- a/fluents +++ b/fluents @@ -63,6 +63,7 @@ if __name__ == '__main__': gnome.program_init(PROGRAM_NAME, VERSION) app = fluents.FluentApp(parameters['workflow']) + fluents.app = app app.set_project(project.Project()) app.show() gtk.main() diff --git a/system/fluents.glade b/system/fluents.glade index 8b6b851..e7131df 100644 --- a/system/fluents.glade +++ b/system/fluents.glade @@ -320,7 +320,7 @@ GTK_SHADOW_OUT - + True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_ICONS diff --git a/system/fluents.py b/system/fluents.py index fa66169..ae82580 100755 --- a/system/fluents.py +++ b/system/fluents.py @@ -5,6 +5,7 @@ import sys import pygtk pygtk.require('2.0') +import gobject import gtk import gtk.gdk import gtk.glade @@ -21,6 +22,104 @@ DATADIR = os.path.dirname(sys.modules['system'].__file__) ICONDIR = os.path.join(DATADIR,"..","icons") GLADEFILENAME = os.path.join(DATADIR, 'fluents.glade') +class TableSizeSelection(gtk.Window): + + def __init__(self): + gtk.Window.__init__(self, gtk.WINDOW_POPUP) + self._table = gtk.Table(3, 3, True) + self._items = [] + + ## Create a 3x3 table of EventBox object, doubly stored because + ## gtk.Table does not support indexed retrieval. + + for y in range(3): + line = [] + for x in range(3): + ebox = gtk.EventBox() + ebox.add(gtk.Frame()) + ebox.set_size_request(20, 20) + ebox.set_visible_window(True) + self._table.attach(ebox, x, x+1, y, y+1, gtk.FILL, gtk.FILL) + line.append(ebox) + self._items.append(line) + + self.set_border_width(5) + self.add(self._table) + self.connect_signals() + + def _get_child_pos(self, child): + for x in range(3): + for y in range(3): + if self._items[y][x] == child: + return (x, y) + return None + + def connect_signals(self): + for x in range(3): + for y in range(3): + self._items[y][x].add_events(gtk.gdk.ENTER_NOTIFY_MASK) + self._items[y][x].connect("enter-notify-event", + self._on_enter_notify) + self._items[y][x].connect("button-release-event", + self._on_button_release) + + def _on_enter_notify(self, widget, event): + x, y = self._get_child_pos(widget) + for i in range(3): + for j in range(3): + if i <= x and j <= y: + self._items[j][i].set_state(gtk.STATE_SELECTED) + else: + self._items[j][i].set_state(gtk.STATE_NORMAL) + self.x = x + self.y = y + + def _on_button_release(self, widget, event): + self.emit('table-size-set', self.x+1, self.y+1) + self.hide_all() + + for x in range(3): + for y in range(3): + self._items[y][x].set_state(gtk.STATE_NORMAL) + + +class ViewFrameToolButton (gtk.ToolItem): + + def __init__(self): + gtk.ToolItem.__init__(self) + + fname = os.path.join(ICONDIR, "move.png") + image = gtk.Image() + image.set_from_file(fname) + + self._button = gtk.Button() + self._button.set_image(image) +# self._button.set_focus_on_click(False) + self._button.set_property("can-focus", False) + + eb = gtk.EventBox() + eb.add(self._button) + self.add(eb) + self._item = TableSizeSelection() + self._button.connect("button-press-event", self._on_show_menu) + image.show() + self._image = image + + self._item.connect("table-size-set", self._on_table_size_set) + self._button.set_relief(gtk.RELIEF_NONE) + self.show_all() + + def _on_show_menu(self, widget, event): + x, y = self._image.window.get_origin() + x2, y2, w, h, b = self._image.window.get_geometry() + + self._item.move(x, y+h) + self._item.show_all() + + def _on_table_size_set(self, widget, width, height): + app['main_view'].resize_table(width, height) + + class FluentApp: def __init__(self, wf): # Application variables @@ -33,11 +132,9 @@ class FluentApp: gtk.glade.set_custom_handler(self.custom_object_factory) self.widget_tree = gtk.glade.XML(GLADEFILENAME, 'appwindow') self.workflow = wf(self) -# self['selection_tree'].set_identifier_list(self['identifier_list']) self.dimlistcontroller = selections.DimListController(self['dim_list'], self['selection_tree'], self['identifier_list']) -# self['dim_list'].set_selection_tree(self['selection_tree']) def init_gui(self): self['appwindow'].set_size_request(800, 600) @@ -47,9 +144,6 @@ class FluentApp: self.wf_menu.show() self['workflow_vbox'].pack_end(self.wf_menu) - # Set up plot toolbar -# self['plot_toolbar_dock'].add(plot.get_toolbar(self.app)) - # Connect signals signals = {'on_quit1_activate' : (gtk.main_quit), 'on_appwindow_delete_event' : (gtk.main_quit), @@ -71,6 +165,10 @@ class FluentApp: # Log that we've set up the app now logger.log('debug', 'Program started') + # Add ViewFrame table size to toolbar + tb = ViewFrameToolButton() + self['toolbar'].add(tb) + def set_project(self, project): logger.log('notice', 'Creating a new project') self.project = project @@ -211,3 +309,8 @@ class FluentApp: def on_view_changed(self, widget, vf): self._update_toolbar(vf.get_view()) + +gobject.signal_new('table-size-set', TableSizeSelection, gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_INT, gobject.TYPE_INT)) + diff --git a/system/plots.py b/system/plots.py index 3c4e354..9db52aa 100644 --- a/system/plots.py +++ b/system/plots.py @@ -45,6 +45,9 @@ class ObjectTable: new_elems = xsize - len(row) row.extend([self._creator() for i in range(new_elems)]) + self.xsize = xsize + self.ysize = ysize + def __getitem__(self, index): x, y = index return self._elements[y][x] @@ -194,9 +197,6 @@ class MainView (gtk.Notebook): self._view_frames = [] self._views = ObjectTable(2, 2, lambda : ViewFrame(self._view_frames)) - self._small_views = gtk.Table(2, 2, True) - self._small_views.set_col_spacings(4) - self._small_views.set_row_spacings(4) self._large_view = ViewFrame(list()) self.update_small_views() @@ -212,10 +212,14 @@ class MainView (gtk.Notebook): return self._views[x, y] def update_small_views(self): + self._small_views = gtk.Table(self._views.ysize, self._views.xsize, True) + self._small_views.set_col_spacings(4) + self._small_views.set_row_spacings(4) for x in range(self._views.xsize): for y in range(self._views.ysize): child = self._views[x,y] self._small_views.attach(child, x, x+1, y, y+1) + self._small_views.show_all() def get_active_small_view(self): for vf in self._view_frames: @@ -273,6 +277,21 @@ class MainView (gtk.Notebook): if focused: self.emit('view-changed', vf) + def resize_table(self, width, height): + + ## Hide all plots that will be removed from the screen. + for x in range(self._views.xsize): + for y in range(self._views.ysize): + if width > x or height > y: + self._views[x, y].set_view(None) + self._small_views.remove(self._views[x, y]) + + self._views.resize(width, height) + self.update_small_views() + self.insert_page(self._small_views, gtk.Label("small"), 0) + self.remove_page(1) + #self.set_current_page(0) + self.goto_small() class View (gtk.Frame): """The base class of everything that is shown in the center view of fluents.