Пример #1
0
 def is_point_in(self, p: Point, category=MouseEvent.UNKNOWN):
     v = self._vertexes
     start = Point(min(x.x for x in v), min(x.y for x in v))
     width = max(x.x for x in v) - start.x
     height = max(x.y for x in v) - start.y
     rectangle = Rectangle(start, width, height)
     return rectangle.is_point_in(p)
Пример #2
0
 def is_point_in(self,p: Point,category=MouseEvent.UNKNOWN):
     v = self._vertexes
     start = Point(min(x.x for x in v), min(x.y for x in v))
     width = max(x.x for x in v) - start.x
     height = max(x.y for x in v) - start.y
     rectangle = Rectangle(start, width, height)
     return rectangle.is_point_in(p)
Пример #3
0
class _GuideLine(Widget):
    def __init__(self,
                 elements: List[int],
                 orientation: Orientation,
                 line_thickness: int,
                 font_size: int,
                 max_size: int = None,
                 element_distance: int = 10,
                 line_distance: int = 1.8,
                 **kwargs):
        super().__init__(**kwargs)

        if not elements:
            elements = [0]
        self._elements = [_GuideElement(str(e)) for e in elements]
        self.orientation = orientation
        self.line_thickness = line_thickness
        self.font_size = font_size
        self.shape = None
        self.max_size = max_size
        self.element_distance = element_distance
        self.line_distance = line_distance
        self.mouse_was_down = False

        self.line_extension = 0
        self._selected_cell = None

    def set_done(self):
        for e in self._elements:
            e.is_done = True
            e.is_wrong = False

    def set_wrong(self):
        for e in self._elements:
            e.is_wrong = True
            e.is_done = False

    def set_default(self):
        for e in self._elements:
            e.is_wrong = False
            e.is_done = False

    def set_cancelled(self, is_it: bool, index: int):
        self._elements[index].is_cancelled = is_it

    def toggle_cancelled(self, index: int):
        e = self._elements[index]
        e.is_cancelled = not e.is_cancelled

    def set_shape_from_context(self, context: cairo.Context):

        widths_heights = []

        done = False

        while not done:
            max_width = 0
            max_height = 0
            context.set_font_size(self.font_size)

            for e in reversed(self._elements):
                xb, yb, w, h, xa, ya = context.text_extents(e.label)
                widths_heights.append((xa, h))
                e.width = xa
                e.height = h
                max_width = max(max_width, xa)
                max_height = max(max_height, h)

            # adjust font size in case it's too big
            if self.max_size is None:
                done = True
            else:
                if self.orientation == Orientation.HORIZONTAL:
                    reference = max_height
                else:
                    reference = max_width
                if reference + 2 * self.line_distance <= self.max_size:
                    done = True
                else:
                    self.font_size -= 1

        positions = []
        width = self.element_distance
        height = self.element_distance

        def get_padding(actual_size):
            if self.max_size is not None:
                return (self.max_size - actual_size) / 2
            else:
                return self.line_distance

        if self.orientation == Orientation.HORIZONTAL:

            def handle_extents(e: _GuideElement):
                nonlocal width, height, positions, max_height
                width += e.width
                e.position = (-width, max_height + get_padding(max_height))
                width += self.element_distance
        else:

            def handle_extents(e: _GuideElement):
                nonlocal width, height, positions, max_width
                e.position = (get_padding(e.width), -height)
                height += e.height + self.element_distance

        # for w, h in widths_heights:
        #     handle_extents(w, h)

        for element in reversed(self._elements):
            handle_extents(element)

        if self.orientation == Orientation.HORIZONTAL:
            height = max_height + get_padding(max_height) * 2
            width = width - self.element_distance + self.line_distance
            base_point = Point(-width, 0)
        else:
            width = max_width + get_padding(max_width) * 2
            height = height - self.element_distance + self.line_distance
            base_point = Point(0, -height)

        self.shape = Rectangle(base_point, width, height)
        # for e, p in zip(self._elements, reversed(positions)):
        #     e.position = p

    def on_draw(self, widget: Widget, context: cairo.Context):

        self.set_shape_from_context(context)
        shape = self.shape

        context.set_line_width(self.line_thickness)
        if self.orientation == Orientation.HORIZONTAL:
            context.move_to(shape.start.x - self.line_extension, shape.start.y)
            context.line_to(shape.start.x + shape.width, shape.start.y)
        else:
            context.move_to(shape.start.x, shape.start.y - self.line_extension)
            context.line_to(shape.start.x, shape.start.y + shape.height)
        context.stroke()

        for element in self._elements:
            context.move_to(*element.position)
            context.set_source_rgb(*element.color)
            context.show_text(element.label)

    def get_cell(self, p: Point):
        delta = self.line_distance
        for index, element in enumerate(self._elements):
            if Rectangle(
                    Point(*element.position) + Point(-delta, delta),
                    element.width + 2 * delta,
                    -element.height - 2 * delta).is_point_in(p):
                return index
        return None

    def on_mouse_down(self, widget: Widget, event: MouseEvent):
        self._selected_cell = self.get_cell(event)

    def on_mouse_up(self, widget: Widget, event: MouseEvent):
        if self._selected_cell is not None and \
                        self._selected_cell == self.get_cell(event):
            self.toggle_cancelled(self._selected_cell)
            self.invalidate()
        self._selected_cell = None

    def is_point_in(self, p: Point, category=MouseEvent.UNKNOWN):
        if self.shape is None:
            return False
        elif (category == MouseEvent.MOUSE_UP and self.mouse_was_down) \
                or self.shape.is_point_in(p):
            return True
        else:
            return False
