Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@sugarlabs.org>2009-01-24 12:28:52 (GMT)
committer Tomeu Vizoso <tomeu@sugarlabs.org>2009-01-24 12:28:52 (GMT)
commit852766ad7192a6b53eea8127643e8a81ecf49efa (patch)
tree793265678d8c25f3fc4b5e677698ef990c5a41a0
parent69bebc6b6f7fd0bb73bc0eda538b44eacda3fe59 (diff)
Make MindMapModel inherit from gtk.TreeStore
-rw-r--r--canvas.py8
-rw-r--r--model.py204
-rw-r--r--treeview.py16
-rw-r--r--view.py84
4 files changed, 88 insertions, 224 deletions
diff --git a/canvas.py b/canvas.py
index a65a03f..ca1beb8 100644
--- a/canvas.py
+++ b/canvas.py
@@ -56,6 +56,8 @@ class Canvas(gtk.DrawingArea):
rect.x = 0
rect.y = 0
+ logging.debug('__expose_event_cb1 %r %r %r %r' % (event.area.x, event.area.y,
+ event.area.width, event.area.height))
context.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
context.clip()
@@ -65,6 +67,7 @@ class Canvas(gtk.DrawingArea):
for element in self._elements:
rect = element.get_rect()
+ logging.debug('__expose_event_cb %r %r %r %r' % (rect.x, rect.y, rect.width, rect.height))
if rect.intersect(event.area):
context.save()
@@ -107,6 +110,9 @@ class Canvas(gtk.DrawingArea):
self._elements = []
+ def get_elements(self):
+ return self._elements
+
def __element_invalidated_cb(self, **kwargs):
element = kwargs['sender']
@@ -180,7 +186,7 @@ class Canvas(gtk.DrawingArea):
class CanvasElement(object):
def __init__(self):
self.invalidated = dispatch.Signal()
- self.previous_rect = (0, 0, 0, 0)
+ self.previous_rect = gtk.gdk.Rectangle(0, 0, 0, 0)
def draw(self, context):
self.previous_rect = self.get_rect()
diff --git a/model.py b/model.py
index 2084773..aaead38 100644
--- a/model.py
+++ b/model.py
@@ -22,50 +22,29 @@ import cjson
from sugar import dispatch
-class MindMapModel(gtk.GenericTreeModel):
-
- _COLUMN_TYPES = (str, str, long, long, str)
+class MindMapModel(gtk.TreeStore):
def __init__(self):
- gobject.GObject.__init__(self)
+ gtk.TreeStore.__init__(self, int, str, long, long, str)
self._next_thought_id = 0
self._thoughts_by_id = {}
self._thoughts = []
def create_new_thought(self):
- thought = Thought(self._next_thought_id)
- self._add_thought(thought)
-
- def _add_thought(self, thought):
- thought.changed.connect(self.__thought_changed_cb)
- self._thoughts.append(thought)
- self._thoughts_by_id[thought.id] = thought
+ self.append(None, (self._next_thought_id, '', 0, 0, ''))
self._next_thought_id += 1
- path = (thought.id,)
- self.row_inserted(path, self.get_iter(path))
-
- def get_thought(self, thought_id):
- return self._thoughts_by_id[int(thought_id)]
-
- def __thought_changed_cb(self, **kwargs):
- thought = kwargs['sender']
- path = (thought.id,)
- self.row_changed(path, self.get_iter(path))
-
- def get_thoughts(self):
- return self._thoughts
-
def serialize(self):
thoughts = []
- for thought in self._thoughts:
+ for row in self:
+ logging.debug('serialize %r' % row[0])
thought_dict = {}
- thought_dict['id'] = thought.id
- thought_dict['name'] = thought.name
- thought_dict['x'] = thought.x
- thought_dict['y'] = thought.y
- thought_dict['color'] = thought.color
+ thought_dict['id'] = row[0]
+ thought_dict['name'] = row[1]
+ thought_dict['x'] = row[2]
+ thought_dict['y'] = row[3]
+ thought_dict['color'] = row[4]
thoughts.append(thought_dict)
return cjson.encode({'thoughts': thoughts})
@@ -73,152 +52,19 @@ class MindMapModel(gtk.GenericTreeModel):
def unserialize(self, data):
thoughts = cjson.decode(data)['thoughts']
for thought_dict in thoughts:
- thought = Thought(thought_dict['id'])
- thought.name = thought_dict.get('name', None)
- thought.x = thought_dict.get('x', None)
- thought.y = thought_dict.get('y', None)
- thought.color = thought_dict.get('color', None)
- self._add_thought(thought)
-
- # gtk.GenericTreeModel methods
- # paths and rowrefs are the thought ids
- def on_get_flags(self):
- return gtk.TREE_MODEL_ITERS_PERSIST
-
- def on_get_n_columns(self):
- return len(self._COLUMN_TYPES)
-
- def on_get_column_type(self, n):
- return self._COLUMN_TYPES[n]
-
- def on_get_iter(self, path):
- logging.debug('on_get_iter %r %r' % (type(path), path))
- if path[0] in self._thoughts_by_id:
- return path[0]
- else:
- return None
-
- def on_get_path(self, rowref):
- logging.debug('on_get_path %r' % rowref)
- return (rowref,)
-
- def on_get_value(self, rowref, column):
- #logging.debug('on_get_value %r %r' % (rowref, column))
- if rowref >= len(self._thoughts):
- return None
- thought = self._thoughts[rowref]
- value_tuple = thought.get_tuple()
- return value_tuple[column]
-
- def on_iter_next(self, rowref):
- #logging.debug('on_iter_next %r' % rowref)
- if rowref not in self._thoughts_by_id:
- return None
- thought = self._thoughts_by_id[rowref]
-
- index = self._thoughts.index(thought)
- if index + 1 >= len(self._thoughts):
- return None
- next_thought = self._thoughts[index + 1]
- #logging.debug('on_iter_next returning %r' % next_thought.id)
- return next_thought.id
-
- def on_iter_children(self, rowref):
- logging.debug('on_iter_children %r' % rowref)
- if rowref:
- return None
- if self._thoughts:
- return self._thoughts[0].id
- else:
- return None
-
- def on_iter_has_child(self, rowref):
- return False
-
- def on_iter_n_children(self, rowref):
- logging.debug('on_iter_n_children %r' % rowref)
- if rowref:
- return 0
- return len(self._thoughts)
-
- def on_iter_nth_child(self, rowref, n):
- logging.debug('on_iter_nth_child %r %r' % (rowref, n))
- if rowref is not None:
- return None
- if n < len(self._thoughts):
- return self._thoughts[n].id
-
- def on_iter_parent(child):
- return None
-
-class Thought(object):
-
- def __init__(self, thought_id, name=None, x=0, y=0, color=None):
- if thought_id is None:
- raise ValueError('thought_id cannot be None')
- self._id = thought_id
- self._name = name
- self._x = x
- self._y = y
- self._color = color
-
- self.changed = dispatch.Signal()
-
- def get_tuple(self):
- return (self.id, self.name, self.x, self.y, self.color)
-
- def set_id(self, new_id):
- if self._id == new_id:
- return
- self._id = new_id
- self.changed.send(self)
-
- def get_id(self):
- return self._id
-
- id = property(get_id, set_id)
-
- def set_name(self, new_name):
- if self._name == new_name:
- return
- self._name = new_name
- self.changed.send(self)
-
- def get_name(self):
- return self._name
-
- name = property(get_name, set_name)
-
- def set_x(self, new_x):
- if self._x == new_x:
- return
- self._x = new_x
- self.changed.send(self)
-
- def get_x(self):
- return self._x
-
- x = property(get_x, set_x)
-
- def set_y(self, new_y):
- if self._y == new_y:
- return
- self._y = new_y
- self.changed.send(self)
-
- def get_y(self):
- return self._y
-
- y = property(get_y, set_y)
-
- def set_color(self, new_color):
- if self._color == new_color:
- return
- self._color = new_color
- self.changed.send(self)
-
- def get_color(self):
- return self._color
-
- color = property(get_color, set_color)
+ self._next_thought_id = max(self._next_thought_id + 1,
+ thought_dict['id'] + 1)
+ self.append(None, (thought_dict['id'],
+ thought_dict.get('name', None),
+ thought_dict.get('x', None),
+ thought_dict.get('y', None),
+ thought_dict.get('color', None)))
+
+ def find_by_id(self, thought_id, rows=None):
+ if rows is None:
+ rows = self
+ for row in rows:
+ if row[0] == thought_id:
+ return row
+ self.find_by_id(thought_id, row.iterchildren())
diff --git a/treeview.py b/treeview.py
index cec8562..e255fa8 100644
--- a/treeview.py
+++ b/treeview.py
@@ -69,18 +69,18 @@ class TreeView(gtk.ScrolledWindow):
self.set_size_request(200, -1)
def __name_edited_cb(self, cell_renderer, path, new_text):
- thought = self._tree_view.props.model.get_thought(path[0])
- thought.name = new_text
+ model = self._tree_view.props.model
+ model.set(model.get_iter(path), 1, new_text)
def __x_edited_cb(self, cell_renderer, path, new_text):
- thought = self._tree_view.props.model.get_thought(path[0])
- thought.x = int(new_text)
+ model = self._tree_view.props.model
+ model.set(model.get_iter(path), 2, float(new_text))
def __y_edited_cb(self, cell_renderer, path, new_text):
- thought = self._tree_view.props.model.get_thought(path[0])
- thought.y = int(new_text)
+ model = self._tree_view.props.model
+ model.set(model.get_iter(path), 3, float(new_text))
def __color_edited_cb(self, cell_renderer, path, new_text):
- thought = self._tree_view.props.model.get_thought(path[0])
- thought.color = new_text
+ model = self._tree_view.props.model
+ model.set(model.get_iter(path), 4, new_text)
diff --git a/view.py b/view.py
index 326ced8..cbe31d7 100644
--- a/view.py
+++ b/view.py
@@ -31,8 +31,8 @@ class MindMapView(Canvas):
def __init__(self, model=None):
self._model = None
+ self._row_changed_sid = None
self._row_deleted_sid = None
- self._row_inserted_sid = None
self._selected_thought = None
Canvas.__init__(self)
@@ -63,8 +63,8 @@ class MindMapView(Canvas):
thought_rect = thought.get_rect()
if (x >= 0 and x + thought_rect.width <= rect.width) and \
(y >= 0 and y + thought_rect.height <= rect.height):
- thought.model.x = x
- thought.model.y = y
+ row = self.model.find_by_id(thought.id)
+ self.model.set(row.iter, 2, x, 3, y)
def __button_release_event_cb(self, widget, event):
logging.debug('button_release_event_cb')
@@ -86,43 +86,55 @@ class MindMapView(Canvas):
return
if self._model is not None:
+ self._model.disconnect(self._row_changed_sid)
self._model.disconnect(self._row_deleted_sid)
- self._model.disconnect(self._row_inserted_sid)
self._model = new_model
if self._model is not None:
+ self._row_changed_sid = \
+ self._model.connect('row-changed', self.__row_changed_cb)
self._row_deleted_sid = \
self._model.connect('row-deleted', self.__row_deleted_cb)
- self._row_inserted_sid = \
- self._model.connect('row-inserted', self.__row_inserted_cb)
self.remove_all_elements()
- for thought_model in self._model.get_thoughts():
- though_view = ThoughtView(thought_model)
- self.add_element(though_view)
+ self._populate_from_model(self._model)
+
+ def _populate_from_model(self, rows):
+ for row in rows:
+ thought_view = ThoughtView(row[0], row[1], row[2], row[3], row[4])
+ self._populate_from_model(row.iterchildren())
+ self.add_element(thought_view)
def get_model(self):
return self._model
model = property(get_model, set_model)
- def __row_inserted_cb(self, model, path, iter):
- logging.debug('__row_inserted_cb %r' % path)
+ def __row_changed_cb(self, model, path, iter):
+ logging.debug('__row_changed_cb %r' % path)
- thought_model = model.get_thought(path[0])
- though_view = ThoughtView(thought_model)
- self.add_element(though_view)
+ row = model[iter]
+ thought_view = self._get_thought_by_id(row[0])
+ if thought_view is None:
+ thought_view = ThoughtView(row[0], row[1], row[2], row[3], row[4])
+ self.add_element(thought_view)
+ else:
+ thought_view.name = row[1]
+ thought_view.x = row[2]
+ thought_view.y = row[3]
+ thought_view.color = row[4]
+ thought_view.invalidate()
def __row_deleted_cb(self, model, path):
logging.debug('__row_deleted_cb %r' % path)
- though_view = self._get_though_by_id(path[0])
- self.remove_element(though_view)
+ thought_view = self._get_thought_by_id(path[0])
+ self.remove_element(thought_view)
- def _get_though_by_id(self, thought_id):
+ def _get_thought_by_id(self, thought_id):
for thought_view in self.get_elements():
- if thought_view.model.id == path[0]:
+ if thought_view.id == thought_id:
return thought_view
return None
@@ -131,17 +143,22 @@ class ThoughtView(CanvasElement):
_PADDING = style.zoom(15)
_LINE_WIDTH = style.zoom(2)
- def __init__(self, model):
+ def __init__(self, thought_id, name, x, y, color):
CanvasElement.__init__(self)
- self.model = model
+ logging.debug('ThoughtView %r %r' % (thought_id, name))
+
+ self.id = thought_id
+ self.name = name
+ self.x = x
+ self.y = y
+ self.color = color
+
self._last_width = -1
self._last_height = -1
self._dragging = False
self._selected = False
- self.model.changed.connect(self.__model_changed_cb)
-
def set_dragging(self, dragging):
if self._dragging != dragging:
self._dragging = dragging
@@ -165,10 +182,10 @@ class ThoughtView(CanvasElement):
pixmap = gtk.gdk.Pixmap(None, 1, 1, visual.depth)
context = pixmap.cairo_create()
- if self.model.name is None or not self.model.name:
+ if self.name is None or not self.name:
name = _('Unnamed')
else:
- name = self.model.name
+ name = self.name
layout = context.create_layout()
layout.set_text(name)
@@ -186,10 +203,10 @@ class ThoughtView(CanvasElement):
CanvasElement.draw(self, context)
def _draw_background(self, context):
- if self.model.color is None or not self.model.color:
+ if self.color is None or not self.color:
color = style.Color('#FFFFFF')
else:
- color = style.Color(self.model.color)
+ color = style.Color(self.color)
r, g, b, a = color.get_rgba()
context.save()
@@ -208,8 +225,8 @@ class ThoughtView(CanvasElement):
width += self._PADDING * 2
height += self._PADDING * 2
- x = self.model.x + self._PADDING
- y = self.model.y + self._PADDING
+ x = self.x + self._PADDING
+ y = self.y + self._PADDING
context.translate(x, y)
context.show_layout(layout)
context.restore()
@@ -226,8 +243,8 @@ class ThoughtView(CanvasElement):
context.set_source_rgb(0, 0, 0)
context.set_line_width(self._LINE_WIDTH)
- x = self.model.x + self._LINE_WIDTH / 2
- y = self.model.y + self._LINE_WIDTH / 2
+ x = self.x + self._LINE_WIDTH / 2
+ y = self.y + self._LINE_WIDTH / 2
rect_width = width - self._LINE_WIDTH
rect_height = height - self._LINE_WIDTH
@@ -235,11 +252,6 @@ class ThoughtView(CanvasElement):
context.stroke()
context.restore()
- def __model_changed_cb(self, **kwargs):
- self.x = self.model.x
- self.y = self.model.y
- self.invalidate()
-
def get_rect(self):
if -1 in (self._last_width, self._last_height):
layout = self._get_name_layout()
@@ -247,6 +259,6 @@ class ThoughtView(CanvasElement):
self._last_width = width + self._PADDING * 2
self._last_height = height + self._PADDING * 2
- return gtk.gdk.Rectangle(self.model.x, self.model.y,
+ return gtk.gdk.Rectangle(self.x, self.y,
self._last_width, self._last_height)