Beispiel #1
0
    def __init__(self, master=None, orient=HORIZONTAL, canvas=None, **kw):
        apply(PyWidget.__init__, (self, master), kw)
        self.orient = orient
        self.canvas = canvas

        self.gc_initialized = 0
        self.gc = GraphicsDevice()
        self.gc.SetViewportTransform(1.0, Identity, Identity)

        self.positions = None
        self.SetRange(0.0, 1.0, force=1)

        self['height'] = 19
        self['width'] = 19

        self.border_color = XRGBColor(ui_colors.light_border)
        self.bg_color = XRGBColor(ui_colors.menubackground)
        self.fg_color = XRGBColor(ui_colors.fg)

        self.gradient = []
        start = ui_colors.menubackground
        stop = ui_colors.light_border
        for pos in range(20):
            color = gtkutils.middle_color(start, stop, pos * 3.5 / 100)
            self.gradient.append(XRGBColor(color))

        self.bind('<ButtonPress>', self.ButtonPressEvent)
        self.bind('<ButtonRelease>', self.ButtonReleaseEvent)
        self.bind('<Motion>', self.PointerMotionEvent)
        self.button_down = 0
        self.forward_motion = 0

        config.preferences.Subscribe(CHANGED, self.preference_changed)
Beispiel #2
0
    def __init__(self,
                 master=None,
                 toplevel=None,
                 document=None,
                 show_visible=0,
                 show_printable=1,
                 resolution=None,
                 **kw):
        apply(PyWidget.__init__, (self, master), kw)
        Viewport.__init__(self, resolution)
        QueueingPublisher.__init__(self)
        self.toplevel = toplevel

        self.move_window_count = 0
        self.show_page_outline = 1
        self.show_visible = show_visible
        self.show_printable = show_printable
        self.gcs_initialized = 0
        self.gc = GraphicsDevice()

        self.init_transactions()
        if document is not None:
            self.SetDocument(document)
        else:
            self.SetDocument(Document(create_layer=1))
Beispiel #3
0
 def __init__(self, master=None, **kw):
     apply(PyWidget.__init__, (self, master), kw)
     self.gc_initialized = 0
     self.gc = GraphicsDevice()
     self.pattern = EmptyPattern
     self.properties = PropertyStack()
     self.properties.AddStyle(EmptyLineStyle)
     self.properties.SetProperty(fill_pattern = self.pattern)
     self.gc.SetProperties(self.properties)
     self.fill_rect = None
Beispiel #4
0
class PatternSample(PyWidget):

    def __init__(self, master=None, **kw):
	apply(PyWidget.__init__, (self, master), kw)
	self.gc_initialized = 0
	self.gc = GraphicsDevice()
	self.pattern = EmptyPattern
	self.properties = PropertyStack()
	self.properties.AddStyle(EmptyLineStyle)
	self.properties.SetProperty(fill_pattern = self.pattern)
	self.gc.SetProperties(self.properties)
	self.fill_rect = None

    def MapMethod(self):
	self.fill_rect = Rect(0, 0, self.tkwin.width, self.tkwin.height)
	if not self.gc_initialized:
	    self.init_gc()
	    self.gc_initialized = 1

    def init_gc(self):
	self.gc.init_gc(self.tkwin)
	self.compute_trafo()

    def compute_trafo(self):
	height = self.tkwin.height
	doc_to_win = Trafo(1, 0, 0, -1, 0, height)
	win_to_doc = doc_to_win.inverse()
	self.gc.SetViewportTransform(1.0, doc_to_win, win_to_doc)
	self.fill_rect = Rect(0, 0, self.tkwin.width, self.tkwin.height)
	self.gc.SetProperties(self.properties, self.fill_rect)

    def SetPattern(self, pattern):
	if pattern != self.pattern:
	    self.pattern = pattern
	    self.UpdateWhenIdle()
	    self.properties.SetProperty(fill_pattern = pattern)
	    self.gc.SetProperties(self.properties, self.fill_rect)

    def RedrawMethod(self, region = None):
	win = self.tkwin
	self.gc.StartDblBuffer()
	self.gc.SetFillColor(StandardColors.white)
	self.gc.FillRectangle(0, 0, win.width, win.height)
	if self.properties.HasFill():
	    self.gc.Rectangle(Trafo(win.width, 0, 0, win.height, 0, 0))
	else:
	    self.gc.SetLineColor(StandardColors.black)
	    self.gc.DrawLineXY(0, win.height, win.width, 0)
	self.gc.EndDblBuffer()

    def ResizedMethod(self, width, height):
	self.gc.WindowResized(width, height)
	self.UpdateWhenIdle()
	self.compute_trafo()
Beispiel #5
0
    def __init__(self, master=None, **kw):
	apply(PyWidget.__init__, (self, master), kw)
	self.gc_initialized = 0
	self.gc = GraphicsDevice()
	self.pattern = EmptyPattern
	self.properties = PropertyStack()
	self.properties.AddStyle(EmptyLineStyle)
	self.properties.SetProperty(fill_pattern = self.pattern)
	self.gc.SetProperties(self.properties)
	self.fill_rect = None
Beispiel #6
0
    def __init__(self, master=None, palette=None, cell_size=16, **kw):
        if not kw.has_key('height'):
            kw['height'] = cell_size
        apply(PyWidget.__init__, (self, master), kw)

        self.cell_size = cell_size
        self.num_cells = 0
        self.gc_initialized = 0
        self.gc = GraphicsDevice()
        self.gc.SetViewportTransform(1.0, Identity, Identity)
        self.start_idx = 0
        self.palette = None
        if palette is None:
            palette = RGBPalette()
        self.SetPalette(palette)
        self.dragging = 0
        self.bind('<ButtonPress-1>', self.press_1)
        self.bind('<Motion>', self.move_1)
        self.bind('<ButtonRelease-1>', self.release_1)
        self.bind('<ButtonRelease-3>', self.apply_color_2)
Beispiel #7
0
    def __init__(self, master=None, toplevel = None, document = None,
		 show_visible = 0, show_printable = 1,
		 resolution = None, **kw):
	apply(PyWidget.__init__, (self, master), kw)
	Viewport.__init__(self, resolution)
	QueueingPublisher.__init__(self)
	self.toplevel = toplevel

	self.move_window_count = 0
	self.show_page_outline = 1
	self.show_visible = show_visible
	self.show_printable = show_printable
	self.gcs_initialized = 0
	self.gc = GraphicsDevice()

	self.init_transactions()
	if document is not None:
	    self.SetDocument(document)
	else:
	    self.SetDocument(Document(create_layer = 1))
