Example #1
0
 def on_draw(self, widget: Widget, context: cairo.Context):
     self.shape.draw_on_context(context)
     context.set_source_rgb(*global_constants.background)
     context.fill_preserve()
     context.set_source_rgb(0, 0, 0)
     context.stroke()
     super().on_draw(widget, context)
Example #2
0
    def fill(
        self,
        ctx: cairo.Context,
        rng: Generator,
        x1: float,
        y1: float,
        x2: float,
        y2: float,
    ):
        with source(ctx, self.stops[-1].to_pattern()):
            ctx.fill_preserve()

        # Orient the canvas so that our gradient goes straight in direction of +Y.
        gradient_angle = angle((x1, y1), (x2, y2)) - (pi / 2)
        with translation(ctx, x1, y1), rotation(ctx, gradient_angle), source(
                ctx, self.stops[0].to_pattern()):
            # We translated and rotated the canvas, so our gradient control
            # vector is now from (0, 0) straight up:
            grad_control_y = distance((x1, y1), (x2, y2))
            # Get a bounding box of what needs to be filled:
            start_x, start_y, end_x, end_y = ctx.fill_extents()
            ctx.new_path()

            for cx, cy, cr in self.pattern.func(
                    rng,
                (start_x, start_y),
                (end_x, end_y),
                (0, 0),
                (0, grad_control_y),
                    self.dot_radius,
            ):
                ctx.arc(cx, cy, cr, 0, tau)
                ctx.fill()
Example #3
0
    def on_draw(self, widget: Widget, context: cairo.Context):
        if not self.is_shape_set:
            self.layout(context)

        context.set_font_size(self.font_size)

        self.shape.draw_on_context(context)
        context.set_source_rgb(1, 1, 1)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.stroke()
        shape = self.shape

        label = self.label
        if len(label) > 0 and label[-1] == ' ':
            label += '.'
        xb, yb, w, h, xa, ya = context.text_extents(label)
        context.rectangle(shape.start.x + self.padding,
                          shape.start.y,
                          shape.width - self.padding,
                          shape.height)
        context.clip()
        context.move_to(shape.start.x + (shape.width - self.padding - w)/2,
                        shape.start.y + shape.height - self.padding)
        context.show_text(self.label)
Example #4
0
 def on_draw(self, widget: Widget, context: cairo.Context):
     context.save()
     self.shape.draw_on_context(context)
     context.set_source_rgb(1, 1, 1)
     context.fill_preserve()
     context.set_source_rgb(0, 0, 0)
     context.stroke()
     context.restore()
     super().on_draw(widget, context)
Example #5
0
 def on_draw(self, widget: Widget, context: cairo.Context):
     context.save()
     self.shape.draw_on_context(context)
     context.set_source_rgb(1, 1, 1)
     context.fill_preserve()
     context.set_source_rgb(0, 0, 0)
     context.stroke()
     context.restore()
     super().on_draw(widget, context)
Example #6
0
    def on_draw(self, widget: Widget, context: cairo.Context):

        context.save()
        context.set_source_rgb(*self.background_color)
        self.shape.draw_on_context(context)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.set_line_width(1)
        context.stroke()

        context.restore()

        super().on_draw(widget, context)
Example #7
0
    def on_draw(self, widget: Widget, context: cairo.Context):

        context.save()
        context.set_source_rgb(*self.background_color)
        self.shape.draw_on_context(context)
        context.fill_preserve()
        context.set_source_rgb(0,0,0)
        context.set_line_width(1)
        context.stroke()

        context.restore()

        super().on_draw(widget, context)
Example #8
0
 def _polygon(self, ctx: cairo.Context, points, color, outline=None):
     ctx.new_path()
     for point in points:
         ctx.line_to(*point)
     ctx.close_path()
     ctx.set_source_rgba(*color)
     if outline is not None:
         ctx.fill_preserve()
         ctx.set_source_rgba(*outline)
         ctx.set_line_width(1)
         ctx.stroke()
     else:
         ctx.fill()
Example #9
0
 def on_draw(self, widget: Widget, context: cairo.Context):
     super().on_draw(widget, context)
     if self.shape is not None:
         self.__wrapper_shape.draw_on_context(context)
         context.stroke()
         context.set_source_rgb(*global_constants.background)
         self.__outer_font_box.draw_on_context(context)
         context.fill_preserve()
         context.set_source_rgb(0, 0, 0)
         context.stroke()
         context.move_to(self.__title_start_point.x,
                         self.__title_start_point.y)
         context.set_font_size(self.font_size)
         context.show_text(self.title)
Example #10
0
    def func_wrapper(self, ctx: cairo.Context):
        func(self, ctx)

        if self.fill:
            ctx.set_source_rgb(*self.fill_color)
            if self.stroke:
                ctx.fill_preserve()
            else:
                ctx.fill()

        if self.stroke:
            ctx.set_line_width(self.stroke_width)
            ctx.set_source_rgb(*self.stroke_color)
            ctx.stroke()
Example #11
0
 def on_draw(self, widget: Widget, context: cairo.Context):
     super().on_draw(widget, context)
     if self.shape is not None:
         self.__wrapper_shape.draw_on_context(context)
         context.stroke()
         context.set_source_rgb(*global_constants.background)
         self.__outer_font_box.draw_on_context(context)
         context.fill_preserve()
         context.set_source_rgb(0, 0, 0)
         context.stroke()
         context.move_to(self.__title_start_point.x,
                         self.__title_start_point.y)
         context.set_font_size(self.font_size)
         context.show_text(self.title)
Example #12
0
    def on_draw(self, widget: Widget, context: cairo.Context):
        shape = self.shape
        if shape is None:
            self.layout(context)
            shape = self.shape
        shape.draw_on_context(context)
        context.set_source_rgb(1, 1, 1)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.stroke()

        text = str(self.value)
        context.set_font_size(self.font_size)
        xb, yb, w, h, xa, ya = context.text_extents(text)
        context.move_to(shape.start.x + shape.width - w - self.padding,
                        shape.start.y + shape.height - self.padding)
        context.show_text(text)
