[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r8364 - in trunk/gnue-designer/src: forms/PagePainter/skins ui/wx
From: |
jcater |
Subject: |
[gnue] r8364 - in trunk/gnue-designer/src: forms/PagePainter/skins ui/wx/uihelpers/doccanvas |
Date: |
Wed, 5 Apr 2006 00:10:59 -0500 (CDT) |
Author: jcater
Date: 2006-04-05 00:10:58 -0500 (Wed, 05 Apr 2006)
New Revision: 8364
Modified:
trunk/gnue-designer/src/forms/PagePainter/skins/common.py
trunk/gnue-designer/src/forms/PagePainter/skins/default.py
trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py
trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/widget.py
Log:
Selecting and moving page objects now work again via mouse
Pages can be resized with a mouse.
Pages can be moved on the workspace via the mouse.
Pages are drawn with a dropshadow.
Misc bug fixes.
Modified: trunk/gnue-designer/src/forms/PagePainter/skins/common.py
===================================================================
--- trunk/gnue-designer/src/forms/PagePainter/skins/common.py 2006-04-05
02:35:12 UTC (rev 8363)
+++ trunk/gnue-designer/src/forms/PagePainter/skins/common.py 2006-04-05
05:10:58 UTC (rev 8364)
@@ -68,8 +68,8 @@
# This gives us an offset onto the current drawing canvas
# accounting for any workspace margins.
- documentX = canvas.document_origin_x
- documentY = canvas.document_origin_y
+ doc_x = canvas.document_origin_x
+ doc_y = canvas.document_origin_y
# Right now, only Char positioning is supported.
try:
@@ -79,20 +79,20 @@
x = y = 0
try:
- w = object['Char:width']
+ width = object['Char:width']
except KeyError:
- w = self.char_default_width
+ width = self.char_default_width
try:
- h = object['Char:height']
+ height = object['Char:height']
except KeyError:
- h = self.char_default_height
+ height = self.char_default_height
# Convert from Char positions into wx positions
x *= char_x_scale
y *= char_y_scale
- w *= char_x_scale
- h *= char_y_scale
+ width *= char_x_scale
+ height *= char_y_scale
# Used to figure in compensation needed for selection box
# decorations and borders
@@ -101,26 +101,80 @@
# Save the area, relative to the canvas, of the area
# that needs to be refreshed when this widget changes.
# (Includes all generic decoration, like selection borders)
- self.refresh_area = wx.Rect(x + documentX - compensation,
- y + documentY - compensation,
- w + compensation * 2,
- h + compensation * 2)
+ self.refresh_area = wx.Rect(x + doc_x - compensation,
+ y + doc_y - compensation,
+ width + compensation * 2,
+ height + compensation * 2)
# Save the area, relative to the canvas, of the area
# that the widget sans decorations occupy on the
- self.hit_test_area = wx.Rect(x + documentX,
- y + documentY,
- w, h)
+ self.hit_test_area = wx.Rect(x + doc_x,
+ y + doc_y,
+ width, height)
# Save the area, relative to being drawn in a context at (0,0)
- self.draw_area = wx.Rect(compensation, compensation, w, h)
+ self.draw_area = wx.Rect(compensation, compensation, width, height)
- def draw_decorations(self, dc):
+ def draw_decorations(self, target_dc):
# TODO: eventually, this will show tab-order icons
pass
+ def move_from_canvas(self, delta_x, delta_y):
+ """
+ Called when the object is moved via mouse
+ """
+ self.force_canvas_refresh()
+
+ delta_char_x = int(round(delta_x / float(char_x_scale)))
+ delta_char_y = int(round(delta_y / float(char_y_scale)))
+
+ if delta_char_x or delta_char_y:
+ char_x = self.gobject['Char:x'] + delta_char_x
+ char_y = self.gobject['Char:y'] + delta_char_y
+
+ # TODO: see if the object was dropped into a new
+ # container object
+
+ self.gobject['Char:x'] = char_x
+ self.gobject['Char:y'] = char_y
+
+ # Standard boilerplate stuff
+ self.recalc_metrics()
+ self.force_canvas_refresh()
+
+
+ def resize_from_canvas(self, delta_width, delta_height):
+ """
+ Called when the object is resized via mouse.
+ """
+ self.force_canvas_refresh()
+
+ delta_char_width = int(round(delta_width / float(char_x_scale)))
+ delta_char_height = int(round(delta_height / float(char_y_scale)))
+
+ if delta_char_width or delta_char_height:
+ char_width = min(max(delta_char_width +
+ self.gobject['Char:width'],
+ self.char_min_width),
+ self.char_max_width)
+
+ char_height = min(max(delta_char_height +
+ self.gobject['Char:height'],
+ self.char_min_height),
+ self.char_max_height)
+
+ if delta_char_width:
+ self.gobject['Char:width'] = char_width
+ if delta_char_height:
+ self.gobject['Char:height'] = char_height
+
+ self.recalc_metrics()
+ self.force_canvas_refresh()
+
+
+
class ContainerWidget(FormWidget):
"""
A widget that can be a container
Modified: trunk/gnue-designer/src/forms/PagePainter/skins/default.py
===================================================================
--- trunk/gnue-designer/src/forms/PagePainter/skins/default.py 2006-04-05
02:35:12 UTC (rev 8363)
+++ trunk/gnue-designer/src/forms/PagePainter/skins/default.py 2006-04-05
05:10:58 UTC (rev 8364)
@@ -91,14 +91,14 @@
# Save the area, relative to the canvas, of the area
# that needs to be refreshed when this widget changes.
# (Includes all generic decoration, like selection borders)
- self.refresh_area = wx.Rect(x + x_offset - compensation,
+ self.refresh_area = wx.Rect(x + x_offset - compensation,
y + y_offset - compensation,
width + compensation * 2,
height + compensation * 2)
# Save the area, relative to the canvas, of the area
# that the widget sans decorations occupy on the
- self.hit_test_area = wx.Rect(x + x_offset,
+ self.hit_test_area = wx.Rect(x + x_offset,
y + y_offset,
width, height)
self.hit_test_exclusions = [
@@ -111,14 +111,78 @@
self.draw_area = wx.Rect(compensation, compensation, width, height)
- def draw_widget(self, dc):
- dc.SetPen(wx.Pen(color_map['widget']))
- dc.SetBrush(wx.Brush(color_map['panel'], style=wx.SOLID))
+ def draw_widget(self, target_dc):
object = self.gobject
x, y, width, height = self.draw_area.Get()
- dc.DrawRectangle(x, y, width, height)
+ target_dc.SetPen(wx.Pen(color_map['widgetdark']))
+ target_dc.SetBrush(wx.Brush(color_map['widgetdark'], style=wx.SOLID))
+ target_dc.DrawRectangle(x+2, y+2, width, height)
+ target_dc.SetPen(wx.Pen(color_map['widget']))
+ target_dc.SetBrush(wx.Brush(color_map['panel'], style=wx.SOLID))
+ target_dc.DrawRectangle(x, y, width, height)
+
+
+ def move_from_canvas(self, delta_x, delta_y):
+ """
+ Called when the object is moved via mouse.
+
+ For Page objects, this doesn't really change the GObject.
+ It only changes the canvas' document offset.
+ """
+ self.force_canvas_refresh()
+
+ rounded_x = (self.canvas.document_origin_x +
+ int(round(delta_x / float(common.char_x_scale)))
+ * common.char_x_scale)
+ rounded_y = (self.canvas.document_origin_y +
+ int(round(delta_y / float(common.char_y_scale)))
+ * common.char_y_scale)
+
+ if rounded_x != self.canvas.document_origin_x or \
+ rounded_y != self.canvas.document_origin_y:
+ self.canvas.document_origin_x = rounded_x
+ self.canvas.document_origin_y = rounded_y
+
+ # Force all of the widgets to recalculate their display metrics
+ self.canvas.recalc_metrics()
+
+
+
+ def resize_from_canvas(self, delta_width, delta_height):
+ """
+ Called when the object is resized via mouse.
+ """
+ self.force_canvas_refresh()
+
+ object = self.gobject.findParentOfType('GFLayout')
+
+ delta_char_width = int(round(delta_width /
+ float(common.char_x_scale)))
+ delta_char_height = int(round(delta_height /
+ float(common.char_y_scale)))
+
+ if delta_char_width or delta_char_height:
+ char_width = min(max(delta_char_width +
+ object['Char:width'],
+ self.char_min_width),
+ self.char_max_width)
+
+ char_height = min(max(delta_char_height +
+ object['Char:height'],
+ self.char_min_height),
+ self.char_max_height)
+
+ if delta_char_width:
+ object['Char:width'] = char_width
+ if delta_char_height:
+ object['Char:height'] = char_height
+
+ self.recalc_metrics()
+ self.force_canvas_refresh()
+
+
# --------------------------------------------------------------------------
# Label
# --------------------------------------------------------------------------
@@ -126,16 +190,16 @@
char_max_height = 1
- def draw_widget(self, dc):
- dc.SetPen(wx.Pen(color_map['text']))
- dc.SetBrush(wx.Brush(wx.WHITE, style=wx.TRANSPARENT))
+ def draw_widget(self, target_dc):
+ target_dc.SetPen(wx.Pen(color_map['text']))
+ target_dc.SetBrush(wx.Brush(wx.WHITE, style=wx.TRANSPARENT))
object = self.gobject
x, y, width, height = self.draw_area.Get()
- dc.SetFont(font_map['label'])
+ target_dc.SetFont(font_map['label'])
# Center each character in its cell
for char in object['text']:
- text_width, text_height = dc.GetTextExtent(char)
- dc.DrawText(char,
+ text_width, text_height = target_dc.GetTextExtent(char)
+ target_dc.DrawText(char,
x + (common.char_x_scale - text_width) // 2,
y + 1)
x += common.char_x_scale
@@ -162,29 +226,29 @@
# Entry
# --------------------------------------------------------------------------
class EntryWidget(FormWidget):
- def draw_widget(self, dc):
- dc.SetPen(wx.Pen(color_map['widget']))
- dc.SetBrush(wx.Brush(color_map['widgetback']))
+ def draw_widget(self, target_dc):
+ target_dc.SetPen(wx.Pen(color_map['widget']))
+ target_dc.SetBrush(wx.Brush(color_map['widgetback']))
x, y, width, height = self.draw_area.Get()
- dc.DrawRectangle(x, y, width, height - 1)
+ target_dc.DrawRectangle(x, y, width, height - 1)
# --------------------------------------------------------------------------
# Button
# --------------------------------------------------------------------------
class ButtonWidget(FormWidget):
- def draw_widget(self, dc):
- dc.SetPen(wx.Pen(color_map['widget']))
- dc.SetBrush(wx.Brush(color_map['widgetback']))
+ def draw_widget(self, target_dc):
+ target_dc.SetPen(wx.Pen(color_map['widget']))
+ target_dc.SetBrush(wx.Brush(color_map['widgetback']))
x, y, width, height = self.draw_area.Get()
- dc.DrawRoundedRectangle(x, y, width, height - 1, 4)
+ target_dc.DrawRoundedRectangle(x, y, width, height - 1, 4)
# Draw the text, centered in the button
- dc.SetFont(font_map['button'])
+ target_dc.SetFont(font_map['button'])
text = self.gobject['label']
- text_width, text_height = dc.GetTextExtent(text)
+ text_width, text_height = target_dc.GetTextExtent(text)
- dc.DrawText(text,
+ target_dc.DrawText(text,
x + width // 2 - text_width // 2,
y + height // 2 - text_height // 2 - 2)
@@ -210,9 +274,9 @@
# Box
# --------------------------------------------------------------------------
class BoxWidget(ContainerWidget):
- def draw_widget(self, dc):
- dc.SetPen(wx.Pen(color_map['text']))
- dc.SetBrush(wx.Brush(wx.WHITE, style=wx.TRANSPARENT))
+ def draw_widget(self, target_dc):
+ target_dc.SetPen(wx.Pen(color_map['text']))
+ target_dc.SetBrush(wx.Brush(wx.WHITE, style=wx.TRANSPARENT))
object = self.gobject
x, y, width, height = self.draw_area.Get()
@@ -222,26 +286,26 @@
y2 = y + height - common.char_y_scale // 2
# Draw the lines
- dc.SetFont(font_map['box'])
+ target_dc.SetFont(font_map['box'])
text = self.gobject['label']
- text_width, text_height = text_extents = dc.GetTextExtent(text)
+ text_width, text_height = text_extents = target_dc.GetTextExtent(text)
- dc.SetPen(wx.Pen(color_map['widgetdark']))
- dc.DrawLine(x1 + 1, y2, x2, y2) # Bottom
- dc.DrawLine(x2, y1 + 1, x2, y2) # Right
+ target_dc.SetPen(wx.Pen(color_map['widgetdark']))
+ target_dc.DrawLine(x1 + 1, y2, x2, y2) # Bottom
+ target_dc.DrawLine(x2, y1 + 1, x2, y2) # Right
- dc.SetPen(wx.Pen(color_map['widgetlight']))
- dc.DrawLine(x1, y1 + 1, x1, y2) # Left
- dc.DrawLine(x1 + 1, # Top
- y1, x + int(common.char_x_scale * 1.5) - 4, y1)
- dc.DrawLine(x + int(common.char_x_scale * 1.5) + 3 + text_width,
+ target_dc.SetPen(wx.Pen(color_map['widgetlight']))
+ target_dc.DrawLine(x1, y1 + 1, x1, y2) # Left
+ target_dc.DrawLine(x1 + 1, # Top
+ y1, x + int(common.char_x_scale * 2) - 4, y1)
+ target_dc.DrawLine(x + int(common.char_x_scale * 2) + 3 + text_width,
y1, x2, y1)
# and draw the text
- dc.SetPen(wx.Pen(color_map['text']))
- dc.DrawText(text,
- x + int(common.char_x_scale * 1.5),
+ target_dc.SetPen(wx.Pen(color_map['text']))
+ target_dc.DrawText(text,
+ x + int(common.char_x_scale * 2),
y + common.char_y_scale // 2 - text_height // 2)
def enter_edit_mode(self):
@@ -266,10 +330,10 @@
# Unknown/unimplemented widgets
# --------------------------------------------------------------------------
class UnknownWidget(FormWidget):
- def draw_widget(self, dc):
- dc.SetPen(wx.Pen(color_map['widget']))
- dc.SetBrush(wx.Brush(color_map['widget'], style=wx.CROSSDIAG_HATCH))
+ def draw_widget(self, target_dc):
+ target_dc.SetPen(wx.Pen(color_map['widget']))
+ target_dc.SetBrush(wx.Brush(color_map['widget'],
style=wx.CROSSDIAG_HATCH))
object = self.gobject
x, y, width, height = self.draw_area.Get()
- dc.SetFont(font_map['label'])
- dc.DrawRoundedRectangle(x, y, width, height - 1, 4)
+ target_dc.SetFont(font_map['label'])
+ target_dc.DrawRoundedRectangle(x, y, width, height - 1, 4)
Modified: trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py
===================================================================
--- trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py 2006-04-05
02:35:12 UTC (rev 8363)
+++ trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py 2006-04-05
05:10:58 UTC (rev 8364)
@@ -200,7 +200,7 @@
self.__mouse_hot_spots = []
- # The updateRegion is not in scrolled coordinates.
+ # The update_area is not in scrolled coordinates.
scroll_x, scroll_y = self.CalcUnscrolledPosition(0, 0)
selection_area = None
@@ -212,7 +212,7 @@
refresh_area = widget.refresh_area
(obj_x, obj_y,
- obj_width, obj_height) = refresh_area.Get()
+ obj_width, obj_height) = refresh_area.Get()
# Calculate the area, offset by the scrollwindow's origin
area = wx.Rect(obj_x - scroll_x,
@@ -235,12 +235,9 @@
# Not sure why we have to do this, but it makes the
# box draw correctly.
- sel_x += 2
- sel_y += 2
- sel_w -= 4
- sel_h -= 4
+ selection_area = wx.Rect(sel_x + 2, sel_y + 2,
+ sel_w - 4, sel_h - 4)
- selection_area = wx.Rect(sel_x,sel_y,sel_w,sel_h)
self.refresh_scrolled_area(selection_area)
self.__selection_area = selection_area
@@ -254,7 +251,7 @@
Catch the wx OnPaint event and draw the canvas and any widgets
"""
- # The updateRegion is not in scrolled coordinates.
+ # The update_area is not in scrolled coordinates.
(scroll_x,
scroll_y) = self.CalcUnscrolledPosition(0, 0)
@@ -315,7 +312,7 @@
Draw the individual widgets
"""
- updateRegion = self.GetUpdateRegion()
+ update_area = self.GetUpdateRegion()
(scroll_x,
scroll_y) = self.CalcUnscrolledPosition(0, 0)
@@ -335,7 +332,7 @@
obj_width, obj_height)
- if (updateRegion.ContainsRect(area) != wx.OutRegion and
+ if (update_area.ContainsRect(area) != wx.OutRegion and
widget.visible):
target_dc.SetDeviceOrigin(obj_x + dc_x, obj_y + dc_y)
@@ -542,10 +539,10 @@
self.selected_from_canvas(widgets)
elif current_action == 'move':
- self.__stop_moving()
+ self.__stop_moving(x, y)
elif current_action == 'resize':
- self.__stop_resizing()
+ self.__stop_resizing(x, y)
self.__mouse_current_action = ''
@@ -749,8 +746,8 @@
memory_dc.SetDeviceOrigin(0,0)
# Draw a selection box
- sx, sy, sw, sh = self.__selection_area.Get()
- self.__draw_selection_box(memory_dc, 2, 2, sw, sh)
+ sel_x, sel_y, sel_w, sel_h = self.__selection_area.Get()
+ self.__draw_selection_box(memory_dc, 2, 2, sel_w, sel_h)
memory_dc.EndDrawing()
@@ -758,6 +755,8 @@
self.__mouse_move_dy = y - buff_y
self.__mouse_move_buffer = memory_dc
self.__mouse_move_area = area
+ self.__mouse_move_start_x = x
+ self.__mouse_move_start_y = y
# Hide the real widgets
self.refresh_scrolled_area(area)
@@ -775,7 +774,7 @@
self.refresh_scrolled_area(old_area.Union(self.__mouse_move_area))
- def __stop_moving(self):
+ def __stop_moving(self, x, y):
"""
Erase the "moving" feedback
"""
@@ -793,6 +792,10 @@
for widget in self.__mouse_move_items:
widget.selected = True
widget.show()
+ if x != self.__mouse_move_start_x or \
+ y != self.__mouse_move_start_y:
+ widget.move_from_canvas(x - self.__mouse_move_start_x,
+ y - self.__mouse_move_start_y)
self.__mouse_move_items = None
self.refresh_selection()
@@ -852,7 +855,7 @@
start_y2 = start_y + start_height - 1
# The anchor point and changable points
- # varie based on the resize orientation.
+ # vary based on the resize orientation.
if orientation == 'left':
start_x += delta_x
elif orientation == 'right':
@@ -884,16 +887,45 @@
target_dc.EndDrawing()
- def __stop_resizing(self):
+ def __stop_resizing(self, x, y):
"""
Erase the resizing feedback
"""
+ self.begin_refresh_batch()
+
self.ReleaseMouse()
self.__update_resizing(None, None)
self.__hide_selection_frame = False
self.refresh_scrolled_area(self.__mouse_resize_orig_area)
+ # If there was no mouse movement, no need to do the logic
+ if self.__mouse_resize_last_area:
+ delta_width = self.__mouse_resize_start_x - x
+ delta_height = self.__mouse_resize_start_y - y
+
+ # First, determine if the widget moved while being resized
+ orientation = self.__mouse_resize_orientation
+ delta_x = 0
+ delta_y = 0
+ if orientation in ('left','ul','ll') and delta_width:
+ delta_x = -delta_width
+ if orientation in ('top','ul','ur') and delta_height:
+ delta_y = -delta_height
+
+ # Figure out the resize amount
+ for widget in self.get_selected_widgets():
+ if delta_x or delta_y:
+ widget.move_from_canvas(delta_x, delta_y)
+ if delta_width or delta_height:
+ widget.resize_from_canvas(delta_width, delta_height)
+
+ # Recalculate the selection box
+ self.refresh_selection()
+
+ self.end_refresh_batch()
+
+
# ---------------------------------------------------------------
# Support for click and drag rubberband boxes
# ---------------------------------------------------------------
@@ -1027,6 +1059,13 @@
self.refresh_scrolled_area(refresh_area)
widget.Destroy()
+ def recalc_metrics(self):
+ """
+ Recalculates all of the widgets' metrics info
+ """
+ for widget in self.ordered_widget_list:
+ widget.recalc_metrics()
+
# ---------------------------------------------------------------
# Local mouse events
# ---------------------------------------------------------------
Modified: trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/widget.py
===================================================================
--- trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/widget.py 2006-04-05
02:35:12 UTC (rev 8363)
+++ trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/widget.py 2006-04-05
05:10:58 UTC (rev 8364)
@@ -37,18 +37,12 @@
from textedit import PopupTextEdit
-# NOTE: any methods using MixedCaseNaming are left over from
-# SimpleCanvas and probably aren't used yet. But, the code
-# is left as an example for when I get around to implementing
-# that feature.
-
# ===================================================================
# A Drawable canvas widget
# ===================================================================
class DocumentWidget:
def __init__(self, gobject, canvas):
- #super(DocumentWidget, self).__init__()
self.gobject = gobject
@@ -58,7 +52,7 @@
# Coordinates (relative to canvas) that should register hit tests
self.hit_test_area = wx.Rect()
- self.hit_test_exclusions = [] # Can be a list of wx.Rect()
+ self.hit_test_exclusions = [] # Can be a list of wx.Rect()s
# Coordinates (relative to canvas) to refresh on widget updates
self.refresh_area = wx.Rect()
@@ -67,18 +61,7 @@
self.recalc_metrics()
- def drag_move(self, x, y):
- self.force_canvas_refresh()
- self.recalc_metrics()
- self.force_canvas_refresh()
-
- def drag_resize(self, width, height):
- self.force_canvas_refresh()
- # TODO
- self.force_canvas_refresh()
-
-
def show(self, show=True):
# Make sure show is a Boolean
show = bool(show)
@@ -183,7 +166,7 @@
if result:
# If the entire dragRect is in an exclusion area, return false
for exclusion in self.hit_test_exclusions:
- if exclusion.Intersect(area) == area:
+ if wx.IntersectRect(exclusion, area) == area:
return False
return result
@@ -226,6 +209,11 @@
"""
self.set_selected()
+ def context_menu(self, x, y):
+ """
+ """
+ self.canvas.PopupMenu(self.gobject._popupMenu, (x,y))
+
# ====================================================================
# You *must* implement the following functions
# ====================================================================
@@ -293,7 +281,19 @@
"""
pass
- def context_menu(self, x, y):
+
+ def move_from_canvas(self, delta_x, delta_y):
"""
+ Called when the object is moved via mouse.
+ Coordinates are relative from widget's (0,0)
"""
- self.canvas.PopupMenu(self.gobject._popupMenu, (x,y))
+ assert(False)
+
+
+ def resize_from_canvas(self, delta_width, delta_height):
+ """
+ Called when the object is resized via mouse.
+ Measurements are relative from the widgets original size
+ (i.e., delta_width = 0 means the width did not change)
+ """
+ assert(False)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r8364 - in trunk/gnue-designer/src: forms/PagePainter/skins ui/wx/uihelpers/doccanvas,
jcater <=