Beispiel #8
0
    def __init__(self, master=None, palette = None, cell_size = 16, **kw):
	if not kw.has_key('height'):
	    kw['height'] = cell_size
	apply(PyWidget.__init__, (self, master), kw)

	self.cell_size = cell_size
	self.num_cells = 0
	self.gc_initialized = 0
	self.gc = GraphicsDevice()
	self.gc.SetViewportTransform(1.0, Identity, Identity)
	self.start_idx = 0
	self.palette = None
	if palette is None:
	    palette = RGBPalette()
	self.SetPalette(palette)
	self.dragging = 0
	self.bind('<ButtonPress-1>', self.press_1)
	self.bind('<Motion>', self.move_1)
	self.bind('<ButtonRelease-1>', self.release_1)
	self.bind('<ButtonRelease-2>', self.apply_color_2)
Beispiel #9
0
class PaletteWidget(PyWidget, Publisher):
    def __init__(self, master=None, palette=None, cell_size=16, **kw):
        if not kw.has_key('height'):
            kw['height'] = cell_size
        apply(PyWidget.__init__, (self, master), kw)

        self.cell_size = cell_size
        self.num_cells = 0
        self.gc_initialized = 0
        self.gc = GraphicsDevice()
        self.gc.SetViewportTransform(1.0, Identity, Identity)
        self.start_idx = 0
        self.palette = None
        if palette is None:
            palette = RGBPalette()
        self.SetPalette(palette)
        self.dragging = 0
        self.bind('<ButtonPress-1>', self.press_1)
        self.bind('<Motion>', self.move_1)
        self.bind('<ButtonRelease-1>', self.release_1)
        self.bind('<ButtonRelease-3>', self.apply_color_2)

    def DestroyMethod(self):
        self.palette.Unsubscribe(CHANGED, self.palette_changed)
        Publisher.Destroy(self)

    def compute_num_cells(self):
        self.num_cells = self.tkwin.width / self.cell_size + 1

    def MapMethod(self):
        self.compute_num_cells()
        self.issue(VIEW)
        if not self.gc_initialized:
            self.init_gc()
            self.gc_initialized = 1

    def init_gc(self):
        self.gc.init_gc(self.tkwin)

    def get_color(self, x, y):
        if 0 <= x < self.tkwin.width and 0 <= y < self.tkwin.height:
            i = self.start_idx + x / self.cell_size
            if i < len(self.palette):
                return apply(CreateRGBColor, self.palette.GetRGB(i))

    def release_1(self, event):
        try:
            if self.dragging:
                self.drop_color(event)
            else:
                self.apply_color_1(event)
        finally:
            self.dragging = 0

    def drop_color(self, event):
        self['cursor'] = self.drag_old_cursor
        w = self.winfo_containing(event.x_root, event.y_root)
        while w and w != self:
            if __debug__:
                pdebug('DND', 'trying to drop on', w)
            try:
                accepts = w.accept_drop
            except AttributeError:
                accepts = ()
            if DROP_COLOR in accepts:
                x = event.x_root - w.winfo_rootx()
                y = event.y_root - w.winfo_rooty()
                w.DropAt(x, y, DROP_COLOR, self.drag_start)
                break
            if w != w.winfo_toplevel():
                parent = self.tk.call('winfo', 'parent', w._w)
                w = self.nametowidget(parent)
            else:
                break

    def apply_color_1(self, event):
        c = self.get_color(event.x, event.y)
        if c:
            self.issue(COLOR1, c)

    def apply_color_2(self, event):
        c = self.get_color(event.x, event.y)
        if c:
            self.issue(COLOR2, c)

    drag_start = (0, 0, 0)

    def press_1(self, event):
        self.drag_start = self.get_color(event.x, event.y)

    def move_1(self, event):
        if event.state & X.Button1Mask:
            if not self.dragging:
                self.dragging = 1
                self.drag_old_cursor = self['cursor']
                self['cursor'] = CurDragColor
            w = self.winfo_containing(event.x_root, event.y_root)

    def Palette(self):
        return self.palette

    def SetPalette(self, palette):
        if self.palette is not None:
            self.palette.Unsubscribe(CHANGED, self.palette_changed)
        self.palette = palette
        self.palette.Subscribe(CHANGED, self.palette_changed)
        self.palette_changed()

    def palette_changed(self):
        self.compute_num_cells()
        self.normalize_start()
        self.issue(VIEW)
        self.UpdateWhenIdle()

    def RedrawMethod(self, region=None):
        win = self.tkwin
        width = win.width
        height = win.height
        self.gc.StartDblBuffer()
        self.gc.SetFillColor(StandardColors.white)
        self.gc.FillRectangle(0, 0, width, height)

        x = 0
        FillRectangle = self.gc.FillRectangle
        SetFillColor = self.gc.SetFillColor
        create_color = CreateRGBColor
        rgbs = self.palette.Colors()
        rgbs = rgbs[self.start_idx:self.start_idx + self.num_cells]
        for rgb in rgbs:
            SetFillColor(apply(create_color, rgb))
            FillRectangle(x, 0, x + height, height)
            x = x + height
        self.gc.EndDblBuffer()

    def ResizedMethod(self, width, height):
        self.compute_num_cells()
        self.gc.WindowResized(width, height)
        self.normalize_start()
        self.UpdateWhenIdle()

    def normalize_start(self):
        length = len(self.palette)
        if self.start_idx < 0:
            self.start_idx = 0
        if length < self.num_cells:
            self.start_idx = 0
        elif length - self.start_idx < self.num_cells:
            self.start_idx = length - self.num_cells

    def CanScrollLeft(self):
        return self.start_idx > 0

    def CanScrollRight(self):
        return len(self.palette) - self.start_idx > self.num_cells

    def ScrollXPages(self, count):
        length = self.tkwin.width / self.cell_size
        start = self.start_idx
        self.start_idx = self.start_idx + count * length
        self.normalize_start()
        if start != self.start_idx:
            self.UpdateWhenIdle()
            self.issue(VIEW)

    def ScrollXUnits(self, count):
        start = self.start_idx
        self.start_idx = self.start_idx + count
        self.normalize_start()
        if start != self.start_idx:
            self.UpdateWhenIdle()
            self.issue(VIEW)