Пример #4
0
class _GuideLine(Widget):

    def __init__(self, elements: List[int],
                 orientation: Orientation, line_thickness: int,
                 font_size: int, max_size: int = None,
                 element_distance: int=10, line_distance: int=1.8,
                 **kwargs):
        super().__init__(**kwargs)

        if not elements:
            elements = [0]
        self._elements = [_GuideElement(str(e)) for e in elements]
        self.orientation = orientation
        self.line_thickness = line_thickness
        self.font_size = font_size
        self.shape = None
        self.max_size = max_size
        self.element_distance = element_distance
        self.line_distance = line_distance
        self.mouse_was_down = False

        self.line_extension = 0
        self._selected_cell = None

    def set_done(self):
        for e in self._elements:
            e.is_done = True
            e.is_wrong = False

    def set_wrong(self):
        for e in self._elements:
            e.is_wrong = True
            e.is_done = False

    def set_default(self):
        for e in self._elements:
            e.is_wrong = False
            e.is_done = False

    def set_cancelled(self, is_it: bool, index: int):
        self._elements[index].is_cancelled = is_it

    def toggle_cancelled(self, index: int):
        e = self._elements[index]
        e.is_cancelled = not e.is_cancelled

    def set_shape_from_context(self, context: cairo.Context):

        widths_heights = []

        done = False

        while not done:
            max_width = 0
            max_height = 0
            context.set_font_size(self.font_size)

            for e in reversed(self._elements):
                xb, yb, w, h, xa, ya = context.text_extents(e.label)
                widths_heights.append((xa, h))
                e.width = xa
                e.height = h
                max_width = max(max_width, xa)
                max_height = max(max_height, h)


            # adjust font size in case it's too big
            if self.max_size is None:
                done = True
            else:
                if self.orientation == Orientation.HORIZONTAL:
                    reference = max_height
                else:
                    reference = max_width
                if reference + 2 * self.line_distance <= self.max_size:
                    done = True
                else:
                    self.font_size -= 1

        positions = []
        width = self.element_distance
        height = self.element_distance

        def get_padding(actual_size):
            if self.max_size is not None:
                return (self.max_size - actual_size) / 2
            else:
                return self.line_distance

        if self.orientation == Orientation.HORIZONTAL:
            def handle_extents(e: _GuideElement):
                nonlocal width, height, positions, max_height
                width += e.width
                e.position = (-width,
                              max_height + get_padding(max_height))
                width += self.element_distance
        else:
            def handle_extents(e: _GuideElement):
                nonlocal width, height, positions, max_width
                e.position = (get_padding(e.width),
                              -height)
                height += e.height + self.element_distance

        # for w, h in widths_heights:
        #     handle_extents(w, h)

        for element in reversed(self._elements):
            handle_extents(element)

        if self.orientation == Orientation.HORIZONTAL:
            height = max_height + get_padding(max_height) * 2
            width = width - self.element_distance + self.line_distance
            base_point = Point(-width, 0)
        else:
            width = max_width + get_padding(max_width) * 2
            height = height - self.element_distance + self.line_distance
            base_point = Point(0, -height)

        self.shape = Rectangle(base_point, width, height)
        # for e, p in zip(self._elements, reversed(positions)):
        #     e.position = p

    def on_draw(self, widget: Widget, context: cairo.Context):

        self.set_shape_from_context(context)
        shape = self.shape

        context.set_line_width(self.line_thickness)
        if self.orientation == Orientation.HORIZONTAL:
            context.move_to(shape.start.x - self.line_extension, shape.start.y)
            context.line_to(shape.start.x + shape.width, shape.start.y)
        else:
            context.move_to(shape.start.x, shape.start.y - self.line_extension)
            context.line_to(shape.start.x, shape.start.y + shape.height)
        context.stroke()

        for element in self._elements:
            context.move_to(*element.position)
            context.set_source_rgb(*element.color)
            context.show_text(element.label)

    def get_cell(self, p: Point):
        delta = self.line_distance
        for index, element in enumerate(self._elements):
            if Rectangle(Point(*element.position) + Point(-delta, delta),
                         element.width + 2 * delta,
                         -element.height - 2 * delta).is_point_in(p):
                return index
        return None

    def on_mouse_down(self, widget: Widget, event: MouseEvent):
        self._selected_cell = self.get_cell(event)

    def on_mouse_up(self, widget: Widget, event: MouseEvent):
        if self._selected_cell is not None and \
                        self._selected_cell == self.get_cell(event):
            self.toggle_cancelled(self._selected_cell)
            self.invalidate()
        self._selected_cell = None

    def is_point_in(self, p: Point, category=MouseEvent.UNKNOWN):
        if self.shape is None:
            return False
        elif (category == MouseEvent.MOUSE_UP and self.mouse_was_down) \
                or self.shape.is_point_in(p):
            return True
        else:
            return False