Example #13
0
    def on_draw(self, widget: Widget, context: cairo.Context):
        shape = self.shape
        if shape is None:
            self.layout(context)
            shape = self.shape
        shape.draw_on_context(context)
        context.set_source_rgb(1, 1, 1)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.stroke()

        text = str(self.value)
        context.set_font_size(self.font_size)
        xb, yb, w, h, xa, ya = context.text_extents(text)
        context.move_to(shape.start.x + shape.width - w - self.padding,
                        shape.start.y + shape.height - self.padding)
        context.show_text(text)
Example #14
0
    def on_draw(self, widget: Widget, context: cairo.Context):

        context.set_source_rgba(*self.background_color, self.background_alpha)
        self.__background_rectangle.draw_on_context(context)
        context.fill()

        context.set_font_size(self.font_size)

        self.__overlay_shape.draw_on_context(context)
        context.set_source_rgb(.3, .3, .3)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.stroke()

        context.move_to(self.__label_start.x, self.__label_start.y)
        context.show_text(self.label)
        super().on_draw(widget, context)
Example #15
0
    def on_draw(self, widget: Widget, context: cairo.Context):

        context.set_source_rgba(*self.background_color, self.background_alpha)
        self.__background_rectangle.draw_on_context(context)
        context.fill()

        context.set_font_size(self.font_size)

        self.__label_rectangle.draw_on_context(context)
        context.set_source_rgb(.3, .3, .3)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.stroke()

        rectangle = self.__label_rectangle
        start = rectangle.start
        context.move_to(start.x + self.padding,
                        start.y + rectangle.height - self.padding/2)
        context.show_text(self.label)
 def draw_points_labels(self, layout: Layout, cr: Context):
     for i, piece in enumerate(layout.points):
         if not piece.position:
             continue
         cr.save()
         cr.set_font_size(4)
         cr.translate(
             *piece.position.as_matrix().transform_point(
                 4, -10 if piece.direction == "left" else 10
             )
         )
         cr.rectangle(-4, -4, 8, 8)
         cr.set_source_rgb(1, 1, 1)
         cr.fill_preserve()
         cr.set_source_rgb(0, 0, 0)
         cr.set_line_width(1)
         cr.stroke()
         cr.move_to(-2, 2)
         cr.show_text(str(i))
         cr.restore()
Example #17
0
    def on_draw(self, widget: Widget, context: cairo.Context):

        start_x, start_y = context.get_current_point()
        context.set_font_size(self.font_size)

        context.move_to(0, 0)

        if not self.is_shape_set:
            self.set_shape_from_context(context)
        shape = self.shape
        start = shape.start
        padding = self.padding
        h = shape.height - 2 * padding
        label = self.label

        context.set_source_rgb(*self.background_color)
        shape.draw_on_context(context)
        context.fill_preserve()

        context.set_line_width(1)
        context.set_source_rgb(*self.label_color)
        context.stroke()

        if self.disabled:
            context.set_source_rgba(1, 1, 1, .7)
            context.move_to(start.x + padding-1,
                            start.y + padding + h+1)
            context.show_text(label)
            context.set_source_rgba(*self.label_color, .9)
        else:
            context.set_source_rgb(*self.label_color)
        context.move_to(start.x + padding,
                        start.y + padding + h)
        context.show_text(label)

        if self.disabled:
            context.set_source_rgba(1, 1, 1, .7)
            context.move_to(0, 0)
            shape.draw_on_context(context)
            context.fill()
def draw_speed_limit(ctx: Context, surface_marking: SurfaceMarking, limit: int,
                     start_zone: bool):
    """Draw a speed limit on the road. Add a cross if it is the end of a speed limit zone.

    Args:
        start_zone: Is this speed limit the start or end?
    """
    ctx.translate(surface_marking.center.x, surface_marking.center.y
                  )  # Translate to the center point of the surface marking
    ctx.rotate(surface_marking.orientation)

    ctx.translate(0, surface_marking.width / 2)  # Translate to the middle

    # Position text and scale it
    ctx.rotate(-math.pi / 2)  # rotate by 90deg
    ctx.scale(1, -1)  # mirror y-axis to display text correctly
    ctx.scale(0.7245, 1.8506)  # scale text to match rule book

    # Set font options
    ctx.select_font_face("OpenDinSchriftenEngshrift", cairo.FONT_SLANT_NORMAL)
    ctx.set_font_size(0.4)
    ctx.text_path(str(limit))
    ctx.set_line_width(0.01)

    # Draw text
    _, _, text_width, text_height, _, _ = ctx.text_extents(str(limit))
    ctx.fill_preserve()
    ctx.stroke()

    if not start_zone:
        # Draw cross
        padding = 0.025
        ctx.set_line_width(0.03)
        ctx.move_to(-padding, padding)
        ctx.line_to(text_width + padding, -text_height - padding)
        ctx.stroke()
        ctx.move_to(-padding, -text_height - padding)
        ctx.line_to(text_width + padding, padding)
        ctx.stroke()
Example #19
0
    def on_draw(self, widget: Widget, context: cairo.Context):

        start_x, start_y = context.get_current_point()
        context.set_font_size(self.font_size)

        context.move_to(0, 0)

        if not self.is_shape_set:
            self.set_shape_from_context(context)
        shape = self.shape
        start = shape.start
        padding = self.padding
        h = shape.height - 2 * padding
        label = self.label

        context.set_source_rgb(*self.background_color)
        shape.draw_on_context(context)
        context.fill_preserve()

        context.set_line_width(1)
        context.set_source_rgb(*self.label_color)
        context.stroke()

        if self.disabled:
            context.set_source_rgba(1, 1, 1, .7)
            context.move_to(start.x + padding - 1, start.y + padding + h + 1)
            context.show_text(label)
            context.set_source_rgba(*self.label_color, .9)
        else:
            context.set_source_rgb(*self.label_color)
        context.move_to(start.x + padding, start.y + padding + h)
        context.show_text(label)

        if self.disabled:
            context.set_source_rgba(1, 1, 1, .7)
            context.move_to(0, 0)
            shape.draw_on_context(context)
            context.fill()
