Esempio n. 1
0
	def __init__(self, parent):

		gtk.DrawingArea.__init__(self)
		self.mw = parent
		self.presenter = parent.presenter
		self.eventloop = self.presenter.eventloop
		self.app = self.presenter.app

		self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#ffffff"))

		self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
					gtk.gdk.POINTER_MOTION_MASK |
					gtk.gdk.BUTTON_RELEASE_MASK |
              		gtk.gdk.SCROLL_MASK)

		self.connect('button_press_event', self.mousePressEvent)
		self.connect('motion_notify_event', self.mouseMoveEvent)
		self.connect('button_release_event', self.mouseReleaseEvent)
		self.connect('scroll-event', self.wheelEvent)

		self.connect('expose_event', self.repaint)
		self.trafo = [1.0, 0.0, 0.0, 1.0, 0.0 , 0.0]
		self.mw.h_adj.connect('value_changed', self.hscroll)
		self.mw.v_adj.connect('value_changed', self.vscroll)

		self.doc = self.presenter.model
		self.renderer = CairoRenderer(self)
		self.my_change = False
		self.ctrls = self.init_controllers()
		self.eventloop.connect(self.eventloop.DOC_MODIFIED, self.repaint)
		self.eventloop.connect(self.eventloop.SELECTION_CHANGED,
							self.selection_repaint)
Esempio n. 2
0
 def __init__(self, filename, width, height):
     self.filename = filename
     self.renderer = CairoRenderer(width, height)
Esempio n. 3
0
class RenderInstance:
    def __init__(self, filename, width, height):
        self.filename = filename
        self.renderer = CairoRenderer(width, height)

    def draw_rect(self,
                  id: str = "",
                  x: float = 0,
                  y: float = 0,
                  w: float = 100,
                  h: float = 100,
                  color: Color = BLACK,
                  stroke: bool = False,
                  fill: bool = True,
                  radius: float = 0) -> None:
        self.renderer.set_color(*color)
        self.renderer.plot_rectangle(x, y, w, h, radius)
        if stroke:
            self.renderer.stroke()
        if fill:
            self.renderer.fill()

    def draw_image(self,
                   id: str = "",
                   x: float = 0,
                   y: float = 0,
                   w: float = 100,
                   h: float = 100,
                   file: str = "") -> None:
        try:
            width, height = self.renderer.set_image_buffer(file)
        except FileNotFoundError:
            warnings.warn("Could not load file: {}".format(file))
            return
        with self.renderer.translate(x, y):
            with self.renderer.scale(w / width, h / height):
                self.renderer.paint_image()

    def draw_text(
        self,
        id: str = None,
        x: float = 0,
        y: float = 0,
        w: float = -1.0,  # By default, DON'T restrict w/h
        h: float = -1.0,
        text: str = "",
        color: Color = BLACK,
        font_name: str = "Ubuntu",
        font_size: int = 16,
        align: str = "left",
        line_spacing: int = 0,
        justify: bool = False,
        debug: bool = False,
    ):
        """Draw the configured text widget on the canvas.
        """
        # First, draw a debug box (if requested)
        if debug:
            self.draw_rect(x=x,
                           y=y,
                           w=w,
                           h=h,
                           color=Color(0.0, 1.0, 1.0, 1.0),
                           stroke=True,
                           fill=False)

        # Process the inputs
        text = text.replace("\\n", "\n")
        alignment = {
            "left": TextAlignment.Left,
            "center": TextAlignment.Center,
            "right": TextAlignment.Right,
        }[align]  # TODO: Validate on the parser

        # Configure the text
        self.renderer.set_font(font_name, font_size)
        self.renderer.configure_text_layout(
            width=w,
            height=h,
            line_spacing=line_spacing,
            alignment=alignment,
            justify=justify,
        )
        self.renderer.set_color(*color)
        self.renderer.set_text(text)

        # Draw the text
        with self.renderer.translate(x, y):
            self.renderer.paint_text()

    def draw_table(
        self,
        id: str = None,
        data: [] = None,
        x: float = 0,
        y: float = 0,
        w: float = 100,
        padding_x: int = 2,
        padding_y: int = 2,
        color: Color = BLACK,
        border_color: Color = BLACK,
        font_name: str = "Ubuntu",
        font_size: int = 16,
    ):
        # Load the data
        if not data:
            return
        data = json.loads(data)
        # TODO: Assert the table data is rectangular

        # Set the font
        self.renderer.set_font(font_name, font_size)

        # First pass to generate the column widths
        widths = [0] * len(data[0])
        for row in data:
            for i, text in enumerate(row):
                text = text.replace("\\n", "\n")
                self.renderer.set_text(text)
                self.renderer.configure_text_layout(width=w,
                                                    height=-MAX_TABLE_LINES)
                this_w, _ = self.renderer.get_text_size()
                this_w += padding_x * 2
                widths[i] = max(this_w, widths[i])

        # Make the widths smaller until it fits
        widths = _scale_column_widths(widths, w)

        # Second pass to do rendering
        cursor_y = 0
        for i, row in enumerate(data):
            cursor_x = 0

            # calculate the height of this row
            height = 0
            for j, text in enumerate(row):
                self.renderer.set_text(text)
                self.renderer.configure_text_layout(width=widths[j],
                                                    height=-MAX_TABLE_LINES)
                _, h = self.renderer.get_text_size()
                height = max(height, h)
            height += padding_y * 2

            for j, text in enumerate(row):
                # render the table cell
                self.draw_rect(x=x + cursor_x,
                               y=y + cursor_y,
                               w=widths[j],
                               h=height,
                               stroke=True,
                               fill=False,
                               color=border_color)
                # then render the text inside it
                self.draw_text(text=text,
                               x=x + cursor_x + padding_x,
                               y=y + cursor_y + padding_y,
                               w=widths[j],
                               h=height,
                               color=color,
                               font_name=font_name,
                               font_size=font_size)
                cursor_x += widths[j]
            cursor_y += height

    def save(self):
        self.renderer.save(self.filename)