Beispiel #10
0
class Ruler(PyWidget):
    def __init__(self, master=None, orient=HORIZONTAL, canvas=None, **kw):
        apply(PyWidget.__init__, (self, master), kw)
        self.orient = orient
        self.canvas = canvas

        self.gc_initialized = 0
        self.gc = GraphicsDevice()
        self.gc.SetViewportTransform(1.0, Identity, Identity)

        self.positions = None
        self.SetRange(0.0, 1.0, force=1)

        self['height'] = 19
        self['width'] = 19

        self.border_color = XRGBColor(ui_colors.light_border)
        self.bg_color = XRGBColor(ui_colors.menubackground)
        self.fg_color = XRGBColor(ui_colors.fg)

        self.gradient = []
        start = ui_colors.menubackground
        stop = ui_colors.light_border
        for pos in range(20):
            color = gtkutils.middle_color(start, stop, pos * 3.5 / 100)
            self.gradient.append(XRGBColor(color))

        self.bind('<ButtonPress>', self.ButtonPressEvent)
        self.bind('<ButtonRelease>', self.ButtonReleaseEvent)
        self.bind('<Motion>', self.PointerMotionEvent)
        self.button_down = 0
        self.forward_motion = 0

        config.preferences.Subscribe(CHANGED, self.preference_changed)

    def destroy(self):
        PyWidget.destroy(self)
        self.canvas = None

    def MapMethod(self):
        if not self.gc_initialized:
            self.gc.init_gc(self.tkwin)
            self.gc_initialized = 1

    def ResizedMethod(self, width, height):
        self.SetRange(self.start, self.pixel_per_pt, force=1)

    def SetRange(self, start, pixel_per_pt, force=0):
        if not force and start == self.start and pixel_per_pt == self.pixel_per_pt:
            return
        self.start = start
        self.pixel_per_pt = pixel_per_pt
        self.positions = None
        self.UpdateWhenIdle()

    def preference_changed(self, pref, value):
        if pref == 'default_unit':
            self.positions = None  # force recomputation
            self.UpdateWhenIdle()

    def get_positions(self):
        if self.positions is not None:
            return self.positions, self.texts

        min_text_step = config.preferences.ruler_min_text_step
        max_text_step = config.preferences.ruler_max_text_step
        min_tick_step = config.preferences.ruler_min_tick_step
        if self.orient == HORIZONTAL:
            length = self.tkwin.width
            origin = self.start
        else:
            length = self.tkwin.height
            origin = self.start - length / self.pixel_per_pt
        unit_name = config.preferences.default_unit
        pt_per_unit = units.unit_dict[unit_name]
        units_per_pixel = 1.0 / (pt_per_unit * self.pixel_per_pt)
        factor, subdivisions = tick_config[unit_name]
        subdivisions = (1, ) + subdivisions

        factor = factor * pt_per_unit
        start_pos = floor(origin / factor) * factor
        main_tick_step = factor * self.pixel_per_pt
        num_ticks = floor(length / main_tick_step) + 2

        if main_tick_step < min_tick_step:
            tick_step = ceil(min_tick_step / main_tick_step) * main_tick_step
            subdivisions = (1, )
            ticks = 1
        else:
            tick_step = main_tick_step
            ticks = 1
            for depth in range(len(subdivisions)):
                tick_step = tick_step / subdivisions[depth]
                if tick_step < min_tick_step:
                    tick_step = tick_step * subdivisions[depth]
                    depth = depth - 1
                    break
                ticks = ticks * subdivisions[depth]
            subdivisions = subdivisions[:depth + 1]

        positions = range(int(num_ticks * ticks))
        positions = map(operator.mul, [tick_step] * len(positions), positions)
        positions = map(operator.add, positions,
                        [(start_pos - origin) * self.pixel_per_pt] *
                        len(positions))

        stride = ticks
        marks = [None] * len(positions)
        for depth in range(len(subdivisions)):
            stride = stride / subdivisions[depth]
            if depth >= len(tick_lengths):
                height = tick_lengths[-1]
            else:
                height = tick_lengths[depth]
            for i in range(0, len(positions), stride):
                if marks[i] is None:
                    marks[i] = (height, int(round(positions[i])))

        texts = []
        if main_tick_step < min_text_step:
            stride = int(ceil(min_text_step / main_tick_step))
            start_index = stride - (floor(origin / factor) % stride)
            start_index = int(start_index * ticks)
            stride = stride * ticks
        else:
            start_index = 0
            stride = ticks
            step = main_tick_step
            for div in subdivisions:
                step = step / div
                if step < min_text_step:
                    break
                stride = stride / div
                if step < max_text_step:
                    break

        for i in range(start_index, len(positions), stride):
            pos = positions[i] * units_per_pixel + origin / pt_per_unit
            pos = round(pos, 3)
            if pos == 0.0:
                # avoid '-0' strings
                pos = 0.0
            texts.append(("%g" % pos, marks[i][-1]))
        self.positions = marks
        self.texts = texts

        return self.positions, self.texts

    def RedrawMethod(self, region=None):
        if self.orient == HORIZONTAL:
            self.draw_ruler_horizontal()
        else:
            self.draw_ruler_vertical()

    def draw_ruler_horizontal(self):
        DrawLine = self.gc.gc.DrawLine
        height = self.tkwin.height
        width = self.tkwin.width

        for pos in range(0, 20):
            self.gc.SetFillColor(self.gradient[pos])
            DrawLine(0, pos, width, pos)

        self.gc.SetFillColor(self.fg_color)
        ticks, texts = self.get_positions()
        for h, pos in ticks:
            DrawLine(pos, height, pos, height - h - 1)
            pos = pos + 1

        y = 8
        for text, pos in texts:
            pos += 1
            for character in str(text):
                data = HFONT[character]
                lines = data[1]
                for line in lines:
                    DrawLine(line[0] + pos, y - line[1], line[2] + pos,
                             y - line[3])
                pos += data[0]

        self.gc.SetFillColor(self.border_color)
        self.gc.gc.DrawLine(0, 0, 0, height)
        self.gc.gc.DrawLine(0, height - 1, width, height - 1)

    def draw_ruler_vertical(self):
        DrawLine = self.gc.gc.DrawLine
        height = self.tkwin.height
        width = self.tkwin.width

        for pos in range(0, 20):
            self.gc.SetFillColor(self.gradient[pos])
            DrawLine(pos, 0, pos, height)

        self.gc.SetFillColor(self.fg_color)
        ticks, texts = self.get_positions()
        for h, pos in ticks:
            pos = height - pos
            DrawLine(width - h - 1, pos, width, pos)
            pos = pos + 1

        x = 8
        for text, pos in texts:
            pos = height - pos
            pos -= 1
            for character in str(text):
                data = VFONT[character]
                lines = data[1]
                for line in lines:
                    DrawLine(x - line[0], pos - line[1], x - line[2],
                             pos - line[3])
                pos -= data[0]

        self.gc.SetFillColor(self.border_color)
        DrawLine(0, 0, width, 0)
        DrawLine(width - 1, 0, width - 1, height)

    def ButtonPressEvent(self, event):
        if event.num == const.Button1:
            self.button_down = 1
            self.pressevent = event

    def ButtonReleaseEvent(self, event):
        if event.num == const.Button1:
            self.button_down = 0

    def PointerMotionEvent(self, event):
        if self.button_down:
            if self.canvas is not None:
                press = self.pressevent
                if hypot(press.x - event.x, press.y - event.y) > 3:
                    guide = GuideLine(Point(0, 0), self.orient == HORIZONTAL)
                    self.canvas.PlaceObject(guide)
                    press.x = press.x_root - self.canvas.winfo_rootx()
                    press.y = press.y_root - self.canvas.winfo_rooty()
                    self.canvas.ButtonPressEvent(press)
                    self.canvas.grab_set()
                    self.button_down = 0

    def SetCanvas(self, canvas):
        self.canvas = canvas