Example #20
0
    def on_draw(self, widget: Widget, context: cairo.Context):
        if not self.is_shape_set:
            self.layout(context)

        context.set_font_size(self.font_size)

        self.shape.draw_on_context(context)
        context.set_source_rgb(1, 1, 1)
        context.fill_preserve()
        context.set_source_rgb(0, 0, 0)
        context.stroke()
        shape = self.shape

        label = self.label
        if len(label) > 0 and label[-1] == ' ':
            label += '.'
        xb, yb, w, h, xa, ya = context.text_extents(label)
        context.rectangle(shape.start.x + self.padding, shape.start.y,
                          shape.width - self.padding, shape.height)
        context.clip()
        context.move_to(shape.start.x + (shape.width - self.padding - w) / 2,
                        shape.start.y + shape.height - self.padding)
        context.show_text(self.label)
Example #21
0
 def hypotrochoid(self,
                  cr: cairo.Context,
                  r,
                  R,
                  d,
                  theta=4 * np.pi,
                  n=1000,
                  c=(0, 4),
                  alpha=1.0):
     # t = self.theta
     th = np.linspace(0, theta, n)
     for t in th:
         ph = ((R - r) * np.cos(t) + d * np.cos(
             (R - r) * t / r), (R - r) * np.sin(t) - d * np.sin(
                 (R - r) * t / r))
         if t == 0:
             cr.move_to(*ph)
             continue
         cr.line_to(*ph)
     cr.set_source_rgba(*colors[c[0]], alpha)
     cr.fill_preserve()
     cr.set_source_rgba(*colors[c[1]], alpha)
     cr.stroke()
Example #22
0
def draw_moon(
    ctx: cairo.Context,
    pos_x: float,
    pos_y: float,
    radius: float,
    eclipse_pct: float = -1.0,
):
    moon_color = Color(0.9, 0.9, 0.9)

    ctx.arc(pos_x, pos_y, radius, 0, tau)
    ctx.stroke_preserve()

    with source(
        ctx,
        moon_color.to_pattern(),
    ):
        ctx.fill_preserve()
        ctx.clip()

    with source(ctx, Color(0.0, 0.0, 0.0).to_pattern()):
        eclipse_cx = pos_x + eclipse_pct * 2.0 * radius
        ctx.arc(eclipse_cx, pos_y, radius, 0, tau)
        ctx.fill()
        ctx.reset_clip()
Example #23
0
class Canvas:
    def __init__(self,
                 width: int,
                 height: Optional[int] = None,
                 *,
                 normalise: bool = True):
        if height is None:
            height = width
        self._width = width
        self._height = height
        self._surface = ImageSurface(FORMAT_ARGB32, width, height)
        self._context = Context(self._surface)
        self._normalise = normalise
        if self._normalise:
            self.scale(self._width, self._height)

    @property
    def width(self) -> int:
        return self._width if not self._normalise else 1

    @property
    def height(self) -> int:
        return self._height if not self._normalise else 1

    # TODO depreciate
    @property
    def context(self) -> Context:  # pragma: no cover
        return self._context

    def save(self) -> None:
        self._context.save()

    def restore(self) -> None:
        self._context.restore()

    # Transformation
    def rotate(self, angle: float) -> None:
        self._context.rotate(angle)

    def translate(self, x: float, y: float) -> None:
        self._context.translate(x, y)

    def scale(self, width: int, height: int) -> None:
        self._context.scale(width, height)

    def set_line_width(self, width: float) -> None:
        self._context.set_line_width(width)

    # Colour functionality
    def set_colour(self, colour: Colour) -> None:
        self._context.set_source_rgba(colour.red, colour.blue, colour.green,
                                      colour.alpha)

    def set_grey(self, colour_value: float, alpha: float = 1) -> None:
        colour = Colour(*(colour_value, ) * 3, alpha)
        self.set_colour(colour)

    def set_black(self) -> None:
        self.set_colour(BLACK)

    def set_white(self) -> None:
        self.set_colour(WHITE)

    def set_background(self, colour: Colour) -> None:
        self._context.rectangle(0, 0, self.width, self.height)
        self.set_colour(colour)
        self._context.fill()

    def set_line_cap(self, line_cap: LineCap) -> None:
        self._context.set_line_cap(line_cap.value)

    def set_line_join(self, line_join: LineJoin) -> None:
        self._context.set_line_join(line_join.value)

    def set_fill_rule(self, file_rule: FillRule) -> None:
        self._context.set_fill_rule(file_rule.value)

    # Render methods
    def fill(self, preserve: bool = False) -> None:
        if not preserve:
            self._context.fill()
        else:
            self._context.fill_preserve()

    def stroke(self, preserve: bool = False) -> None:
        if not preserve:
            self._context.stroke()
        else:
            self._context.stroke_preserve()

    def clip(self) -> None:
        self._context.clip()

    def _draw_path(self, path: Iterable[Point], close_path: bool) -> None:
        self._context.new_sub_path()
        for p in path:
            self._context.line_to(*p)
        if close_path:
            self._context.close_path()

    def draw_path(self,
                  path: Iterable[PointType],
                  close_path: bool = False) -> None:
        points = (p if isinstance(p, Point) else Point(*p) for p in path)
        self._draw_path(points, close_path)

    def draw_polygon(self, polygon: Polygon) -> None:
        self._draw_path(polygon.points, close_path=True)

    def draw_circle(self,
                    circle: Circle,
                    fill: bool = False,
                    stroke: bool = True) -> None:
        self._context.new_sub_path()
        self._context.arc(*circle.centre, circle.radius, 0, 2 * pi)

    def write_to_png(self, file_name: str) -> None:
        self._surface.write_to_png(file_name)