Esempio n. 4
0
 def __init__(self, filename, width, height):
     self.filename = filename
     self.renderer = CairoRenderer(width, height)
Esempio n. 5
0
class RenderInstance:
    def __init__(self, filename, width, height):
        self.filename = filename
        self.renderer = CairoRenderer(width, height)

    def draw_rect(self,
                  id: str="",
                  x: float=0,
                  y: float=0,
                  w: float=100,
                  h: float=100,
                  color: Color=BLACK,
                  stroke: bool=False,
                  fill: bool=True,
                  radius: float=0) -> None:
        self.renderer.set_color(*color)
        self.renderer.plot_rectangle(x, y, w, h, radius)
        if stroke:
            self.renderer.stroke()
        if fill:
            self.renderer.fill()

    def draw_image(self,
                   id: str="",
                   x: float=0,
                   y: float=0,
                   w: float=100,
                   h: float=100,
                   file: str="") -> None:
        try:
            width, height = self.renderer.set_image_buffer(file)
        except FileNotFoundError:
            warnings.warn("Could not load file: {}".format(file))
            return
        with self.renderer.translate(x, y):
            with self.renderer.scale(w/width, h/height):
                self.renderer.paint_image()

    def draw_text(self,
                  id: str=None,
                  x: float=0,
                  y: float=0,
                  w: float=-1.0,  # By default, DON'T restrict w/h
                  h: float=-1.0,
                  text: str="",
                  color: Color=BLACK,
                  font_name: str="Ubuntu",
                  font_size: int=16,
                  align: str="left",
                  line_spacing: int=0,
                  justify: bool=False,
                  debug: bool=False,
                  ):
        """Draw the configured text widget on the canvas.
        """
        # First, draw a debug box (if requested)
        if debug:
            self.draw_rect(x=x, y=y, w=w, h=h, color=Color(0.0, 1.0, 1.0, 1.0),
                           stroke=True, fill=False)

        # Process the inputs
        text = text.replace("\\n", "\n")
        alignment = {
            "left": TextAlignment.Left,
            "center": TextAlignment.Center,
            "right": TextAlignment.Right,
        }[align]  # TODO: Validate on the parser

        # Configure the text
        self.renderer.set_font(font_name, font_size)
        self.renderer.configure_text_layout(
            width=w, height=h,
            line_spacing=line_spacing,
            alignment=alignment,
            justify=justify,
        )
        self.renderer.set_color(*color)
        self.renderer.set_text(text)

        # Draw the text
        with self.renderer.translate(x, y):
            self.renderer.paint_text()

    def draw_table(self,
                   id: str=None,
                   data: []=None,
                   x: float=0,
                   y: float=0,
                   w: float=100,
                   padding_x: int=2,
                   padding_y: int=2,
                   color: Color=BLACK,
                   border_color: Color=BLACK,
                   font_name: str="Ubuntu",
                   font_size: int=16,
                   ):
        # Load the data
        if not data:
            return
        data = json.loads(data)
        # TODO: Assert the table data is rectangular

        # Set the font
        self.renderer.set_font(font_name, font_size)

        # First pass to generate the column widths
        widths = [0] * len(data[0])
        for row in data:
            for i, text in enumerate(row):
                text = text.replace("\\n", "\n")
                self.renderer.set_text(text)
                self.renderer.configure_text_layout(
                    width=w, height=-MAX_TABLE_LINES)
                this_w, _ = self.renderer.get_text_size()
                this_w += padding_x * 2
                widths[i] = max(this_w, widths[i])

        # Make the widths smaller until it fits
        widths = _scale_column_widths(widths, w)

        # Second pass to do rendering
        cursor_y = 0
        for i, row in enumerate(data):
            cursor_x = 0

            # calculate the height of this row
            height = 0
            for j, text in enumerate(row):
                self.renderer.set_text(text)
                self.renderer.configure_text_layout(
                    width=widths[j], height=-MAX_TABLE_LINES)
                _, h = self.renderer.get_text_size()
                height = max(height, h)
            height += padding_y * 2

            for j, text in enumerate(row):
                # render the table cell
                self.draw_rect(x=x + cursor_x, y=y + cursor_y, w=widths[j],
                               h=height, stroke=True, fill=False,
                               color=border_color)
                # then render the text inside it
                self.draw_text(text=text,
                               x=x + cursor_x + padding_x,
                               y=y + cursor_y + padding_y,
                               w=widths[j], h=height, color=color,
                               font_name=font_name, font_size=font_size)
                cursor_x += widths[j]
            cursor_y += height

    def save(self):
        self.renderer.save(self.filename)