Beispiel #11
0
class SketchView(PyWidget, Viewport, QueueingPublisher):

    document = None

    def __init__(self,
                 master=None,
                 toplevel=None,
                 document=None,
                 show_visible=0,
                 show_printable=1,
                 resolution=None,
                 **kw):
        apply(PyWidget.__init__, (self, master), kw)
        Viewport.__init__(self, resolution)
        QueueingPublisher.__init__(self)
        self.toplevel = toplevel

        self.move_window_count = 0
        self.show_page_outline = 1
        self.show_visible = show_visible
        self.show_printable = show_printable
        self.gcs_initialized = 0
        self.gc = GraphicsDevice()

        self.init_transactions()
        if document is not None:
            self.SetDocument(document)
        else:
            self.SetDocument(Document(create_layer=1))

    def destroy(self):
        self.unsubscribe_doc()
        PyWidget.destroy(self)
        QueueingPublisher.Destroy(self)

    def MapMethod(self):
        # when being mapped the first time, initialise the gcs. this cannot be
        # done earlier, because the hitgc creates a pixmap which currently
        # only works after the window (id) has been created. In Xt this can be
        # done in the Realize widget method (after calling the superclass'
        # method), but Tk doesn't seem to offer any similar thing.
        if not self.gcs_initialized:
            self.init_gcs()
            self.issue_state()

    def DestroyMethod(self):
        # make sure that gc is deleted. gc may have a shared memory ximage
        # which is not freed if the gc is not destroyed leaving unused shared
        # memory segments in the system even after the process has finished.
        self.gc = None
        PyWidget.DestroyMethod(self)

    def init_gcs(self):
        self.gc.init_gc(self.tkwin, graphics_exposures=1)
        self.gc.draw_visible = self.show_visible
        self.gc.draw_printable = self.show_printable
        self.gc.allow_outline = 0
        self.gcs_initialized = 1
        self.default_view()
        self.set_gc_transforms()

    def default_view(self):
        self.FitPageToWindow()

    def set_gc_transforms(self):
        self.gc.SetViewportTransform(self.scale, self.doc_to_win,
                                     self.win_to_doc)

    #
    #	Channels
    #

    def issue_state(self):
        self.queue_message(STATE)

    def issue_view(self):
        self.queue_message(VIEW)

    def issue_document(self):
        self.doc_changed = 1

    def queue_message(self, Publisher):
        if self.transaction:
            QueueingPublisher.queue_message(self, Publisher)
        else:
            self.issue(Publisher)

    def init_transactions(self):
        self.sb_update_pending = 0
        self.doc_changed = 0
        self.transaction = 0

    def begin_transaction(self):
        self.transaction = self.transaction + 1

    def end_transaction(self):
        self.transaction = self.transaction - 1
        if self.transaction == 0:
            if self.doc_changed:
                self.issue(DOCUMENT, self.document)
            self.sb_update_pending = 0
            self.doc_changed = 0
            self.flush_message_queue()
        elif self.transaction < 0:
            raise SketchInternalError('transaction count < 0')

    #
    #	receivers
    #

    def redraw_doc(self, all, rects=None):
        if all:
            self.clear_window()
        else:
            map(self.clear_area_doc, rects)

    def layout_changed(self):
        self.SetPageSize(self.document.Layout().Size())
        self.set_gc_transforms()
        self.update_scrollbars()
        self.update_rulers()
        if self.show_page_outline:
            self.clear_window()

    def layer_changed(self, *args):
        if args:
            redraw = EmptyRect
            if args[0] == LAYER_STATE:
                layer, visible_changed, printable_changed, outlined_changed \
                     = args[1]
                rect = layer.bounding_rect
                if rect is not EmptyRect:
                    if self.show_printable and printable_changed:
                        redraw = rect
                    if self.show_visible:
                        if visible_changed:
                            redraw = rect
                        if outlined_changed and layer.Visible():
                            redraw = rect
            elif args[0] == LAYER_ORDER:
                layer = args[1]
                if (self.show_printable and layer.Printable()
                        or self.show_visible and layer.Visible()):
                    redraw = layer.bounding_rect
                if len(args) > 2:
                    other = args[2]
                    if (self.show_printable and other.Printable()
                            or self.show_visible and other.Visible()):
                        redraw = IntersectRects(redraw, other.bounding_rect)
                    else:
                        redraw = EmptyRect
            elif args[0] == LAYER_COLOR:
                layer = args[1]
                rect = layer.bounding_rect
                if self.show_visible and rect is not EmptyRect \
                   and layer.Visible():
                    redraw = rect
            self.clear_area_doc(redraw)

    #
    #	Widget Methods (Redraw, ... )
    #

    time_redraw = 0

    def RedrawMethod(self, region=None):
        # draw the document
        if __debug__:
            if self.time_redraw:
                import time
                start = time.clock()
        if self.move_window_count >= 2:
            self.clear_window(update=0)
        self.move_window_count = 0

        region = self.do_clear(region)

        # draw document
        self.gc.InitClip()
        self.gc.ResetFontCache()
        if region:
            self.gc.PushClip()
            self.gc.ClipRegion(region)

        tkwin = self.tkwin
        if region:
            x, y, w, h = region.ClipBox()
            if x < 0:
                w = w - x
                x = 0
            if y < 0:
                h = h - y
                y = 0
            if w > tkwin.width:
                w = tkwin.width
            if h > tkwin.height:
                h = tkwin.height
        else:
            x = y = 0
            w = tkwin.width
            h = tkwin.height
        p1 = self.WinToDoc(x - 1, y - 1)
        p2 = self.WinToDoc(x + w + 1, y + h + 1)
        rect = Rect(p1, p2)

        self.gc.SetFillColor(StandardColors.white)
        self.gc.gc.FillRectangle(x, y, w, h)  # XXX ugly to access gc.gc

        #	draw paper
        if self.show_page_outline:
            w, h = self.document.PageSize()
            self.gc.DrawPageOutline(w, h)

        self.document.Draw(self.gc, rect)
        if region:
            self.gc.PopClip()

        if __debug__:
            if self.time_redraw:
                pdebug('timing', 'redraw', time.clock() - start)

        return region

    def ResizedMethod(self, width, height):
        Viewport.ResizedMethod(self, width, height)
        self.gc.WindowResized(width, height)

    #
    #	Viewport- and related methods
    #
    #	extend some Viewport methods to issue VIEW whenever
    #	the displayed area changes
    #

    def ForceRedraw(self):
        # Force a redraw of the whole window
        self.clear_window()
        if __debug__:
            #self.time_redraw = 1
            pass

