def __init__(self):
        gtk.EventBox.__init__(self)
        self.box = FloatBox()
        self.pref_box = gtk.EventBox()
        self.form = Target()
        self.element_factory = ElementFactory()
        self.element_view = ElementView(self.element_factory)
        self.add(self.box)
        self.box.connect('key-press-event', self._on_box_key_press)
        self.box.connect('motion-notify-event', self._on_box_motion_notify)
        self.box.connect('button-press-event', self._on_box_button_press)
        self.box.connect('button-release-event', self._on_box_button_release)
        self.element_view.connect('element-button-press-event',
                                  self._on_element_button_press_event)

        hbox = gtk.HBox()
        vbox = gtk.VBox()
        vbox.pack_start(self.element_view, False)
        hbox.pack_start(vbox, False)
        hbox.pack_start(self.form)
        hbox.pack_start(self.pref_box, False)
        hbox.set_spacing(6)
        self.box.add_bg_widget(hbox)
        self.pref_box.set_size_request(200, -1)
        self.selected = None
        self.mouse_button = None

        # Load built-in widgets.
        for name in sorted(Elements.__all__):
            if name in ('Element', 'Target'):
                continue
            element_class = Elements.__dict__[name]
            if type(element_class) != gobject.GObjectMeta:
                continue
            self.element_factory.register(element_class)
示例#2
0
    def __init__(self):
        gtk.EventBox.__init__(self)
        self.box = FloatBox()
        self.pref_box = gtk.EventBox()
        self.form = Target()
        self.element_factory = ElementFactory()
        self.element_view = ElementView(self.element_factory)
        self.add(self.box)
        self.box.connect("key-press-event", self._on_box_key_press)
        self.box.connect("motion-notify-event", self._on_box_motion_notify)
        self.box.connect("button-press-event", self._on_box_button_press)
        self.box.connect("button-release-event", self._on_box_button_release)
        self.element_view.connect("element-button-press-event", self._on_element_button_press_event)

        hbox = gtk.HBox()
        vbox = gtk.VBox()
        vbox.pack_start(self.element_view, False)
        hbox.pack_start(vbox, False)
        hbox.pack_start(self.form)
        hbox.pack_start(self.pref_box, False)
        hbox.set_spacing(6)
        self.box.add_bg_widget(hbox)
        self.pref_box.set_size_request(200, -1)
        self.selected = None
        self.mouse_button = None

        # Load built-in widgets.
        for name in sorted(Elements.__all__):
            if name in ("Element", "Target"):
                continue
            element_class = Elements.__dict__[name]
            if type(element_class) != gobject.GObjectMeta:
                continue
            self.element_factory.register(element_class)