Esempio n. 6
0
class AppCanvas(gtk.DrawingArea):

	mw = None
	matrix = None
	trafo = []
	zoom = 1.0
	width = 0
	height = 0
	mode = None
	previous_mode = None
	controller = None
	ctrls = None
	orig_cursor = None
	current_cursor = None
	resize_marker = 0
	stroke_view = False
	draft_view = False

	def __init__(self, parent):

		gtk.DrawingArea.__init__(self)
		self.mw = parent
		self.presenter = parent.presenter
		self.eventloop = self.presenter.eventloop
		self.app = self.presenter.app

		self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#ffffff"))

		self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
					gtk.gdk.POINTER_MOTION_MASK |
					gtk.gdk.BUTTON_RELEASE_MASK |
              		gtk.gdk.SCROLL_MASK)

		self.connect('button_press_event', self.mousePressEvent)
		self.connect('motion_notify_event', self.mouseMoveEvent)
		self.connect('button_release_event', self.mouseReleaseEvent)
		self.connect('scroll-event', self.wheelEvent)

		self.connect('expose_event', self.repaint)
		self.trafo = [1.0, 0.0, 0.0, 1.0, 0.0 , 0.0]
		self.mw.h_adj.connect('value_changed', self.hscroll)
		self.mw.v_adj.connect('value_changed', self.vscroll)

		self.doc = self.presenter.model
		self.renderer = CairoRenderer(self)
		self.my_change = False
		self.ctrls = self.init_controllers()
		self.eventloop.connect(self.eventloop.DOC_MODIFIED, self.repaint)
		self.eventloop.connect(self.eventloop.SELECTION_CHANGED,
							self.selection_repaint)

	def init_controllers(self):
		dummy = controllers.AbstractController(self, self.presenter)
		ctrls = {
		modes.SELECT_MODE: controllers.SelectController(self, self.presenter),
		modes.SHAPER_MODE: dummy,
		modes.ZOOM_MODE: controllers.ZoomController(self, self.presenter),
		modes.FLEUR_MODE: controllers.FleurController(self, self.presenter),
		modes.LINE_MODE: dummy,
		modes.CURVE_MODE: dummy,
		modes.RECT_MODE: creators.RectangleCreator(self, self.presenter),
		modes.ELLIPSE_MODE: dummy,
		modes.TEXT_MODE: dummy,
		modes.POLYGON_MODE: dummy,
		modes.MOVE_MODE: controllers.MoveController(self, self.presenter),
		modes.RESIZE_MODE: controllers.TransformController(self, self.presenter),
		}
		return ctrls


	def set_mode(self, mode=modes.SELECT_MODE):
		if not mode == self.mode:
			self.mode = mode