#     def SetScrollbars(self, hbar, vbar):
# 	Viewport.SetScrollbars(self, hbar, vbar)
# 	hbar.configure(jump = 1)
# 	vbar.configure(jump = 1)

    def set_origin(self, xorg, yorg, move_contents=1):
        self.begin_transaction()
        try:
            Viewport.set_origin(self, xorg, yorg, move_contents=move_contents)
            self.set_gc_transforms()
            self.issue_view()
        finally:
            self.end_transaction()

    def move_window_contents(self, offx, offy):
        # implement the method needed by Viewport.set_origin
        w = self.tkwin
        width = w.width
        height = w.height
        if abs(offx) < width and abs(offy) < height:
            w.CopyArea(w, self.gc.gc, offx, offy, width, height, 0, 0)
            self.move_window_count = self.move_window_count + 1
        else:
            self.clear_window()

    def SetScale(self, scale, do_center=1):
        # Set current scale
        self.begin_transaction()
        try:
            Viewport.SetScale(self, scale, do_center=do_center)
            self.set_gc_transforms()
        finally:
            self.end_transaction()

    def zoom_fit_rect(self, rect, save_viewport=0):
        if save_viewport:
            self.save_viewport()
        Viewport.zoom_fit_rect(self, rect)

    #
    #	other view related methods
    #
    def FitToWindow(self, selected_only=0, save_viewport=1):
        self.begin_transaction()
        try:
            if selected_only:
                rect = self.document.SelectionBoundingRect()
            else:
                rect = self.document.BoundingRect()
            if rect:
                self.zoom_fit_rect(rect, save_viewport=save_viewport)
        finally:
            self.end_transaction()

    def FitPageToWindow(self, save_viewport=1):
        self.begin_transaction()
        try:
            w, h = self.document.PageSize()
            self.zoom_fit_rect(Rect(0 - w * .03, 0 - h * .03, w * 1.03,
                                    h * 1.03).grown(10),
                               save_viewport=save_viewport)
        finally:
            self.end_transaction()

    #
    #	Outline Mode
    #
    #	Although not directly related to the viewport methods (the outline
    #	mode doesn't change the displayed area) the outline mode changes the
    #	way the drawing is displayed and thus issues VIEW.

    def SetOutlineMode(self, on=1):
        self.begin_transaction()
        try:
            if on:
                if self.gc.IsOutlineActive():
                    return
                else:
                    self.gc.StartOutlineMode()
                    self.hitgc.StartOutlineMode()
            else:
                if self.gc.IsOutlineActive():
                    self.gc.EndOutlineMode()
                    self.hitgc.EndOutlineMode()
                else:
                    return
            self.issue_view()
            self.clear_window()
        finally:
            self.end_transaction()

    def ToggleOutlineMode(self):
        self.SetOutlineMode(not self.IsOutlineMode())

    def IsOutlineMode(self):
        return self.gc and self.gc.IsOutlineActive()

    #
    #	Show page outline on/off
    #

    def SetPageOutlineMode(self, on=1):
        self.begin_transaction()
        try:
            self.show_page_outline = on
            self.issue_view()
            self.clear_window()
        finally:
            self.end_transaction()

    def TogglePageOutlineMode(self):
        self.SetPageOutlineMode(not self.IsPageOutlineMode())

    def IsPageOutlineMode(self):
        return self.show_page_outline

    #
    #
    #

    def unsubscribe_doc(self):
        if self.document is not None:
            self.document.Unsubscribe(REDRAW, self.redraw_doc)
            self.document.Unsubscribe(LAYOUT, self.layout_changed)
            self.document.Unsubscribe(LAYER, self.layer_changed)

    def subscribe_doc(self):
        self.document.Subscribe(REDRAW, self.redraw_doc)
        self.document.Subscribe(LAYOUT, self.layout_changed)
        self.document.Subscribe(LAYER, self.layer_changed)

    def SetDocument(self, doc):
        self.begin_transaction()
        try:
            self.unsubscribe_doc()
            self.document = doc
            self.subscribe_doc()
            self.clear_window()
            self.SetPageSize(self.document.Layout().Size())
            self.FitPageToWindow(save_viewport=0)
            self.issue_document()
            self.issue_state()
            self.issue_view()
        finally:
            self.end_transaction()
