diff --git a/system/fluents.py b/system/fluents.py index a79cfe8..9c2e7cd 100755 --- a/system/fluents.py +++ b/system/fluents.py @@ -56,7 +56,7 @@ class FluentApp: return self.log_view def create_main_view(self, str1, str2, int1, int2): - self.main_view = plots.MainView(self._update_toolbar) + self.main_view = plots.MainView() self.main_view.show() return self.main_view diff --git a/system/plots.py b/system/plots.py index 801b9cd..bc5e887 100644 --- a/system/plots.py +++ b/system/plots.py @@ -13,69 +13,181 @@ from matplotlib import cm from system import logger +class ObjectTable: + """A 2D table of elements.""" + + def __init__(self, xsize=0, ysize=0, creator=None): + self._elements = [] + self._creator = creator or (lambda : None) + self.xsize = xsize + self.ysize = ysize + self.resize(xsize, ysize) + + def resize(self, xsize, ysize): + """Resizes the table by removing and creating elements as required.""" + # Delete or append new rows + del self._elements[ysize:] + new_rows = ysize - len(self._elements) + self._elements.extend([list() for i in range(new_rows)]) + + # Delete or append new columns + for row in self._elements: + del row[xsize:] + new_elems = xsize - len(row) + row.extend([self._creator() for i in range(new_elems)]) + + def __getitem__(self, index): + x, y = index + return self._elements[y][x] + + def __setitem__(self, index, value): + x, y = index + self._elements[y][x] = value + + +class ViewFrame (gtk.Frame): + def __init__(self, view_frames): + gtk.Frame.__init__(self) + self.focused = False + self.view_frames = view_frames + self.empty_view = EmptyView() + + view_frames.append(self) + if len(view_frames) == 1: + self.focus() + else: + self.unfocus() + + self._view = self.empty_view + self.set_view(self._view) + self.show() + + def focus(self): + """Gets focus and ensures that no other window is in focus.""" + if self.focused: + return self + + for frame in self.view_frames: + frame.unfocus() + + self.set_shadow_type(gtk.SHADOW_IN) + self.focused = True + return self + + def unfocus(self): + """Removes focus from the ViewFrame if it is focused.""" + if not self.focused: + return + + self.set_shadow_type(gtk.SHADOW_OUT) + self.focused = False + + def set_view(self, view): + """Set view to view or to empty view if parameter is None""" + # if None is passed, use empty view + if view == None: + view = self.empty_view + +# # do nothing if the view is already there +# if view == self._view: +# return + + # switch which widget we are listening to +# if self._view: +# self._view.disconnect(self.on_button_press_event) + view.connect("button-press-event", self.on_button_press_event) + + # remove old view, set new view + self._view.hide() + self.remove(self._view) + self.add(view) + view.show() + + self._view = view + + def get_view(self): + """Returns current view, or None if the empty view is set.""" + if self._view == self.empty_view: + return None + return self._view + + def on_button_press_event(self, widget, event): + print "foo" + if not self.focused: + self.focus() + class MainView (gtk.Notebook): - def __init__(self, view_listener): + def __init__(self): gtk.Notebook.__init__(self) self.set_show_tabs(False) self.set_show_border(False) - # Add a multiple pane view and a single pane view. - self.small_view = SmallView() - self.small_view.set_view_listener(view_listener) - self.small_view.show() - self.large_view = LargeView() - self.large_view.show() - - self.append_page(self.small_view) - self.append_page(self.large_view) + 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() + + self.append_page(self._small_views) + self.append_page(self._large_view) self.set_current_page(0) + self.show() + + def __getitem__(self, x, y): + return self._views[x, y] + + def update_small_views(self): + 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) + + def get_active_small_view(self): + for vf in self._view_frames: + if vf.focused: + return vf + return None - def goto_small(self): - if self.get_current_page() == 0: - return None - self.set_current_page(0) - view = self.large_view.remove_child() - self.small_view.return_current(view) - def goto_large(self): - if self.get_current_page() == 1: - return None + vf = self.get_active_small_view() + view = vf.get_view() + vf.set_view(None) + self._large_view.set_view(view) self.set_current_page(1) - view = self.small_view.borrow_current() - self.large_view.set_child(view) - def show(self): - gtk.Notebook.show(self) + def goto_small(self): + vf = self.get_active_small_view() + view = self._large_view.get_view() + self._large_view.set_view(None) + vf.set_view(view) + self.set_current_page(0) def insert_view(self, view): - self.small_view.insert_view(view) - - + vf = self.get_active_small_view() + vf.set_view(view) + + def show(self): + for vf in self._view_frames: + vf.show() + self._small_views.show() + gtk.Notebook.show(self) + +# def insert_view(self, view) + class Plot (gtk.Frame): def __init__(self, title): gtk.Frame.__init__(self) - self.mark_active(False) - self.connect('button_press_event', self.on_button_press) self.sel_obj = None - self.active = False self.title = title self.selection_listener = None + self.set_shadow_type(gtk.SHADOW_NONE) def get_title(self): return self.title - def on_button_press(self, *rest): -# logger.log('debug', 'button pressed in plot') - self.mark_active(True) - - def mark_active(self, active): - if active: - self.set_shadow_type(gtk.SHADOW_IN) - else: - self.set_shadow_type(gtk.SHADOW_OUT) - self.active = active - def selection_changed(self, selection): pass @@ -118,7 +230,9 @@ class SmallView (gtk.Table): # drag'n'drop for views in self.child_views: for view in views: - view.drag_dest_set(gtk.DEST_DEFAULT_ALL, [("GTK_TREE_MODEL_ROW",gtk.TARGET_SAME_APP,7)],gtk.gdk.ACTION_LINK) + view.drag_dest_set(gtk.DEST_DEFAULT_ALL, + [("GTK_TREE_MODEL_ROW",gtk.TARGET_SAME_APP,7)], + gtk.gdk.ACTION_LINK) view.connect("drag-data-received",self.drag_received_by_view,view) @@ -138,7 +252,9 @@ class SmallView (gtk.Table): def set_child(self, child, col, row): # urg, this probably belongs somewhere else - child.drag_dest_set(gtk.DEST_DEFAULT_ALL, [("GTK_TREE_MODEL_ROW",gtk.TARGET_SAME_APP,7)],gtk.gdk.ACTION_LINK) + child.drag_dest_set(gtk.DEST_DEFAULT_ALL, + [("GTK_TREE_MODEL_ROW",gtk.TARGET_SAME_APP,7)], + gtk.gdk.ACTION_LINK) child.connect("drag-data-received",self.drag_received_by_view,child) cur_widget = self.child_views[col][row] @@ -206,57 +322,18 @@ class SmallView (gtk.Table): def get_view(self, x, y): return self.child_views[x][y] -class LargeView (gtk.Frame): - def __init__(self): - gtk.Frame.__init__(self) - self.child_view = EmptyView() - self.add(self.child_view) - - def set_child(self, child): - self.remove(self.child_view) - self.child_view.hide() - self.add(child) - self.child_view = child - child.show() - def hide(self): - self.child_view.hide() - gtk.Frame.hide(self) - - def show(self): - self.child_view.show() - gtk.Frame.show(self) - - def remove_child(self): - child = self.child_view - child.hide() - self.remove(child) - return child - - class EmptyView (Plot): def __init__(self): Plot.__init__(self, 'Empty view') - label = gtk.Label('No view') ebox = gtk.EventBox() ebox.add(label) self.add(ebox) - label.connect('button_press_event', self.on_button_press) - - self.label = label - self.ebox = ebox - self.show() - - def show(self): - self.ebox.show() - self.label.show() - Plot.show(self) - def hide(self): - self.label.hide() - self.ebox.hide() - Plot.hide(self) + label.show() + ebox.show() + self.show() class NavToolbar(NavigationToolbar2):