class Workspace(gtk.EventBox):
    def __init__(self):
        gtk.EventBox.__init__(self)
        self.box = FloatBox()
        self.pref_box = gtk.EventBox()
        self.form = Target()
        self.element_factory = ElementFactory()
        self.element_view = ElementView(self.element_factory)
        self.add(self.box)
        self.box.connect('key-press-event', self._on_box_key_press)
        self.box.connect('motion-notify-event', self._on_box_motion_notify)
        self.box.connect('button-press-event', self._on_box_button_press)
        self.box.connect('button-release-event', self._on_box_button_release)
        self.element_view.connect('element-button-press-event',
                                  self._on_element_button_press_event)

        hbox = gtk.HBox()
        vbox = gtk.VBox()
        vbox.pack_start(self.element_view, False)
        hbox.pack_start(vbox, False)
        hbox.pack_start(self.form)
        hbox.pack_start(self.pref_box, False)
        hbox.set_spacing(6)
        self.box.add_bg_widget(hbox)
        self.pref_box.set_size_request(200, -1)
        self.selected = None
        self.mouse_button = None

        # Load built-in widgets.
        for name in sorted(Elements.__all__):
            if name in ('Element', 'Target'):
                continue
            element_class = Elements.__dict__[name]
            if type(element_class) != gobject.GObjectMeta:
                continue
            self.element_factory.register(element_class)

    def clear(self):
        self.form.clear()

    def target_at(self, x, y):
        x, y = self.box.translate_coordinates(self.form, int(x), int(y))
        return self.form.target_at(x, y)

    def unselect_target(self, target):
        self.selected = None
        target.unselect()

    def _update_widget_prefs(self):
        if self.pref_box.child:
            self.pref_box.remove(self.pref_box.child)
        element = self.selected.get_element()
        if element is None:
            return
        pref_widget = element.get_pref_widget()
        if pref_widget is None:
            return
        self.pref_box.add(pref_widget)
        self.pref_box.show_all()

    def select_target(self, target):
        if target == self.selected:
            return
        if self.selected:
            self.selected.unselect()
        self.selected = target
        if target is not None:
            target.select()
            self._update_widget_prefs()

    def _on_box_key_press(self, box, event):
        if event.keyval == 65535:  # Backspace
            self.selected.clear()
            self._update_widget_prefs()

    def _translate_event_coordinates(self, event):
        # Huh. I haven't found any such thing in the gtk API docs, though
        # it seems like a fairly common thing to do.
        my_x, my_y = self.window.get_origin()
        ev_x, ev_y = event.window.get_origin()
        return int(event.x + ev_x - my_x), int(event.y + ev_y - my_y)

    def _on_box_button_press(self, box, event):
        if event.button != 1:
            return
        self.mouse_button = event.button

        # Fetch the widget at the location of the mouse pointer.
        x, y = self._translate_event_coordinates(event)
        target = self.target_at(x, y)
        if target is not None:
            self.select_target(target)

    def _on_box_motion_notify(self, box, event):
        if self.mouse_button != 1:
            x, y = self._translate_event_coordinates(event)
            target = self.target_at(x, y)
            if target is None:
                return
            element = target.get_element()
            if element is None:
                element = target.get_parent_layout()
                if element is None:
                    return
            x, y = self.translate_coordinates(element, x, y)
            if element.in_resize_area(x, y):
                cursor = gtk.gdk.Cursor(gtk.gdk.BOTTOM_RIGHT_CORNER)
                element.window.set_cursor(cursor)
            else:
                element.window.set_cursor(None)
            return

        # Check whether we are already in a drag operation.
        moving = self.box.get_moving_child()
        if moving and moving.get_data('copy_of'):
            # Strip the coordinates to the parent layout.
            original = moving.get_data('copy_of')
            layout = original.get_parent_layout()
            alloc = layout.get_allocation()
            x1, y1 = self._translate_event_coordinates(event)
            x2, y2 = alloc.x + alloc.width, alloc.y + alloc.height
            x2, y2 = layout.translate_coordinates(self.box, x2, y2)

            # Select the bounding target.
            bounding = self.target_at(min(x1, x2), min(y1, y2))
            if bounding and bounding.get_parent_layout() == layout:
                self.select_target(bounding)
            return
        elif moving:
            x, y = self._translate_event_coordinates(event)
            target = self.target_at(x, y)
            if target is None:
                return
            self.select_target(target)
            return

        # Ending up here, it is time to start a drag operation.
        if not self.selected:
            return
        element = self.selected.get_element()
        if element is None:
            target = self.selected.get_parent_target()
            if target is None:
                return
            element = target.get_element()
            if element is None:
                return

        # Resize the widget?
        x, y = self._translate_event_coordinates(event)
        widget_x, widget_y = self.translate_coordinates(element, x, y)
        if element.in_resize_area(widget_x, widget_y):
            widget = element.copy()
            alloc = element.get_allocation()

            # The widget may span over multiple cells. However, we need to
            # highlight the borders of each individual cell, which does not
            # work when a colspan exists. To work around this, we chop the
            # widget into pieces and assemble it by assigning the pieces into
            # individual cells.
            # Get a "screenshot" of the widget.
            #drawable = gtk.gdk.Pixmap(element.window, alloc.width, alloc.height)
            #pixbuf   = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,
            #                          False,
            #                          8,
            #                          alloc.width,
            #                          alloc.height)
            #pixbuf.get_from_drawable(drawable, drawable.get_colormap(),
            #                         0, 0, 0, 0,
            #                         alloc.width, alloc.height)

            # Chop the screenshot into pieces and replace the original
            # widget by the pieces, allowing for highlighting the borders
            # of individual cells.
            #lft, rgt, top, bot = layout.position_of(target)
            #pixbuf.save('screenshot', "jpeg", {"quality":"100"})

            box_x, box_y = element.translate_coordinates(
                self.box, alloc.x, alloc.y)
            widget.set_size_request(alloc.width, alloc.height)
            widget.set_data('copy_of', element)
            self.box.add(widget)
            self.box.set_child_position(widget, box_x, box_y)
            self.box.start_resize(widget, x, y, event.time)
            return

        # Start dragging? Remove the widget from the layout and re-add it as
        # a floating child.
        if element.in_drag_area(widget_x, widget_y):
            target = element.get_parent_target()
            target.clear()
            self.box.add(element)
            self.box.set_child_position(element, x - 2, y - 4)
            self.box.start_drag(element, x, y, event.time)

    def _on_box_button_release(self, box, event):
        if event.button != 1:
            return
        self.mouse_button = None

        x, y = self._translate_event_coordinates(event)
        target = self.target_at(x, y)
        widget = self.box.get_moving_child()

        # Was an existing widget resized?
        if target and widget and widget.get_data('copy_of'):
            self.box.remove(widget)

            # Find the upper left and lower right targets.
            original = widget.get_data('copy_of')
            layout = original.get_parent_layout()
            top_lft = original.get_parent_target()
            bot_rgt = self.selected or target1

            # Assign the widget to parent layout targets.
            layout.reassign(original, top_lft, bot_rgt)
            self.unselect_target(target)

        # Was a new widget added, or an existing widget moved?
        elif target and widget:
            self.box.remove(widget)
            target.attach(widget)
            self.unselect_target(target)

        # Was a new widget dragged into a non-dropable area?
        elif widget:
            self.box.remove(widget)

        # Was a target clicked?
        elif target:
            self.select_target(target)

    def _emit_box_event(self, event):
        # Fake an event such that the FloatBox can pick up the newly
        # created widget.
        x, y = self.box._translate_event_coordinates(event)
        event.window = self.box.window
        event.x = float(x)
        event.y = float(y)
        gtk.main_do_event(event)

    def _on_element_button_press_event(self, view, button, event):
        alloc = button.get_allocation()
        element = self.element_factory.create(button.get_name())
        element.set_size_request(alloc.width, alloc.height)
        self.box.add(element)
        self.box.set_child_position(element, alloc.x, alloc.y)
        self._emit_box_event(event)
