diff options
author | Aleksey Lim <alsroot@member.fsf.org> | 2009-04-04 20:25:01 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@member.fsf.org> | 2009-04-08 17:13:52 (GMT) |
commit | 08105a19d8f787b04a6e2be36a0f6e1c65680baa (patch) | |
tree | 9a10c808cc9d1f191da83e51e79f58b100a805ee /src/TextThought.py | |
parent | 8329a5d928caa9f5473f141ba33cbaf3bbd36391 (diff) |
Resize drawing and image thoughts before creating
Diffstat (limited to 'src/TextThought.py')
-rw-r--r-- | src/TextThought.py | 254 |
1 files changed, 119 insertions, 135 deletions
diff --git a/src/TextThought.py b/src/TextThought.py index 6d363f2..90a5954 100644 --- a/src/TextThought.py +++ b/src/TextThought.py @@ -23,27 +23,26 @@ import gtk import pango import utils -import BaseThought -import prefs -import UndoManager import os - import xml.dom +from BaseThought import * +import UndoManager +import prefs + UNDO_ADD_ATTR=64 UNDO_ADD_ATTR_SELECTION=65 UNDO_REMOVE_ATTR=66 UNDO_REMOVE_ATTR_SELECTION=67 -class TextThought (BaseThought.BaseThought): +class TextThought (ResizableThought): def __init__ (self, coords, pango_context, thought_number, save, undo, loading, background_color, foreground_color, name="thought"): - super (TextThought, self).__init__(save, name, undo, background_color, foreground_color) + super (TextThought, self).__init__(coords, save, name, undo, background_color, foreground_color) self.index = 0 self.end_index = 0 self.bytes = "" self.bindex = 0 - self.text_location = coords self.text_element = save.createTextNode ("GOOBAH") self.element.appendChild (self.text_element) self.layout = None @@ -54,6 +53,8 @@ class TextThought (BaseThought.BaseThought): self.attrlist = None self.attributes = pango.AttrList() self.current_attrs = [] + self.double_click = False + self.orig_text = None if prefs.get_direction () == gtk.TEXT_DIR_LTR: self.pango_context.set_base_dir (pango.DIRECTION_LTR) @@ -66,6 +67,7 @@ class TextThought (BaseThought.BaseThought): self.ul = (coords[0]-margin[0], coords[1] - margin[1]) else: self.ul = None + self.all_okay = True def index_from_bindex (self, bindex): @@ -196,7 +198,7 @@ class TextThought (BaseThought.BaseThought): self.emit("update-attrs", bold, italics, underline, pango_font) return show_text - def recalc_edges (self): + def recalc_text_edges (self): if (not hasattr(self, "layout")): return del self.layout @@ -216,22 +218,38 @@ class TextThought (BaseThought.BaseThought): self.layout.set_text (show_text) self.layout.set_attributes(self.attrlist) - (x,y) = self.layout.get_pixel_size () margin = utils.margin_required (utils.STYLE_NORMAL) + text_w, text_h = self.layout.get_pixel_size() + text_w += margin[0] + margin[2] + text_h += margin[1] + margin[3] + + self.width = max(self.width, text_w) + self.height = max(self.height, text_h) + + self.min_x = self.ul[0] + (self.width - text_w)/2 + margin[0] + self.min_y = self.ul[1] + (self.height - text_h)/2 + margin[1] + self.max_x = self.min_x + text_w + self.max_y = self.min_y + text_h + + """ if prefs.get_direction () == gtk.TEXT_DIR_LTR: self.text_location = (self.ul[0] + margin[0], self.ul[1] + margin[1]) - self.lr = (x + self.text_location[0]+margin[2], y + self.text_location[1] + margin[3]) + self.lr = (text_w + self.text_location[0]+margin[2], text_h + self.text_location[1] + margin[3]) else: self.layout.set_alignment (pango.ALIGN_RIGHT) tmp1 = self.ul[1] if not self.lr: - self.lr = (self.ul[0], self.ul[1] + y + margin[1] + margin[3]) - self.text_location = (self.lr[0] - margin[2] - x, self.ul[1] + margin[1]) - self.ul = (self.lr[0] - margin[0] - margin[2] - x, tmp1) + self.lr = (self.ul[0], self.ul[1] + text_h + margin[1] + margin[3]) + self.text_location = (self.lr[0] - margin[2] - text_w, self.ul[1] + margin[1]) + self.ul = (self.lr[0] - margin[0] - margin[2] - text_w, tmp1) + """ + + def recalc_edges (self): + self.lr = (self.ul[0]+self.width, self.ul[1]+self.height) + if not self.creating: + self.recalc_text_edges() def commit_text (self, context, string, mode, font_name): - if not self.editing: - self.emit ("begin_editing") self.set_font(font_name) self.add_text (string) self.recalc_edges () @@ -310,32 +328,14 @@ class TextThought (BaseThought.BaseThought): self.end_index = self.index def draw (self, context): + ResizableThought.draw(self, context) + + if self.creating: + return if not self.layout: self.recalc_edges () - if not self.editing: - # We should draw the entire bounding box around ourselves - # We should also have our coordinates figured out. If not, scream! - if not self.ul or not self.lr: - print "Warning: Trying to draw unfinished box "+str(self.identity)+". Aborting." - return - style = utils.STYLE_EXTENDED_CONTENT - if len (self.extended_buffer.get_text()) == 0: - style = utils.STYLE_NORMAL - utils.draw_thought_outline (context, self.ul, self.lr, self.background_color, self.am_selected, self.am_primary, style) - else: - ux, uy = self.ul - if prefs.get_direction() == gtk.TEXT_DIR_LTR: - context.move_to (ux, uy+5) - context.line_to (ux, uy) - context.line_to (ux+5, uy) - else: - lx = self.lr[0] - context.move_to (lx, uy+5) - context.line_to (lx, uy) - context.line_to (lx-5, uy) - context.stroke () - (textx, texty) = (self.text_location[0], self.text_location[1]) + (textx, texty) = (self.min_x, self.min_y) if self.am_primary: r, g, b = utils.primary_colors["text"] elif (self.foreground_color): @@ -361,35 +361,6 @@ class TextThought (BaseThought.BaseThought): context.set_source_rgb (0,0,0) context.stroke () - def begin_editing (self): - self.editing = True - self.emit ("update_links") - return True - - def finish_editing (self): - if not self.editing: - return - self.editing = False - self.end_index = self.index - self.emit ("update_links") - self.recalc_edges () - if len (self.text) == 0: - self.emit ("delete_thought") - - def includes (self, coords, mode): - if not self.ul or not self.lr or not coords: - return False - - inside = (coords[0] < self.lr[0] + self.sensitive) and \ - (coords[0] > self.ul[0] - self.sensitive) and \ - (coords[1] < self.lr[1] + self.sensitive) and \ - (coords[1] > self.ul[1] - self.sensitive) - if inside and self.editing: - self.emit ("change_mouse_cursor", gtk.gdk.XTERM) - elif inside: - self.emit ("change_mouse_cursor", gtk.gdk.LEFT_PTR) - return inside - def process_key_press (self, event, mode): modifiers = gtk.accelerator_get_default_mod_mask () shift = event.state & modifiers == gtk.gdk.SHIFT_MASK @@ -403,7 +374,7 @@ class TextThought (BaseThought.BaseThought): self.index = self.bindex = 0 self.end_index = len (self.text) elif event.keyval == gtk.keysyms.Escape: - self.emit ("finish_editing") + self.leave() elif event.keyval == gtk.keysyms.Left: if prefs.get_direction() == gtk.TEXT_DIR_LTR: self.move_index_back (shift) @@ -435,14 +406,17 @@ class TextThought (BaseThought.BaseThought): clear_attrs = False else: handled = False + if clear_attrs: del self.current_attrs self.current_attrs = [] + self.recalc_edges () self.selection_changed () self.emit ("title_changed", self.text) self.bindex = self.bindex_from_index (self.index) self.emit ("update_view") + return handled def undo_text_action (self, action, mode): @@ -470,7 +444,6 @@ class TextThought (BaseThought.BaseThought): self.attributes = pango.AttrList() map(lambda a : self.attributes.change(a), attrs) self.recalc_edges () - self.emit ("begin_editing") self.emit ("title_changed", self.text) self.emit ("update_view") self.emit ("grab_focus", False) @@ -635,7 +608,7 @@ class TextThought (BaseThought.BaseThought): def move_index_back (self, mod): if self.index <= 0: - self.end_index = self.index + self.index = 0 return self.index -= int(self.bytes[self.bindex-1]) if not mod: @@ -643,7 +616,7 @@ class TextThought (BaseThought.BaseThought): def move_index_forward (self, mod): if self.index >= len(self.text): - self.end_index = self.index + self.index = len(self.text) return self.index += int(self.bytes[self.bindex]) if not mod: @@ -653,7 +626,6 @@ class TextThought (BaseThought.BaseThought): tmp = self.text.decode () lines = tmp.splitlines () if len (lines) == 1: - self.end_index = self.index return loc = 0 line = 0 @@ -665,7 +637,6 @@ class TextThought (BaseThought.BaseThought): break line+=1 if line == -1: - self.end_index = self.index return elif line >= len (lines): self.bindex -= len (lines[-1])+1 @@ -689,7 +660,6 @@ class TextThought (BaseThought.BaseThought): tmp = self.text.decode () lines = tmp.splitlines () if len (lines) == 1: - self.end_index = self.index return loc = 0 line = 0 @@ -699,7 +669,6 @@ class TextThought (BaseThought.BaseThought): break line += 1 if line >= len (lines)-1: - self.end_index = self.index return dist = self.bindex - (loc - len (lines[line]))+1 self.bindex = loc @@ -726,15 +695,19 @@ class TextThought (BaseThought.BaseThought): return line += 1 - def process_button_down (self, event, mode, transformed): + def process_button_down (self, event, coords): + if ResizableThought.process_button_down(self, event, coords): + return True + + if not self.editing: + return False + modifiers = gtk.accelerator_get_default_mod_mask () if event.button == 1: - if event.type == gtk.gdk.BUTTON_PRESS and not self.editing: - self.emit ("select_thought", event.state & modifiers) - elif event.type == gtk.gdk.BUTTON_PRESS and self.editing: - x = int ((transformed[0] - self.ul[0])*pango.SCALE) - y = int ((transformed[1] - self.ul[1])*pango.SCALE) + if event.type == gtk.gdk.BUTTON_PRESS: + x = int ((coords[0] - self.min_x)*pango.SCALE) + y = int ((coords[1] - self.min_y)*pango.SCALE) loc = self.layout.xy_to_index (x, y) self.index = loc[0] if loc[0] >= len(self.text) -1 or self.text[loc[0]+1] == '\n': @@ -742,15 +715,14 @@ class TextThought (BaseThought.BaseThought): self.bindex = self.bindex_from_index (self.index) if not (event.state & modifiers) & gtk.gdk.SHIFT_MASK: self.end_index = self.index - elif mode == BaseThought.MODE_EDITING and event.type == gtk.gdk._2BUTTON_PRESS: - if self.editing: - self.move_index_horizontal(False) # go to the end - self.index = 0 # and mark all - else: - self.emit ("begin_editing") - elif event.button == 2 and self.editing: - x = int ((transformed[0] - self.ul[0])*pango.SCALE) - y = int ((transformed[1] - self.ul[1])*pango.SCALE) + elif event.type == gtk.gdk._2BUTTON_PRESS: + self.index = len(self.text) + self.end_index = 0 # and mark all + self.selection_changed () + self.double_click = True + elif event.button == 2: + x = int ((coords[0] - self.min_x)*pango.SCALE) + y = int ((coords[1] - self.min_y)*pango.SCALE) loc = self.layout.xy_to_index (x, y) self.index = loc[0] if loc[0] >= len(self.text) -1 or self.text[loc[0]+1] == '\n': @@ -760,46 +732,53 @@ class TextThought (BaseThought.BaseThought): if os.name != 'nt': clip = gtk.Clipboard (selection="PRIMARY") self.paste_text (clip) - elif event.button == 3: - self.emit ("popup_requested", event, 1) del self.current_attrs self.current_attrs = [] self.recalc_edges() self.emit ("update_view") - def process_button_release (self, event, unending_link, mode, transformed): - if unending_link: - unending_link.set_child (self) - self.emit ("claim_unending_link") + def process_button_release (self, event, transformed): + if self.orig_size: + if self.creating: + orig_size = self.width >= MIN_SIZE or self.height >= MIN_SIZE + self.width = orig_size and max(MIN_SIZE, self.width) or DEFAULT_WIDTH + self.height = orig_size and max(MIN_SIZE, self.height) or DEFAULT_HEIGHT + self.recalc_edges() + self.creating = False + else: + self.undo.add_undo (UndoManager.UndoAction (self, UNDO_RESIZE, \ + self.undo_resize, self.orig_size, (self.ul, self.width, self.height))) + + self.double_click = False + return ResizableThought.process_button_release(self, event, transformed) def selection_changed (self): (start, end) = (min(self.index, self.end_index), max(self.index, self.end_index)) self.emit ("text_selection_changed", start, end, self.text[start:end]) - def handle_motion (self, event, mode, transformed): - if event.state & gtk.gdk.BUTTON1_MASK and self.editing: - if transformed[0] < self.lr[0] and transformed[0] > self.ul[0] and \ - transformed[1] < self.lr[1] and transformed[1] > self.ul[1]: - x = int ((transformed[0] - self.ul[0])*pango.SCALE) - y = int ((transformed[1] - self.ul[1])*pango.SCALE) + def handle_motion (self, event, transformed): + if ResizableThought.handle_motion(self, event, transformed): + self.recalc_edges() + return True + + if not self.editing or self.resizing: + return False + + if event.state & gtk.gdk.BUTTON1_MASK and not self.double_click: + if transformed[0] < self.max_x and transformed[0] > self.min_x and \ + transformed[1] < self.max_y and transformed[1] > self.min_y: + x = int ((transformed[0] - self.min_x)*pango.SCALE) + y = int ((transformed[1] - self.min_y)*pango.SCALE) loc = self.layout.xy_to_index (x, y) self.index = loc[0] if loc[0] >= len(self.text) -1 or self.text[loc[0]+1] == '\n': self.index += loc[1] self.bindex = self.bindex_from_index (self.index) self.selection_changed () - elif mode == BaseThought.MODE_EDITING: - self.emit ("finish_editing") - self.emit ("create_link", \ - (self.ul[0]-((self.ul[0]-self.lr[0]) / 2.), self.ul[1]-((self.ul[1]-self.lr[1]) / 2.))) return True - elif event.state & gtk.gdk.BUTTON1_MASK and not self.editing and \ - mode == BaseThought.MODE_EDITING and not event.state & gtk.gdk.CONTROL_MASK: - self.emit ("create_link", \ - (self.ul[0]-((self.ul[0]-self.lr[0]) / 2.), self.ul[1]-((self.ul[1]-self.lr[1]) / 2.))) - self.recalc_edges() - self.emit ("update_view") + + return False def export (self, context, move_x, move_y): utils.export_thought_outline (context, self.ul, self.lr, self.background_color, self.am_selected, self.am_primary, utils.STYLE_NORMAL, @@ -807,7 +786,7 @@ class TextThought (BaseThought.BaseThought): r,g,b = utils.gtk_to_cairo_color (self.foreground_color) context.set_source_rgb (r, g, b) - context.move_to (self.text_location[0]+move_x, self.text_location[1]+move_y) + context.move_to (self.min_x+move_x, self.min_y+move_y) context.show_layout (self.layout) context.set_source_rgb (0,0,0) context.stroke () @@ -832,19 +811,11 @@ class TextThought (BaseThought.BaseThought): except xml.dom.NotFoundErr: pass self.element.setAttribute ("cursor", str(self.index)) - self.element.setAttribute ("selection_end", str(self.end_index)) self.element.setAttribute ("ul-coords", str(self.ul)) self.element.setAttribute ("lr-coords", str(self.lr)) self.element.setAttribute ("identity", str(self.identity)) self.element.setAttribute ("background-color", utils.color_to_string(self.background_color)) self.element.setAttribute ("foreground-color", utils.color_to_string(self.foreground_color)) - if self.editing: - self.element.setAttribute ("edit", "true") - else: - try: - self.element.removeAttribute ("edit") - except xml.dom.NotFoundErr: - pass if self.am_selected: self.element.setAttribute ("current_root", "true") else: @@ -918,14 +889,15 @@ class TextThought (BaseThought.BaseThought): def load (self, node): self.index = int (node.getAttribute ("cursor")) - if node.hasAttribute ("selection_end"): - self.end_index = int (node.getAttribute ("selection_end")) - else: - self.end_index = self.index + self.end_index = self.index tmp = node.getAttribute ("ul-coords") self.ul = utils.parse_coords (tmp) tmp = node.getAttribute ("lr-coords") self.lr = utils.parse_coords (tmp) + + self.width = self.lr[0] - self.ul[0] + self.height = self.lr[1] - self.ul[1] + self.identity = int (node.getAttribute ("identity")) try: tmp = node.getAttribute ("background-color") @@ -935,12 +907,6 @@ class TextThought (BaseThought.BaseThought): except ValueError: pass - if node.hasAttribute ("edit"): - self.editing = True - else: - self.editing = False - self.end_index = self.index - self.am_selected = node.hasAttribute ("current_root") self.am_primary = node.hasAttribute ("primary_root") @@ -968,7 +934,7 @@ class TextThought (BaseThought.BaseThought): else: print "Unknown: "+n.nodeName self.rebuild_byte_table () - self.recalc_edges () + self.recalc_edges() def copy_text (self, clip): if self.end_index > self.index: @@ -1229,6 +1195,24 @@ class TextThought (BaseThought.BaseThought): old_attrs, self.attributes.copy())) self.recalc_edges() - - def get_popup_menu_items(self): - return [] + + def inside(self, inside): + if self.editing: + self.emit ("change_mouse_cursor", gtk.gdk.XTERM) + else: + ResizableThought.inside(self, inside) + + def enter(self): + if self.editing: + return + self.orig_text = self.text + self.editing = True + + def leave(self): + if not self.editing: + return + ResizableThought.leave(self) + self.editing = False + self.end_index = self.index + self.emit ("update_links") + self.recalc_edges () |