Example #24
0
    def draw(self, ctx: cairo.Context, display_id: int):
        if self._boost:
            self._draw_boost(ctx, display_id)
            return
        # TODO: Support other display drawing.
        if display_id == 1 and self.enabled and self.debugger:
            if self._refresh_cache and not self._cache_redrawing_registered:
                self._cache_redrawing_registered = True
                threadsafe_emu_nonblocking_coro(self.debugger.emu_thread,
                                                self._update_cache())

            if self._cache_running:
                # Draw
                for bbox in self._actor_bbox_cache:
                    ctx.set_source_rgba(*COLOR_ACTOR)
                    ctx.rectangle(bbox[0], bbox[1], bbox[2] - bbox[0],
                                  bbox[3] - bbox[1])
                    ctx.fill()
                for bbox in self._object_bbox_cache:
                    ctx.set_source_rgba(*COLOR_OBJECTS)
                    ctx.rectangle(bbox[0], bbox[1], bbox[2] - bbox[0],
                                  bbox[3] - bbox[1])
                    ctx.fill()
                for bbox in self._perf_bbox_cache:
                    ctx.set_source_rgba(*COLOR_PERFORMER)
                    ctx.rectangle(bbox[0], bbox[1], bbox[2] - bbox[0],
                                  bbox[3] - bbox[1])
                    ctx.fill()
                for bbox in self._event_bbox_cache:
                    ctx.set_source_rgba(*COLOR_EVENTS)
                    ctx.rectangle(bbox[0], bbox[1], bbox[2] - bbox[0],
                                  bbox[3] - bbox[1])
                    ctx.fill()

                if self.debugger.ground_engine_state:
                    ground_state = self.debugger.ground_engine_state
                    for ssb in ground_state.loaded_ssb_files:
                        if ssb is not None:
                            for mark in ground_state.ssb_file_manager.get(
                                    ssb.file_name
                            ).position_markers:  # type: ignore
                                x_absolute = (mark.x_with_offset * TILE_SIZE
                                              ) - self._camera_pos_cache[0]
                                y_absolute = (mark.y_with_offset * TILE_SIZE
                                              ) - self._camera_pos_cache[1]
                                ctx.set_source_rgba(*COLOR_POS_MARKERS)
                                ctx.rectangle(
                                    # They are centered.
                                    x_absolute - 4,
                                    y_absolute - 4,
                                    TILE_SIZE,
                                    TILE_SIZE)
                                ctx.fill_preserve()
                                ctx.set_source_rgb(0, 0, 0)
                                ctx.set_line_width(1)
                                ctx.stroke()
                                ctx.set_source_rgba(*COLOR_POS_MARKERS)
                                ctx.move_to(x_absolute, y_absolute + 18)
                                ctx.select_font_face("cairo:monospace",
                                                     cairo.FONT_SLANT_NORMAL,
                                                     cairo.FONT_WEIGHT_NORMAL)
                                ctx.set_font_size(8)
                                ctx.text_path(mark.name)
                                ctx.fill_preserve()
                                ctx.set_source_rgb(0, 0, 0)
                                ctx.set_line_width(0.3)
                                ctx.stroke()
Example #25
0
    def do_draw(self, context: cairo.Context) -> bool:
        if not self.adjustment or self.adjustment.get_upper() <= 0:
            return False

        height = self.get_allocated_height()
        width = self.get_allocated_width()

        if width <= 0 or height <= 0:
            return False

        base_bg, base_outline, handle_overdraw, handle_outline = (
            self.get_map_base_colors())

        x0 = self.overdraw_padding + 0.5
        x1 = width - 2 * x0
        height_scale = height * self.get_height_scale()

        if self._cached_map is None:
            surface = cairo.Surface.create_similar(
                context.get_target(), cairo.CONTENT_COLOR_ALPHA, width, height)
            cache_ctx = cairo.Context(surface)
            cache_ctx.set_line_width(1)

            cache_ctx.rectangle(x0, -0.5, x1, height_scale + 0.5)
            cache_ctx.set_source_rgba(*base_bg)
            cache_ctx.fill()

            # We get drawing coordinates by tag to minimise our source
            # colour setting, and make this loop slightly cleaner.
            tagged_diffs = self.chunk_coords_by_tag()

            for tag, diffs in tagged_diffs.items():
                cache_ctx.set_source_rgba(*self.fill_colors[tag])
                for y0, y1 in diffs:
                    y0 = round(y0 * height_scale) + 0.5
                    y1 = round(y1 * height_scale) - 0.5
                    cache_ctx.rectangle(x0, y0, x1, y1 - y0)
                cache_ctx.fill_preserve()
                cache_ctx.set_source_rgba(*self.line_colors[tag])
                cache_ctx.stroke()

            cache_ctx.rectangle(x0, -0.5, x1, height_scale + 0.5)
            cache_ctx.set_source_rgba(*base_outline)
            cache_ctx.stroke()

            self._cached_map = surface

        context.set_source_surface(self._cached_map, 0, 0)
        context.paint()

        # Draw our scroll position indicator
        context.set_line_width(1)
        context.set_source_rgba(*handle_overdraw)
        adj_y = self.adjustment.get_value() / self.adjustment.get_upper()
        adj_h = self.adjustment.get_page_size() / self.adjustment.get_upper()
        context.rectangle(
            x0 - self.overdraw_padding, round(height_scale * adj_y) + 0.5,
            x1 + 2 * self.overdraw_padding, round(height_scale * adj_h) - 1,
        )
        context.fill_preserve()
        context.set_source_rgba(*handle_outline)
        context.stroke()

        return True
    start, end = 0, 0

    VERTS, CODES = [], []
    # Iterate over each contour
    ctx.set_source_rgb(0.5,0.5,0.5)
    for i in range(len(outline.contours)):
        end    = outline.contours[i]

        ctx.move_to(outline.points[start][0],outline.points[start][1])
        for j in range(start, end+1):
            point = outline.points[j]
            ctx.line_to(point[0],point[1])
        #back to origin
        ctx.line_to(outline.points[start][0], outline.points[start][1])
        start = end+1
    ctx.fill_preserve()
    ctx.set_source_rgb(0,1,0)
    ctx.stroke()

    start, end = 0, 0
    for i in range(len(outline.contours)):
        end    = outline.contours[i]

        ctx.new_path()
        ctx.set_source_rgb(0,0,1)
        for j in range(start, end+1):
            if ( Curve_Tag[j] == FT_Curve_Tag_On ):
                point = outline.points[j]
                ctx.move_to(point[0],point[1])
                ctx.arc(point[0], point[1], 40, 0, 2 * math.pi)
        ctx.fill()