#			self.set_canvas_cursor(mode)
			self.controller = self.ctrls[mode]
			self.controller.set_cursor()
			events.emit(events.MODE_CHANGED, mode)

	def set_temp_mode(self, mode=modes.SELECT_MODE):
		if not mode == self.mode:
			self.previous_mode = self.mode
			self.mode = mode
#			self.set_canvas_cursor(mode)
			self.controller = self.ctrls[mode]
			self.controller.set_cursor()

	def restore_mode(self):
		if not self.previous_mode is None:
			self.set_mode(self.previous_mode)
			self.previous_mode = None

	def set_canvas_cursor(self, mode):
		self.current_cursor = self.app.cursors[mode]
		self.window.set_cursor(self.current_cursor)

	def set_temp_cursor(self, cursor):
		self.orig_cursor = self.app.cursors[self.mode]
		self.current_cursor = cursor
		self.window.set_cursor(cursor)

	def restore_cursor(self):
		if not self.orig_cursor is None:
			self.window.set_cursor(self.orig_cursor)
			self.current_cursor = self.orig_cursor
			self.orig_cursor = None

	def vscroll(self, *args):
		if self.my_change:
			self.my_change = False
		else:
			m11, m12, m21, m22, dx, dy = self.trafo
			val = float(self.mw.v_adj.get_value()) * m11
			dy = -val
			self.trafo = [m11, m12, m21, m22, dx, dy]
			self.matrix = cairo.Matrix(m11, m12, m21, m22, dx, dy)
			self.force_redraw()

	def hscroll(self, *args):
		m11, m12, m21, m22, dx, dy = self.trafo
		val = float(self.mw.h_adj.get_value()) * m11
		dx = -val
		self.trafo = [m11, m12, m21, m22, dx, dy]
		self.matrix = cairo.Matrix(m11, m12, m21, m22, dx, dy)
		self.force_redraw()

	def update_scrolls(self):
		x, y = self.win_to_doc()
		m11 = self.trafo[0]

		self.mw.h_adj.set_lower(-WORKSPACE_WIDTH / 2.0)
		self.mw.h_adj.set_upper(WORKSPACE_WIDTH / 2.0)
		self.mw.h_adj.set_page_size(self.width / m11)
		self.mw.h_adj.set_step_increment(self.width / (m11 * 10.0))
		self.my_change = True
		self.mw.h_adj.set_value(x)

		self.mw.v_adj.set_lower(-WORKSPACE_HEIGHT / 2.0)
		self.mw.v_adj.set_upper(WORKSPACE_HEIGHT / 2.0)
		self.mw.v_adj.set_page_size(self.height / m11)
		self.mw.v_adj.set_step_increment(self.height / (m11 * 10.0))
		self.my_change = True
		self.mw.v_adj.set_value(-y)

	def _keep_center(self):
		x, y, w, h = self.allocation
		w = float(w)
		h = float(h)
		if not w == self.width or not h == self.height:
			_dx = (w - self.width) / 2.0
			_dy = (h - self.height) / 2.0
			m11, m12, m21, m22, dx, dy = self.trafo
			dx += _dx
			dy += _dy
			self.trafo = [m11, m12, m21, m22, dx, dy]
			self.matrix = cairo.Matrix(m11, m12, m21, m22, dx, dy)
			self.width = w
			self.height = h
			self.update_scrolls()

	def _set_center(self, center):
		x, y = center
		_dx = self.width / 2.0 - x
		_dy = self.height / 2.0 - y
		m11, m12, m21, m22, dx, dy = self.trafo
		dx += _dx
		dy += _dy
		self.trafo = [m11, m12, m21, m22, dx, dy]
		self.matrix = cairo.Matrix(m11, m12, m21, m22, dx, dy)
		self.update_scrolls()

	def doc_to_win(self, point=[0.0, 0.0]):
		x, y = point
		m11, m12, m21, m22, dx, dy = self.trafo
		x_new = m11 * x + dx
		y_new = m22 * y + dy
		return [x_new, y_new]

	def win_to_doc(self, point=[0, 0]):
		x, y = point
		x = float(x)
		y = float(y)
		m11, m12, m21, m22, dx, dy = self.trafo
		x_new = (x - dx) / m11
		y_new = (y - dy) / m22
		return [x_new, y_new]

	def _fit_to_page(self):
		width, height = self.presenter.get_page_size()

		x, y, w, h = self.allocation
		w = float(w)
		h = float(h)
		self.width = w
		self.height = h
		zoom = min(w / width, h / height) * PAGEFIT
		dx = w / 2.0
		dy = h / 2.0
		self.trafo = [zoom, 0, 0, -zoom, dx, dy]
		self.matrix = cairo.Matrix(zoom, 0, 0, -zoom, dx, dy)
		self.zoom = zoom
		self.update_scrolls()

	def zoom_fit_to_page(self):
		self._fit_to_page()
		self.force_redraw()

	def _zoom(self, dzoom=1.0):
		m11, m12, m21, m22, dx, dy = self.trafo
		m11 *= dzoom
		_dx = (self.width * dzoom - self.width) / 2.0
		_dy = (self.height * dzoom - self.height) / 2.0
		dx = dx * dzoom - _dx
		dy = dy * dzoom - _dy
		self.trafo = [m11, m12, m21, -m11, dx, dy]
		self.matrix = cairo.Matrix(m11, m12, m21, -m11, dx, dy)
		self.zoom = m11
		self.update_scrolls()
		self.force_redraw()

	def zoom_in(self):
		self._zoom(ZOOM_IN)

	def zoom_out(self):
		self._zoom(ZOOM_OUT)

	def zoom_100(self):
		self._zoom(1.0 / self.zoom)

	def zoom_at_point(self, point, zoom):
		self._set_center(point)
		self._zoom(zoom)

	def zoom_to_rectangle(self, start, end):
		x, y, w, h = self.allocation
		w = float(w)
		h = float(h)
		self.width = w
		self.height = h
		width = abs(end[0] - start[0])
		height = abs(end[1] - start[1])
		zoom = min(w / width, h / height)
		center = [start[0] + (end[0] - start[0]) / 2,
				start[1] + (end[1] - start[1]) / 2]
		self._set_center(center)
		self._zoom(zoom)

	def zoom_selected(self):
		x0, y0, x1, y1 = self.presenter.selection.frame
		start = self.doc_to_win([x0, y0])
		end = self.doc_to_win([x1, y1])
		self.zoom_to_rectangle(start, end)

	def select_at_point(self, point, flag=False):
		point = self.win_to_doc(point)
		self.presenter.selection.select_at_point(point, flag)

	def select_by_rect(self, start, end, flag=False):
		start = self.win_to_doc(start)
		end = self.win_to_doc(end)
		rect = start + end
		rect = normalize_bbox(rect)
		self.presenter.selection.select_by_rect(rect, flag)

	def force_redraw(self):
		self.queue_draw()
		self.eventloop.emit(self.eventloop.VIEW_CHANGED)

	def repaint(self, *args):
		if self.matrix is None:
			self.zoom_fit_to_page()
			self.set_mode(modes.SELECT_MODE)
		self._keep_center()
		self.renderer.paint_document()

	def selection_repaint(self, *args):
		self.renderer.paint_selection()

#==============EVENT CONTROLLING==========================
	def mouseDoubleClickEvent(self, widget, event):
		pass

	def mouseMoveEvent(self, widget, event):
		self.controller.mouse_move(event)

	def mousePressEvent(self, widget, event):
		self.controller.set_cursor()
		self.controller.mouse_down(event)

	def mouseReleaseEvent(self, widget, event):
		self.controller.mouse_up(event)

	def wheelEvent(self, widget, event):
		self.controller.wheel(event)

	def keyPressEvent(self, widget, event):
		pass

	def keyReleaseEvent(self, widget, event):
		pass