Beispiel #12
0
class SketchView(PyWidget, Viewport, QueueingPublisher):

    document = None

    def __init__(self, master=None, toplevel = None, document = None,
		 show_visible = 0, show_printable = 1,
		 resolution = None, **kw):
	apply(PyWidget.__init__, (self, master), kw)
	Viewport.__init__(self, resolution)
	QueueingPublisher.__init__(self)
	self.toplevel = toplevel

	self.move_window_count = 0
	self.show_page_outline = 1
	self.show_visible = show_visible
	self.show_printable = show_printable
	self.gcs_initialized = 0
	self.gc = GraphicsDevice()

	self.init_transactions()
	if document is not None:
	    self.SetDocument(document)
	else:
	    self.SetDocument(Document(create_layer = 1))

    def destroy(self):
        self.unsubscribe_doc()
	PyWidget.destroy(self)
	QueueingPublisher.Destroy(self)


    def MapMethod(self):
	# when being mapped the first time, initialise the gcs. this cannot be
	# done earlier, because the hitgc creates a pixmap which currently
	# only works after the window (id) has been created. In Xt this can be
	# done in the Realize widget method (after calling the superclass'
	# method), but Tk doesn't seem to offer any similar thing.
	if not self.gcs_initialized:
	    self.init_gcs()
	    self.issue_state()

    def DestroyMethod(self):
	# make sure that gc is deleted. gc may have a shared memory ximage
	# which is not freed if the gc is not destroyed leaving unused shared
	# memory segments in the system even after the process has finished.
	self.gc = None
	PyWidget.DestroyMethod(self)

    def init_gcs(self):
	self.gc.init_gc(self.tkwin, graphics_exposures = 1)
	self.gc.draw_visible = self.show_visible
	self.gc.draw_printable = self.show_printable
	self.gc.allow_outline = 0
	self.gcs_initialized = 1
	self.default_view()
	self.set_gc_transforms()

    def default_view(self):
        self.FitPageToWindow()

    def set_gc_transforms(self):
	self.gc.SetViewportTransform(self.scale, self.doc_to_win,
				     self.win_to_doc)

    #
    #	Channels
    #

    def issue_state(self):
	self.queue_message(STATE)

    def issue_view(self):
	self.queue_message(VIEW)

    def issue_document(self):
	self.doc_changed = 1

    def queue_message(self, Publisher):
	if self.transaction:
	    QueueingPublisher.queue_message(self, Publisher)
	else:
	    self.issue(Publisher)

    def init_transactions(self):
	self.sb_update_pending = 0
	self.doc_changed = 0
	self.transaction = 0

    def begin_transaction(self):
	self.transaction = self.transaction + 1

    def end_transaction(self):
	self.transaction = self.transaction - 1
	if self.transaction == 0:
	    if self.doc_changed:
		self.issue(DOCUMENT, self.document)
	    self.sb_update_pending = 0
	    self.doc_changed = 0
	    self.flush_message_queue()
	elif self.transaction < 0:
	    raise SketchInternalError('transaction count < 0')

    #
    #	receivers
    #

    def redraw_doc(self, all, rects = None):
	if all:
	    self.clear_window()
	else:
	    map(self.clear_area_doc, rects)

    def layout_changed(self):
        self.SetPageSize(self.document.Layout().Size())
        self.set_gc_transforms()
        self.update_scrollbars()
        self.update_rulers()
	if self.show_page_outline:
	    self.clear_window()

    def layer_changed(self, *args):
	if args:
	    redraw = EmptyRect
	    if args[0] == LAYER_STATE:
		layer, visible_changed, printable_changed, outlined_changed \
		       = args[1]
		rect = layer.bounding_rect
		if rect is not EmptyRect:
		    if self.show_printable and printable_changed:
			redraw = rect
		    if self.show_visible:
			if visible_changed:
			    redraw = rect
			if outlined_changed and layer.Visible():
			    redraw = rect
	    elif args[0] == LAYER_ORDER:
		layer = args[1]
		if (self.show_printable and layer.Printable()
		    or self.show_visible and layer.Visible()):
		    redraw = layer.bounding_rect
		if len(args) > 2:
		    other = args[2]
		    if (self.show_printable and other.Printable()
			or self.show_visible and other.Visible()):
			redraw = IntersectRects(redraw, other.bounding_rect)
		    else:
			redraw = EmptyRect
	    elif args[0] == LAYER_COLOR:
		layer = args[1]
		rect = layer.bounding_rect
		if self.show_visible and rect is not EmptyRect \
		   and layer.Visible():
		    redraw = rect
	    self.clear_area_doc(redraw)

    #
    #	Widget Methods (Redraw, ... )
    #

    time_redraw = 0
    def RedrawMethod(self, region = None):
	# draw the document
	if __debug__:
	    if self.time_redraw:
		import time
		start = time.clock()
	if self.move_window_count >= 2:
	    self.clear_window(update = 0)
	self.move_window_count = 0

	region = self.do_clear(region)

	# draw document
	self.gc.InitClip()
	self.gc.ResetFontCache()
	if region:
	    self.gc.PushClip()
	    self.gc.ClipRegion(region)

        tkwin = self.tkwin
	if region:
	    x, y, w, h = region.ClipBox()
            if x < 0:
                w = w - x; x = 0
            if y < 0:
                h = h - y; y = 0
            if w > tkwin.width:
                w = tkwin.width
            if h > tkwin.height:
                h = tkwin.height
	else:
	    x = y = 0
	    w = tkwin.width
	    h = tkwin.height
	p1 = self.WinToDoc(x - 1, y - 1)
	p2 = self.WinToDoc(x + w + 1, y + h + 1)
	rect = Rect(p1, p2)

        self.gc.SetFillColor(StandardColors.white)
        self.gc.gc.FillRectangle(x, y, w, h) # XXX ugly to access gc.gc

	#	draw paper
	if self.show_page_outline:
	    w, h = self.document.PageSize()
	    self.gc.DrawPageOutline(w, h)


	self.document.Draw(self.gc, rect)
	if region:
	    self.gc.PopClip()

	if __debug__:
	    if self.time_redraw:
		pdebug('timing', 'redraw', time.clock() - start)

	return region

    def ResizedMethod(self, width, height):
	Viewport.ResizedMethod(self, width, height)
	self.gc.WindowResized(width, height)


    #
    #	Viewport- and related methods
    #
    #	extend some Viewport methods to issue VIEW whenever
    #	the displayed area changes
    #

    def ForceRedraw(self):
	# Force a redraw of the whole window
	self.clear_window()
	if __debug__:
	    #self.time_redraw = 1
	    pass