Example #27
0
    def draw(self, wdg, ctx: cairo.Context):
        ctx.set_antialias(cairo.Antialias.NONE)
        ctx.scale(self.scale, self.scale)
        # Background
        if self.map_bg is not None:
            ctx.set_source_surface(self.map_bg, 0, 0)
            ctx.get_source().set_filter(cairo.Filter.NEAREST)
            ctx.paint()

        size_w, size_h = self.draw_area.get_size_request()
        size_w /= self.scale
        size_h /= self.scale

        # Black out bg a bit
        if not self._edit_pos_marks:
            ctx.set_source_rgba(0, 0, 0, 0.5)
            ctx.rectangle(0, 0, size_w, size_h)
            ctx.fill()

        # Tile Grid
        if self.draw_tile_grid:
            self.tile_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x,
                                       self.mouse_y)

        # RENDER ENTITIES
        for layer_i, layer in enumerate(self.ssa.layer_list):
            if not self._is_layer_visible(layer_i):
                continue

            for actor in layer.actors:
                if not self._is_dragged(actor):
                    bb = self.get_bb_actor(actor)
                    if actor != self._selected:
                        self._handle_layer_highlight(ctx, layer_i, *bb)
                    self._draw_actor(ctx, actor, *bb)
                    self._draw_hitbox_actor(ctx, actor)
            for obj in layer.objects:
                if not self._is_dragged(obj):
                    bb = self.get_bb_object(obj)
                    if obj != self._selected:
                        self._handle_layer_highlight(ctx, layer_i, *bb)
                    self._draw_object(ctx, obj, *bb)
                    self._draw_hitbox_object(ctx, obj)
            for trigger in layer.events:
                if not self._is_dragged(trigger):
                    bb = self.get_bb_trigger(trigger)
                    if trigger != self._selected:
                        self._handle_layer_highlight(ctx, layer_i, *bb)
                    self._draw_trigger(ctx, trigger, *bb)
            for performer in layer.performers:
                if not self._is_dragged(performer):
                    bb = self.get_bb_performer(performer)
                    if performer != self._selected:
                        self._handle_layer_highlight(ctx, layer_i, *bb)
                    self._draw_hitbox_performer(ctx, performer)
                    self._draw_performer(ctx, performer, *bb)

        # Black out bg a bit
        if self._edit_pos_marks:
            ctx.set_source_rgba(0, 0, 0, 0.5)
            ctx.rectangle(0, 0, size_w, size_h)
            ctx.fill()

        # RENDER POSITION MARKS
        for pos_mark in self.position_marks:
            bb = self.get_bb_pos_mark(pos_mark)
            self._draw_pos_mark(ctx, pos_mark, *bb)

        # Cursor / Active selected / Place mode
        self._handle_selection(ctx)
        x, y, w, h = self._handle_drag_and_place_modes()
        self.selection_plugin.set_size(w, h)
        self.selection_plugin.draw(ctx, size_w, size_h, x, y, ignore_obb=True)

        # Position
        ctx.scale(1 / self.scale, 1 / self.scale)
        ctx.select_font_face("monospace", cairo.FONT_SLANT_NORMAL,
                             cairo.FONT_WEIGHT_NORMAL)
        ctx.set_source_rgb(*COLOR_WHITE)
        ctx.set_font_size(18)
        try:
            sw: Gtk.ScrolledWindow = self.draw_area.get_parent().get_parent(
            ).get_parent()
            s = sw.get_allocated_size()
            ctx.move_to(sw.get_hadjustment().get_value() + 30,
                        s[0].height + sw.get_vadjustment().get_value() - 30)
            if self._selected__drag is not None:
                sx, sy = self.get_current_drag_entity_pos()
            else:
                sx, sy = self._snap_pos(self.mouse_x, self.mouse_y)
            sx /= BPC_TILE_DIM
            sy /= BPC_TILE_DIM
            ctx.text_path(f"X: {sx}, Y: {sy}")
            ctx.set_source_rgb(*COLOR_BLACK)
            ctx.set_line_width(0.3)
            ctx.set_source_rgb(*COLOR_WHITE)
            ctx.fill_preserve()
            ctx.stroke()
        except BaseException:
            pass

        return True