Пример #5
0
class Navigator(UncheckedContainer):

    def __init__(self, side=40, protrusion=30):
        super().__init__()
        base_size = side
        height = protrusion
        colour = global_constants.start_selected
        arrow_up = Arrow(base_size, height, Arrow.UP, colour)
        arrow_down = Arrow(base_size, height, Arrow.DOWN, colour)
        arrow_left = Arrow(base_size, height, Arrow.LEFT, colour)
        arrow_right = Arrow(base_size, height, Arrow.RIGHT, colour)
        factor=6
        center = height + base_size/2 + (base_size/factor)
        distance = (base_size + height)/2 + (base_size/factor)

        arrow_up.translate(center, center - distance)
        arrow_left.translate(center - distance, center)
        arrow_right.translate(center + distance, center)
        arrow_down.translate(center, center + distance)

        self.background_rectangle = Rectangle(Point(0,0), center * 2, center * 2)

        self.add(arrow_up)
        self.add(arrow_down)
        self.add(arrow_left)
        self.add(arrow_right)

        self._should_pass_move = False

    def on_mouse_up(self, widget, event):
        self._should_pass_move = False
        super().on_mouse_up(widget, event)
        return False

    def on_mouse_enter(self) -> bool:
        if self.mouse_is_down:
            self._should_pass_move = True
        return super().on_mouse_enter()

    def on_mouse_exit(self) -> bool:
        self._should_pass_move = False
        return super().on_mouse_exit()

    def on_mouse_move(self, widget, event):
        super().on_mouse_move(widget, event)
        return False

    def on_mouse_down(self, widget, event):
        super().on_mouse_down(widget, event)
        return True

    @property
    def fromWidgetCoords(self):
        width = self.background_rectangle.width
        height = self.background_rectangle.height
        total_width, total_height = self.container_size
        transl_width, transl_height = self._fromScale.transform_point(width, height)
        self.set_translate(total_width - transl_width, total_height - transl_height)
        return super().fromWidgetCoords

    @property
    def width(self):
        return self.background_rectangle.width

    def on_draw(self,widget,context):

        start = self.background_rectangle.start
        width = self.background_rectangle.width
        height = self.background_rectangle.height

        context.save()
        context.rectangle(start.x,start.y,width,height)
        context.set_source_rgb(0,0,0)
        context.stroke_preserve()
        context.set_source_rgb(*global_constants.background)
        context.fill()
        context.restore()

        super().on_draw(widget,context)

    def is_point_in(self, p:"Point", category=MouseEvent.UNKNOWN):
        return self.background_rectangle.is_point_in(p)