#     def SetScrollbars(self, hbar, vbar):
# 	Viewport.SetScrollbars(self, hbar, vbar)
# 	hbar.configure(jump = 1)
# 	vbar.configure(jump = 1)

    def set_origin(self, xorg, yorg, move_contents = 1):
	self.begin_transaction()
	try:
	    Viewport.set_origin(self, xorg, yorg,
				move_contents = move_contents)
	    self.set_gc_transforms()
	    self.issue_view()
	finally:
	    self.end_transaction()

    def move_window_contents(self, offx, offy):
	# implement the method needed by Viewport.set_origin
	w = self.tkwin
	width = w.width
	height = w.height
	if abs(offx) < width and abs(offy) < height:
	    w.CopyArea(w, self.gc.gc, offx, offy, width, height, 0, 0)
	    self.move_window_count = self.move_window_count + 1
	else:
	    self.clear_window()

    def SetScale(self, scale, do_center = 1):
	# Set current scale
	self.begin_transaction()
	try:
	    Viewport.SetScale(self, scale, do_center = do_center)
	    self.set_gc_transforms()
	finally:
	    self.end_transaction()

    def zoom_fit_rect(self, rect, save_viewport = 0):
	if save_viewport:
	    self.save_viewport()
	Viewport.zoom_fit_rect(self, rect)


    #
    #	other view related methods
    #
    def FitToWindow(self, selected_only = 0, save_viewport = 1):
	self.begin_transaction()
	try:
	    if selected_only:
		rect = self.document.SelectionBoundingRect()
	    else:
		rect = self.document.BoundingRect()
	    if rect:
		self.zoom_fit_rect(rect, save_viewport = save_viewport)
	finally:
	    self.end_transaction()

    def FitPageToWindow(self, save_viewport = 1):
	self.begin_transaction()
	try:
	    w, h = self.document.PageSize()
	    self.zoom_fit_rect(Rect(0, 0, w, h).grown(10),
			       save_viewport = save_viewport)
	finally:
	    self.end_transaction()


    #
    #	Outline Mode
    #
    #	Although not directly related to the viewport methods (the outline
    #	mode doesn't change the displayed area) the outline mode changes the
    #	way the drawing is displayed and thus issues VIEW.

    def SetOutlineMode(self, on = 1):
	self.begin_transaction()
	try:
	    if on:
		if self.gc.IsOutlineActive():
		    return
		else:
		    self.gc.StartOutlineMode()
		    self.hitgc.StartOutlineMode()
	    else:
		if self.gc.IsOutlineActive():
		    self.gc.EndOutlineMode()
		    self.hitgc.EndOutlineMode()
		else:
		    return
	    self.issue_view()
	    self.clear_window()
	finally:
	    self.end_transaction()

    def ToggleOutlineMode(self):
	self.SetOutlineMode(not self.IsOutlineMode())

    def IsOutlineMode(self):
	return self.gc and self.gc.IsOutlineActive()

    #
    #	Show page outline on/off
    #

    def SetPageOutlineMode(self, on = 1):
	self.begin_transaction()
	try:
	    self.show_page_outline = on
	    self.issue_view()
	    self.clear_window()
	finally:
	    self.end_transaction()

    def TogglePageOutlineMode(self):
	self.SetPageOutlineMode(not self.IsPageOutlineMode())

    def IsPageOutlineMode(self):
	return self.show_page_outline

    #
    #
    #

    def unsubscribe_doc(self):
        if self.document is not None:
            self.document.Unsubscribe(REDRAW, self.redraw_doc)
            self.document.Unsubscribe(LAYOUT, self.layout_changed)
            self.document.Unsubscribe(LAYER, self.layer_changed)

    def subscribe_doc(self):
        self.document.Subscribe(REDRAW, self.redraw_doc)
        self.document.Subscribe(LAYOUT, self.layout_changed)
        self.document.Subscribe(LAYER, self.layer_changed)

    def SetDocument(self, doc):
	self.begin_transaction()
	try:
            self.unsubscribe_doc()
	    self.document = doc
            self.subscribe_doc()
	    self.clear_window()
	    self.SetPageSize(self.document.Layout().Size())
	    self.FitPageToWindow(save_viewport = 0)
	    self.issue_document()
	    self.issue_state()
	    self.issue_view()
	finally:
	    self.end_transaction()