Example #28
0
    def draw_ticks(self, ctx: cairo.Context):

        #        green = (0, 0.4, 0.2)
        #        red = (0.55, 0.15, 0)
        green = (92 / 256, 214 / 256, 92 / 256)
        red = (1, 102 / 256, 102 / 256)

        bars = self.data

        ylim = (bars.low.min(), bars.high.max())

        axis_x_0 = self.transform_plot @ np.array([-0.03, -0.06, 1])
        axis_x_1 = self.transform_plot @ np.array([1.03, -0.06, 1])
        axis_y_0 = self.transform_plot @ np.array([1.03, 1, 1])

        ctx.set_line_width(self.grid_line_width)
        ctx.set_source_rgb(0, 0, 0)
        ctx.move_to(*axis_x_0[:2])
        ctx.line_to(*axis_x_1[:2])
        ctx.line_to(*axis_y_0[:2])
        ctx.stroke()

        # Draw x ticks.
        ctx.set_font_size(self.tick_font_size)
        x_ticks = [
            -0.5,
        ] + list(range(7))
        x_tick_labels = [
            '9:30',
        ] + list(f'{10+i}:00' for i in x_ticks[1:])
        for idx, tick in enumerate(x_ticks):

            grid_0 = self.transform_plot @ np.array(
                [tick / 6.5 + 0.5 / 6.5, -0.06, 1])
            grid_1 = self.transform_plot @ np.array(
                [tick / 6.5 + 0.5 / 6.5, -0.08, 1])

            ctx.set_line_width(self.grid_line_width)
            ctx.move_to(*grid_0[:2])
            ctx.line_to(*grid_1[:2])
            ctx.set_source_rgb(0, 0, 0)
            ctx.stroke()

            ctx.set_source_rgb(0, 0, 0)
            tick_label = x_tick_labels[idx]
            (x, y, w, h, dx, dy) = ctx.text_extents(tick_label)
            ctx.move_to(grid_0[0] - w / 2,
                        grid_0[1] + h / 2 + 0.9 * self.y_axis_space)
            ctx.show_text(tick_label)

        # Draw y ticks.
        y_tick_min = np.ceil(ylim[0]) + 0
        y_tick_max = np.ceil(ylim[1])

        num_y_ticks = 6
        tick_int = int((y_tick_max - y_tick_min) / num_y_ticks)

        y_ticks = list(y_tick_min + i * tick_int for i in range(num_y_ticks))
        y_tick_labels = list('{:.0f}.00'.format(i) for i in y_ticks)

        for idx in range(num_y_ticks):

            tick = y_ticks[idx]
            label = y_tick_labels[idx]
            grid_0 = self.transform_plot @ np.array(
                [1.03, (tick - ylim[0]) / (ylim[1] - ylim[0]), 1])
            grid_1 = self.transform_plot @ np.array(
                [1.04, (tick - ylim[0]) / (ylim[1] - ylim[0]), 1])

            ctx.move_to(*grid_0[:2])
            ctx.line_to(*grid_1[:2])
            ctx.stroke()

            (x, y, w, h, dx, dy) = ctx.text_extents(tick_label)
            ctx.move_to(grid_0[0] + w / 2 - 4, grid_0[1] + h / 2)
            ctx.show_text(label)

        ctx.set_font_size(self.axis_label_size)
        p = self.transform_plot @ np.array([1.22, -0.98, 0])
        _text(ctx, 'Price', p[:2], -np.pi / 2)

        for idx in range(len(bars)):

            x0 = bars.t_open.iloc[idx] / ((16 - 9.5) * 60 * 60)
            x1 = bars.t_close.iloc[idx] / ((16 - 9.5) * 60 * 60)

            h = bars.high.iloc[idx]
            l = bars.low.iloc[idx]
            o = bars.open.iloc[idx]
            c = bars.close.iloc[idx]

            y0 = (l - ylim[0]) / (ylim[1] - ylim[0])
            y1 = (h - ylim[0]) / (ylim[1] - ylim[0])

            y2 = (o - ylim[0]) / (ylim[1] - ylim[0])
            y3 = (c - ylim[0]) / (ylim[1] - ylim[0])

            if y2 < y3:
                c = green
            else:
                c = red

            ctx.set_source_rgb(*c)
            y2, y3 = min(y2, y3), max(y2, y3)

            x_mid = 0.5 * (x0 + x1)

            line_0 = np.array([x_mid, y0, 1.0])
            line_1 = np.array([x_mid, y1, 1.0])

            line_0 = self.transform_plot @ line_0
            line_1 = self.transform_plot @ line_1

            ctx.set_source_rgb(0, 0, 0)
            ctx.set_line_width(self.stick_line_width)
            ctx.move_to(*line_0[:2])
            ctx.line_to(*line_1[:2])
            ctx.stroke()

            w, h = x1 - x0, y3 - y2

            ctx.set_source_rgb(*c)

            candle_0 = self.transform_plot @ np.array(
                [x_mid - 0.5 * self.candle_width_scale * w, y2, 1])
            candle_1 = self.transform_plot @ np.array(
                [x_mid + 0.5 * self.candle_width_scale * w, y3, 1])
            candle_sc = candle_1 - candle_0

            ctx.rectangle(*candle_0[:2], *candle_sc[:2])
            ctx.fill_preserve()

            ctx.set_source_rgb(0, 0, 0)
            ctx.set_line_width(0.5)
            ctx.stroke()
Example #29
0
 def draw_action(self, ctx: cairo.Context, action: FixedFloorActionRule,
                 sx: int, sy: int):
     if isinstance(action, EntityRule):
         assert self.parent.entity_rule_container is not None
         item, monster, tile, stats = self.parent.entity_rule_container.get(
             action.entity_rule_id)
         # Has trap?
         if tile.trap_id < 25:
             self._draw_trap(ctx, tile.trap_id, sx, sy)
         # Has item?
         if item.item_id > 0:
             try:
                 self._draw_item(ctx, item.item_id, sx, sy)
             except IndexError:
                 ctx.arc(sx + DPCI_TILE_DIM * DPC_TILING_DIM / 2,
                         sy + DPCI_TILE_DIM * DPC_TILING_DIM / 2,
                         DPCI_TILE_DIM * DPC_TILING_DIM / 2, 0, 2 * math.pi)
                 ctx.set_source_rgba(*COLOR_ITEM)
                 ctx.fill_preserve()
                 ctx.set_source_rgba(*COLOR_OUTLINE)
                 ctx.set_line_width(1)
                 ctx.stroke()
         # Has Pokémon?
         if monster.md_idx > 0:
             self._draw_pokemon(ctx, monster.md_idx, action.direction, sx,
                                sy)
     elif isinstance(action, TileRule):
         # Leader spawn tile
         if action.tr_type == TileRuleType.LEADER_SPAWN:
             self.parent.draw_placeholder(0, sx, sy, action.direction, ctx)
         # Attendant1 spawn tile
         if action.tr_type == TileRuleType.ATTENDANT1_SPAWN:
             self.parent.draw_placeholder(10, sx, sy, action.direction, ctx)
         # Attendant2 spawn tile
         if action.tr_type == TileRuleType.ATTENDANT2_SPAWN:
             self.parent.draw_placeholder(11, sx, sy, action.direction, ctx)
         # Attendant3 spawn tile
         if action.tr_type == TileRuleType.ATTENDANT3_SPAWN:
             self.parent.draw_placeholder(15, sx, sy, action.direction, ctx)
         # Key walls
         if action.tr_type == TileRuleType.FL_WA_ROOM_FLAG_0C or action.tr_type == TileRuleType.FL_WA_ROOM_FLAG_0D:
             sprite, x, y, w, h = self.parent.sprite_provider.get_for_trap(
                 31, lambda: GLib.idle_add(self.parent.redraw))
             ctx.translate(sx, sy)
             ctx.set_source_surface(sprite)
             ctx.get_source().set_filter(cairo.Filter.NEAREST)
             ctx.paint()
             ctx.translate(-sx, -sy)
         # Warp zone
         if action.tr_type == TileRuleType.WARP_ZONE or action.tr_type == TileRuleType.WARP_ZONE_2:
             self._draw_stairs(ctx, sx, sy)
     elif isinstance(action, DirectRule):
         if action.tile.room_type == RoomType.KECLEON_SHOP:
             sprite, x, y, w, h = self.parent.sprite_provider.get_for_trap(
                 30, lambda: GLib.idle_add(self.parent.redraw))
             ctx.translate(sx, sy)
             ctx.set_source_surface(sprite)
             ctx.get_source().set_filter(cairo.Filter.NEAREST)
             ctx.paint()
             ctx.translate(-sx, -sy)
         if action.tile.typ == TileType.PLAYER_SPAWN or action.tile.typ == TileType.ENEMY:
             self._draw_pokemon(ctx, action.itmtpmon_id, action.direction,
                                sx, sy)
         if action.tile.typ == TileType.STAIRS:
             self._draw_stairs(ctx, sx, sy)
         if action.tile.typ == TileType.TRAP:
             self._draw_trap(ctx, action.itmtpmon_id, sx, sy)
         if action.tile.typ == TileType.BURIED_ITEM:
             self._draw_item(ctx, action.itmtpmon_id, sx, sy, buried=True)
         if action.tile.typ == TileType.ITEM:
             self._draw_item(ctx, action.itmtpmon_id, sx, sy)
         if action.tile.room_type == RoomType.MONSTER_HOUSE:
             ctx.set_source_rgba(230, 0, 0, 0.2)
             ctx.rectangle(sx, sy, DPCI_TILE_DIM * DPC_TILING_DIM,
                           DPCI_TILE_DIM * DPC_TILING_DIM)
             ctx.fill()