示例#4
0
class Workspace(gtk.EventBox):
    def __init__(self):
        gtk.EventBox.__init__(self)
        self.box = FloatBox()
        self.pref_box = gtk.EventBox()
        self.form = Target()
        self.element_factory = ElementFactory()
        self.element_view = ElementView(self.element_factory)
        self.add(self.box)
        self.box.connect("key-press-event", self._on_box_key_press)
        self.box.connect("motion-notify-event", self._on_box_motion_notify)
        self.box.connect("button-press-event", self._on_box_button_press)
        self.box.connect("button-release-event", self._on_box_button_release)
        self.element_view.connect("element-button-press-event", self._on_element_button_press_event)

        hbox = gtk.HBox()
        vbox = gtk.VBox()
        vbox.pack_start(self.element_view, False)
        hbox.pack_start(vbox, False)
        hbox.pack_start(self.form)
        hbox.pack_start(self.pref_box, False)
        hbox.set_spacing(6)
        self.box.add_bg_widget(hbox)
        self.pref_box.set_size_request(200, -1)
        self.selected = None
        self.mouse_button = None

        # Load built-in widgets.
        for name in sorted(Elements.__all__):
            if name in ("Element", "Target"):
                continue
            element_class = Elements.__dict__[name]
            if type(element_class) != gobject.GObjectMeta:
                continue
            self.element_factory.register(element_class)

    def clear(self):
        self.form.clear()

    def target_at(self, x, y):
        x, y = self.box.translate_coordinates(self.form, int(x), int(y))
        return self.form.target_at(x, y)

    def unselect_target(self, target):
        self.selected = None
        target.unselect()

    def _update_widget_prefs(self):
        if self.pref_box.child:
            self.pref_box.remove(self.pref_box.child)
        element = self.selected.get_element()
        if element is None:
            return
        pref_widget = element.get_pref_widget()
        if pref_widget is None:
            return
        self.pref_box.add(pref_widget)
        self.pref_box.show_all()

    def select_target(self, target):
        if target == self.selected:
            return
        if self.selected:
            self.selected.unselect()
        self.selected = target
        if target is not None:
            target.select()
            self._update_widget_prefs()

    def _on_box_key_press(self, box, event):
        if event.keyval == 65535:  # Backspace
            self.selected.clear()
            self._update_widget_prefs()

    def _translate_event_coordinates(self, event):
        # Huh. I haven't found any such thing in the gtk API docs, though
        # it seems like a fairly common thing to do.
        my_x, my_y = self.window.get_origin()
        ev_x, ev_y = event.window.get_origin()
        return int(event.x + ev_x - my_x), int(event.y + ev_y - my_y)

    def _on_box_button_press(self, box, event):
        if event.button != 1:
            return
        self.mouse_button = event.button

        # Fetch the widget at the location of the mouse pointer.
        x, y = self._translate_event_coordinates(event)
        target = self.target_at(x, y)
        if target is not None:
            self.select_target(target)

    def _on_box_motion_notify(self, box, event):
        if self.mouse_button != 1:
            x, y = self._translate_event_coordinates(event)
            target = self.target_at(x, y)
            if target is None:
                return
            element = target.get_element()
            if element is None:
                element = target.get_parent_layout()
                if element is None:
                    return
            x, y = self.translate_coordinates(element, x, y)
            if element.in_resize_area(x, y):
                cursor = gtk.gdk.Cursor(gtk.gdk.BOTTOM_RIGHT_CORNER)
                element.window.set_cursor(cursor)
            else:
                element.window.set_cursor(None)
            return

        # Check whether we are already in a drag operation.
        moving = self.box.get_moving_child()
        if moving and moving.get_data("copy_of"):
            # Strip the coordinates to the parent layout.
            original = moving.get_data("copy_of")
            layout = original.get_parent_layout()
            alloc = layout.get_allocation()
            x1, y1 = self._translate_event_coordinates(event)
            x2, y2 = alloc.x + alloc.width, alloc.y + alloc.height
            x2, y2 = layout.translate_coordinates(self.box, x2, y2)

            # Select the bounding target.
            bounding = self.target_at(min(x1, x2), min(y1, y2))
            if bounding and bounding.get_parent_layout() == layout:
                self.select_target(bounding)
            return
        elif moving:
            x, y = self._translate_event_coordinates(event)
            target = self.target_at(x, y)
            if target is None:
                return
            self.select_target(target)
            return

        # Ending up here, it is time to start a drag operation.
        if not self.selected:
            return
        element = self.selected.get_element()
        if element is None:
            target = self.selected.get_parent_target()
            if target is None:
                return
            element = target.get_element()
            if element is None:
                return

        # Resize the widget?
        x, y = self._translate_event_coordinates(event)
        widget_x, widget_y = self.translate_coordinates(element, x, y)
        if element.in_resize_area(widget_x, widget_y):
            widget = element.copy()
            alloc = element.get_allocation()

            # The widget may span over multiple cells. However, we need to
            # highlight the borders of each individual cell, which does not
            # work when a colspan exists. To work around this, we chop the
            # widget into pieces and assemble it by assigning the pieces into
            # individual cells.
            # Get a "screenshot" of the widget.
            # drawable = gtk.gdk.Pixmap(element.window, alloc.width, alloc.height)
            # pixbuf   = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,
            #                          False,
            #                          8,
            #                          alloc.width,
            #                          alloc.height)
            # pixbuf.get_from_drawable(drawable, drawable.get_colormap(),
            #                         0, 0, 0, 0,
            #                         alloc.width, alloc.height)

            # Chop the screenshot into pieces and replace the original
            # widget by the pieces, allowing for highlighting the borders
            # of individual cells.
            # lft, rgt, top, bot = layout.position_of(target)
            # pixbuf.save('screenshot', "jpeg", {"quality":"100"})

            box_x, box_y = element.translate_coordinates(self.box, alloc.x, alloc.y)
            widget.set_size_request(alloc.width, alloc.height)
            widget.set_data("copy_of", element)
            self.box.add(widget)
            self.box.set_child_position(widget, box_x, box_y)
            self.box.start_resize(widget, x, y, event.time)
            return

        # Start dragging? Remove the widget from the layout and re-add it as
        # a floating child.
        if element.in_drag_area(widget_x, widget_y):
            target = element.get_parent_target()
            target.clear()
            self.box.add(element)
            self.box.set_child_position(element, x - 2, y - 4)
            self.box.start_drag(element, x, y, event.time)

    def _on_box_button_release(self, box, event):
        if event.button != 1:
            return
        self.mouse_button = None

        x, y = self._translate_event_coordinates(event)
        target = self.target_at(x, y)
        widget = self.box.get_moving_child()

        # Was an existing widget resized?
        if target and widget and widget.get_data("copy_of"):
            self.box.remove(widget)

            # Find the upper left and lower right targets.
            original = widget.get_data("copy_of")
            layout = original.get_parent_layout()
            top_lft = original.get_parent_target()
            bot_rgt = self.selected or target1

            # Assign the widget to parent layout targets.
            layout.reassign(original, top_lft, bot_rgt)
            self.unselect_target(target)

        # Was a new widget added, or an existing widget moved?
        elif target and widget:
            self.box.remove(widget)
            target.attach(widget)
            self.unselect_target(target)

        # Was a new widget dragged into a non-dropable area?
        elif widget:
            self.box.remove(widget)

        # Was a target clicked?
        elif target:
            self.select_target(target)

    def _emit_box_event(self, event):
        # Fake an event such that the FloatBox can pick up the newly
        # created widget.
        x, y = self.box._translate_event_coordinates(event)
        event.window = self.box.window
        event.x = float(x)
        event.y = float(y)
        gtk.main_do_event(event)

    def _on_element_button_press_event(self, view, button, event):
        alloc = button.get_allocation()
        element = self.element_factory.create(button.get_name())
        element.set_size_request(alloc.width, alloc.height)
        self.box.add(element)
        self.box.set_child_position(element, alloc.x, alloc.y)
        self._emit_box_event(event)