Beispiel #13
0
class PaletteWidget(PyWidget, Publisher):

    def __init__(self, master=None, palette = None, cell_size = 16, **kw):
	if not kw.has_key('height'):
	    kw['height'] = cell_size
	apply(PyWidget.__init__, (self, master), kw)

	self.cell_size = cell_size
	self.num_cells = 0
	self.gc_initialized = 0
	self.gc = GraphicsDevice()
	self.gc.SetViewportTransform(1.0, Identity, Identity)
	self.start_idx = 0
	self.palette = None
	if palette is None:
	    palette = RGBPalette()
	self.SetPalette(palette)
	self.dragging = 0
	self.bind('<ButtonPress-1>', self.press_1)
	self.bind('<Motion>', self.move_1)
	self.bind('<ButtonRelease-1>', self.release_1)
	self.bind('<ButtonRelease-2>', self.apply_color_2)

    def DestroyMethod(self):
	self.palette.Unsubscribe(CHANGED, self.palette_changed)
	Publisher.Destroy(self)

    def compute_num_cells(self):
	self.num_cells = self.tkwin.width / self.cell_size

    def MapMethod(self):
	self.compute_num_cells()
	self.issue(VIEW)
	if not self.gc_initialized:
	    self.init_gc()
	    self.gc_initialized = 1

    def init_gc(self):
	self.gc.init_gc(self.tkwin)

    def get_color(self, x, y):
	if 0 <= x < self.tkwin.width and 0 <= y < self.tkwin.height:
	    i = self.start_idx + x / self.cell_size
	    if i < len(self.palette):
		return apply(CreateRGBColor, self.palette.GetRGB(i))

    def release_1(self, event):
	try:
	    if self.dragging:
		self.drop_color(event)
	    else:
		self.apply_color_1(event)
	finally:
	    self.dragging = 0

    def drop_color(self, event):
	self['cursor'] = self.drag_old_cursor
	w = self.winfo_containing(event.x_root, event.y_root)
	while w and w != self:
	    if __debug__:
		pdebug('DND', 'trying to drop on', w)
	    try:
		accepts = w.accept_drop
	    except AttributeError:
		accepts = ()
	    if DROP_COLOR in accepts:
		x = event.x_root - w.winfo_rootx()
		y = event.y_root - w.winfo_rooty()
		w.DropAt(x, y, DROP_COLOR, self.drag_start)
		break
	    if w != w.winfo_toplevel():
		parent = self.tk.call('winfo', 'parent', w._w)
		w = self.nametowidget(parent)
	    else:
		break


    def apply_color_1(self, event):
	c = self.get_color(event.x, event.y)
	if c:
	    self.issue(COLOR1, c)

    def apply_color_2(self, event):
	c = self.get_color(event.x, event.y)
	if c:
	    self.issue(COLOR2, c)

    drag_start = (0, 0, 0)
    def press_1(self, event):
	self.drag_start = self.get_color(event.x, event.y)

    def move_1(self, event):
	if event.state & X.Button1Mask:
	    if not self.dragging:
		self.dragging = 1
		self.drag_old_cursor = self['cursor']
		self['cursor'] = CurDragColor
	    w = self.winfo_containing(event.x_root, event.y_root)

    def Palette(self):
	return self.palette

    def SetPalette(self, palette):
	if self.palette is not None:
	    self.palette.Unsubscribe(CHANGED, self.palette_changed)
	self.palette = palette
	self.palette.Subscribe(CHANGED, self.palette_changed)
	self.palette_changed()

    def palette_changed(self):
	self.compute_num_cells()
	self.normalize_start()
	self.issue(VIEW)
	self.UpdateWhenIdle()

    def RedrawMethod(self, region = None):
	win = self.tkwin
	width = win.width
	height = win.height
	self.gc.StartDblBuffer()
	self.gc.SetFillColor(StandardColors.white)
	self.gc.FillRectangle(0, 0, width, height)

	x = 0
	FillRectangle = self.gc.FillRectangle
	SetFillColor = self.gc.SetFillColor
	create_color = CreateRGBColor
	rgbs = self.palette.Colors()
	rgbs = rgbs[self.start_idx:self.start_idx + self.num_cells]
	for rgb in rgbs:
	    SetFillColor(apply(create_color, rgb))
	    FillRectangle(x, 0, x + height, height)
	    x = x + height
	self.gc.EndDblBuffer()

    def ResizedMethod(self, width, height):
	self.compute_num_cells()
	self.gc.WindowResized(width, height)
	self.normalize_start()
	self.UpdateWhenIdle()

    def normalize_start(self):
	length = len(self.palette)
	if self.start_idx < 0:
	    self.start_idx = 0
	if length < self.num_cells:
	    self.start_idx = 0
	elif length - self.start_idx < self.num_cells:
	    self.start_idx = length - self.num_cells

    def CanScrollLeft(self):
	return self.start_idx > 0

    def CanScrollRight(self):
	return len(self.palette) - self.start_idx > self.num_cells

    def ScrollXPages(self, count):
	length = self.tkwin.width / self.cell_size
	start = self.start_idx
	self.start_idx = self.start_idx + count * length
	self.normalize_start()
	if start != self.start_idx:
	    self.UpdateWhenIdle()
	    self.issue(VIEW)

    def ScrollXUnits(self, count):
	start = self.start_idx
	self.start_idx = self.start_idx + count
	self.normalize_start()
	if start != self.start_idx:
	    self.UpdateWhenIdle()
	    self.issue(VIEW)
Beispiel #14
0
class PatternSample(PyWidget):

    def __init__(self, master=None, **kw):
        apply(PyWidget.__init__, (self, master), kw)
        self.gc_initialized = 0
        self.gc = GraphicsDevice()
        self.pattern = EmptyPattern
        self.properties = PropertyStack()
        self.properties.AddStyle(EmptyLineStyle)
        self.properties.SetProperty(fill_pattern = self.pattern)
        self.gc.SetProperties(self.properties)
        self.fill_rect = None

    def MapMethod(self):
        self.fill_rect = Rect(0, 0, self.tkwin.width, self.tkwin.height)
        if not self.gc_initialized:
            self.init_gc()
            self.gc_initialized = 1

    def init_gc(self):
        self.gc.init_gc(self.tkwin)
        self.compute_trafo()

    def compute_trafo(self):
        height = self.tkwin.height
        doc_to_win = Trafo(1, 0, 0, -1, 0, height)
        win_to_doc = doc_to_win.inverse()
        self.gc.SetViewportTransform(1.0, doc_to_win, win_to_doc)
        self.fill_rect = Rect(0, 0, self.tkwin.width, self.tkwin.height)
        self.gc.SetProperties(self.properties, self.fill_rect)

    def SetPattern(self, pattern):
        if pattern != self.pattern:
            self.pattern = pattern
            self.UpdateWhenIdle()
            self.properties.SetProperty(fill_pattern = pattern)
            self.gc.SetProperties(self.properties, self.fill_rect)

    def RedrawMethod(self, region = None):
        win = self.tkwin
        self.gc.StartDblBuffer()
        self.gc.SetFillColor(StandardColors.white)
        self.gc.FillRectangle(0, 0, win.width, win.height)
        if self.properties.HasFill():
            self.gc.Rectangle(Trafo(win.width, 0, 0, win.height, 0, 0))
        else:
            self.gc.SetLineColor(StandardColors.black)
            self.gc.DrawLineXY(0, win.height, win.width, 0)
        self.gc.EndDblBuffer()

    def ResizedMethod(self, width, height):
        self.gc.WindowResized(width, height)
        self.UpdateWhenIdle()
        self.compute_trafo()