Example #30
0
def draw(widget: Gtk.Widget, cr: cairo.Context):
    if not world.map:
        return

    player_x = world.player.x
    player_y = world.player.y

    allocation = widget.get_allocation()
    tile_width = allocation.width / world.map_width
    tile_height = allocation.height / world.map_height

    # clear drawing
    cr.set_source_rgb(1, 1, 1)
    cr.paint()

    # draw shadow
    shadow_surface = cairo.ImageSurface(cairo.Format.ARGB32, allocation.width,
                                        allocation.height)
    scr = cairo.Context(shadow_surface)
    scr.set_line_width(1)
    scr.set_source_rgb(0, 0, 0)
    for y, row in enumerate(world.map):
        for x, tile in enumerate(row):
            if tile == "#":
                left = x * tile_width
                top = y * tile_height
                right = left + tile_width
                bottom = top + tile_height
                shadow_points = []
                for dest_x, dest_y in itertools.product([left, right],
                                                        [top, bottom]):
                    other_x = {left: right, right: left}[dest_x]
                    other_y = {top: bottom, bottom: top}[dest_y]
                    if line_goes_through_border(player_x, player_y, dest_x, dest_y, other_x, top, bottom) \
                            or line_goes_through_border(player_y, player_x, dest_y, dest_x, other_y, left, right):
                        continue
                    shadow_points.append((dest_x, dest_y))
                if len(shadow_points) == 3:
                    for i in range(len(shadow_points)):
                        if shadow_points[i] == (shadow_points[(i - 1) % 3][0], shadow_points[(i + 1) % 3][1]) \
                                or shadow_points[i] == (shadow_points[(i + 1) % 3][0], shadow_points[(i - 1) % 3][1]):
                            del shadow_points[i]
                            break
                elif len(shadow_points) == 4:
                    continue
                for i, shadow_point in enumerate(
                        extend_shadow_points(shadow_points, allocation)):
                    if i == 0:
                        scr.move_to(*shadow_point)
                    else:
                        scr.line_to(*shadow_point)
                scr.fill()
    cr.set_source_surface(shadow_surface)
    cr.mask(cairo.SolidPattern(0, 0, 0, .6))
    cr.fill()

    # draw tiles
    cr.set_line_width(1)
    for y, row in enumerate(world.map):
        for x, tile in enumerate(row):
            if tile == "#":
                cr.set_source_rgb(.9, 0, 0)
                cr.rectangle(x * tile_width, y * tile_height, tile_width,
                             tile_height)
                cr.fill_preserve()
                cr.set_source_rgba(0, 0, 0)
                cr.stroke()

    for player in world.players.values():
        collides = False
        for y, row in enumerate(world.map):
            for x, tile in enumerate(row):
                if tile == "#":
                    left = x * tile_width
                    top = y * tile_height
                    right = left + tile_width
                    bottom = top + tile_height
                    if collision_rect_line(Rectangle(left, right, top,
                                                     bottom), player_x,
                                           player_y, player.x, player.y):
                        collides = True
                        break
            if collides:
                break
        if not collides:
            draw_player(cr, player)

    draw_player(
        cr,
        Player(player_x, player_y, world.player.rotation, world.player.health))

    for bullet in world.bullets:
        draw_bullet(cr, bullet)
Example #31
0
    def do_draw(self, context: cairo.Context) -> bool:
        if not self.adjustment or self.adjustment.get_upper() <= 0:
            return False

        height = self.get_allocated_height()
        width = self.get_allocated_width()

        if width <= 0 or height <= 0:
            return False

        base_bg, base_outline, handle_overdraw, handle_outline = (
            self.get_map_base_colors())

        x0 = self.overdraw_padding + 0.5
        x1 = width - 2 * x0
        height_scale = height * self.get_height_scale()

        if self._cached_map is None:
            surface = cairo.Surface.create_similar(context.get_target(),
                                                   cairo.CONTENT_COLOR_ALPHA,
                                                   width, height)
            cache_ctx = cairo.Context(surface)
            cache_ctx.set_line_width(1)

            cache_ctx.rectangle(x0, -0.5, x1, height_scale + 0.5)
            cache_ctx.set_source_rgba(*base_bg)
            cache_ctx.fill()

            # We get drawing coordinates by tag to minimise our source
            # colour setting, and make this loop slightly cleaner.
            tagged_diffs = self.chunk_coords_by_tag()

            for tag, diffs in tagged_diffs.items():
                cache_ctx.set_source_rgba(*self.fill_colors[tag])
                for y0, y1 in diffs:
                    y0 = round(y0 * height_scale) + 0.5
                    y1 = round(y1 * height_scale) - 0.5
                    cache_ctx.rectangle(x0, y0, x1, y1 - y0)
                cache_ctx.fill_preserve()
                cache_ctx.set_source_rgba(*self.line_colors[tag])
                cache_ctx.stroke()

            cache_ctx.rectangle(x0, -0.5, x1, height_scale + 0.5)
            cache_ctx.set_source_rgba(*base_outline)
            cache_ctx.stroke()

            self._cached_map = surface

        context.set_source_surface(self._cached_map, 0, 0)
        context.paint()

        # Draw our scroll position indicator
        context.set_line_width(1)
        context.set_source_rgba(*handle_overdraw)

        adj_y = self.adjustment.get_value() / self.adjustment.get_upper()
        adj_h = self.adjustment.get_page_size() / self.adjustment.get_upper()

        context.rectangle(
            x0 - self.overdraw_padding,
            round(height_scale * adj_y) + 0.5,
            x1 + 2 * self.overdraw_padding,
            round(height_scale * adj_h) - 1,
        )
        context.fill_preserve()
        context.set_source_rgba(*handle_outline)
        context.stroke()

        return True
Example #32
0
    def draw_volumes(self, ctx: cairo.Context):

        green = (92 / 256, 214 / 256, 92 / 256)
        red = (1, 102 / 256, 102 / 256)

        bars = self.data

        ylim = (bars.volume.min(), bars.volume.max())

        axis_x_0 = self.transform_plot @ np.array([-0.03, -0.06, 1])
        axis_x_1 = self.transform_plot @ np.array([1.03, -0.06, 1])
        axis_y_0 = self.transform_plot @ np.array([1.03, 1, 1])

        ctx.set_line_width(self.grid_line_width)
        ctx.set_source_rgb(0, 0, 0)
        ctx.move_to(*axis_x_0[:2])
        ctx.line_to(*axis_x_1[:2])
        ctx.line_to(*axis_y_0[:2])
        ctx.stroke()

        ctx.set_font_size(self.tick_label_size)
        x_ticks = [
            -0.5,
        ] + list(range(7))
        x_tick_labels = [
            '9:30',
        ] + list(f'{10+i}:00' for i in x_ticks[1:])
        for idx, tick in enumerate(x_ticks):

            grid_0 = self.transform_plot @ np.array(
                [tick / 6.5 + 0.5 / 6.5, -0.06, 1])
            grid_1 = self.transform_plot @ np.array(
                [tick / 6.5 + 0.5 / 6.5, -0.08, 1])

            ctx.set_line_width(self.grid_line_width)
            ctx.move_to(*grid_0[:2])
            ctx.line_to(*grid_1[:2])
            ctx.set_source_rgb(0, 0, 0)
            ctx.stroke()

            ctx.set_source_rgb(0, 0, 0)
            tick_label = x_tick_labels[idx]
            (x, y, w, h, dx, dy) = ctx.text_extents(tick_label)
            ctx.move_to(grid_0[0] - w / 2,
                        grid_0[1] + h / 2 + 0.9 * self.y_axis_space)
            ctx.show_text(tick_label)

        y_tick_min = np.ceil(ylim[0]) + 0
        y_tick_max = np.ceil(ylim[1])

        num_y_ticks = 6
        tick_int = int((y_tick_max - y_tick_min) / num_y_ticks)

        y_ticks = list(y_tick_min + i * tick_int for i in range(num_y_ticks))
        y_tick_labels = list('{:.0f}'.format(i) for i in y_ticks)

        for idx in range(num_y_ticks):

            tick = y_ticks[idx]
            label = y_tick_labels[idx]
            grid_0 = self.transform_plot @ np.array(
                [1.03, (tick - ylim[0]) / (ylim[1] - ylim[0]), 1])
            grid_1 = self.transform_plot @ np.array(
                [1.04, (tick - ylim[0]) / (ylim[1] - ylim[0]), 1])

            ctx.move_to(*grid_0[:2])
            ctx.line_to(*grid_1[:2])
            ctx.stroke()

            (x, y, w, h, dx, dy) = ctx.text_extents(tick_label)
            ctx.move_to(grid_0[0] + w / 2 - 4, grid_0[1] + h / 2)
            ctx.show_text(label)

        ctx.set_font_size(self.axis_label_size)
        p = self.transform_plot @ np.array([1.22, -0.5, 0])
        p += np.array([0, self.rect_inner.position.y, 1])
        _text(ctx, 'Volume', p[:2], -np.pi / 2)

        for idx in range(len(bars)):

            x0 = bars.t_open.iloc[idx] / ((16 - 9.5) * 60 * 60)
            x1 = bars.t_close.iloc[idx] / ((16 - 9.5) * 60 * 60)

            h = bars.high.iloc[idx]
            l = bars.low.iloc[idx]
            o = bars.open.iloc[idx]
            c = bars.close.iloc[idx]
            v = bars.volume.iloc[idx]

            y0 = 0
            y1 = (v - ylim[0]) / (ylim[1] - ylim[0])

            if o < c:
                c = green
            else:
                c = red

            ctx.set_source_rgb(*c)

            x_mid = 0.5 * (x0 + x1)

            w, h = x1 - x0, y1 - y0

            ctx.set_source_rgb(*c)

            vol_bar_0 = self.transform_plot @ np.array(
                [x_mid - 0.5 * self.candle_width_scale * w, y0, 1])
            vol_bar_1 = self.transform_plot @ np.array(
                [x_mid + 0.5 * self.candle_width_scale * w, y1, 1])
            vol_bar_sc = vol_bar_1 - vol_bar_0

            ctx.rectangle(*vol_bar_0[:2], *vol_bar_sc[:2])
            ctx.fill_preserve()

            ctx.set_source_rgb(0, 0, 0)
            ctx.set_line_width(0.5)
            ctx.stroke()