Ejemplo n.º 1
0
    def __init__(self, icon_file_func, *args, **kwargs):
        super(_PreviewWidget, self).__init__(*args, **kwargs)

        self.board_drawer = \
            BoardDrawer(get_size_func=self._get_drawer_size,
                        invalidate_rect_func=self._invalidate_drawer_rect)
        self.removal_drawer = \
            RemovalDrawer(get_size_func=self._get_drawer_size,
                          invalidate_rect_func=self._invalidate_drawer_rect)
        self.win_drawer = \
            WinDrawer(get_size_func=self._get_drawer_size,
                      invalidate_rect_func=self._invalidate_drawer_rect)

        self._icon_file_func = icon_file_func

        self._preview_rect = Gdk.Rectangle()
        self._preview_rect.x = self._preview_rect.y = \
            self._preview_rect.width = self._preview_rect.height = 0

        self._toolbar_rect = Gdk.Rectangle()
        self._toolbar_rect.x = self._toolbar_rect.y = \
            self._toolbar_rect.width = self._toolbar_rect.height = 0

        self._drawer_rect = Gdk.Rectangle()
        self._drawer_rect.x = self._drawer_rect.y = \
            self._drawer_rect.width = self._drawer_rect.height = 0

        self._drawer = self.board_drawer

        # Mouse position as a floating point value over the 4x3 unit preview
        # area.
        self._cursor_pos = (0.0, 0.0)

        # Cursor size in pixels.
        self._cursor_size = (0, 0)

        self._click_visible = False
        self._cursor_visible = False

        self.connect('draw', self._draw_event_cb)
        self.connect('configure-event', self._configure_event_cb)
Ejemplo n.º 2
0
    def __init__(self, icon_file_func, *args, **kwargs):
        super(_PreviewWidget, self).__init__(*args, **kwargs)

        self.board_drawer = \
            BoardDrawer(get_size_func=self._get_drawer_size,
                        invalidate_rect_func=self._invalidate_drawer_rect)
        self.removal_drawer = \
            RemovalDrawer(get_size_func=self._get_drawer_size,
                          invalidate_rect_func=self._invalidate_drawer_rect)
        self.win_drawer = \
            WinDrawer(get_size_func=self._get_drawer_size,
                      invalidate_rect_func=self._invalidate_drawer_rect)

        self._icon_file_func = icon_file_func

        self._preview_rect = Gdk.Rectangle()
        self._preview_rect.x = self._preview_rect.y = \
            self._preview_rect.width = self._preview_rect.height = 0

        self._toolbar_rect = Gdk.Rectangle()
        self._toolbar_rect.x = self._toolbar_rect.y = \
            self._toolbar_rect.width = self._toolbar_rect.height = 0

        self._drawer_rect = Gdk.Rectangle()
        self._drawer_rect.x = self._drawer_rect.y = \
            self._drawer_rect.width = self._drawer_rect.height = 0

        self._drawer = self.board_drawer

        # Mouse position as a floating point value over the 4x3 unit preview
        # area.
        self._cursor_pos = (0.0, 0.0)

        # Cursor size in pixels.
        self._cursor_size = (0, 0)

        self._click_visible = False
        self._cursor_visible = False

        self.connect('draw', self._draw_event_cb)
        self.connect('configure-event', self._configure_event_cb)
Ejemplo n.º 3
0
class _PreviewWidget(Gtk.DrawingArea):
    def __init__(self, icon_file_func, *args, **kwargs):
        super(_PreviewWidget, self).__init__(*args, **kwargs)

        self.board_drawer = \
            BoardDrawer(get_size_func=self._get_drawer_size,
                        invalidate_rect_func=self._invalidate_drawer_rect)
        self.removal_drawer = \
            RemovalDrawer(get_size_func=self._get_drawer_size,
                          invalidate_rect_func=self._invalidate_drawer_rect)
        self.win_drawer = \
            WinDrawer(get_size_func=self._get_drawer_size,
                      invalidate_rect_func=self._invalidate_drawer_rect)

        self._icon_file_func = icon_file_func

        self._preview_rect = Gdk.Rectangle()
        self._preview_rect.x = self._preview_rect.y = \
            self._preview_rect.width = self._preview_rect.height = 0

        self._toolbar_rect = Gdk.Rectangle()
        self._toolbar_rect.x = self._toolbar_rect.y = \
            self._toolbar_rect.width = self._toolbar_rect.height = 0

        self._drawer_rect = Gdk.Rectangle()
        self._drawer_rect.x = self._drawer_rect.y = \
            self._drawer_rect.width = self._drawer_rect.height = 0

        self._drawer = self.board_drawer

        # Mouse position as a floating point value over the 4x3 unit preview
        # area.
        self._cursor_pos = (0.0, 0.0)

        # Cursor size in pixels.
        self._cursor_size = (0, 0)

        self._click_visible = False
        self._cursor_visible = False

        self.connect('draw', self._draw_event_cb)
        self.connect('configure-event', self._configure_event_cb)
        # self.connect('size-allocate', self._configure_event_cb)

    def _get_drawer_size(self):
        return (self._drawer_rect.width, self._drawer_rect.height)

    def _invalidate_drawer_rect(self, rect):
        if self.get_window():
            (x, y) = (self._drawer_rect.x, self._drawer_rect.y)
            offset_rect = Gdk.Rectangle()
            offset_rect.x, offset_rect.y, = (rect.x + x, rect.y + y)
            offset_rect.width, offset_rect.height = (rect.width, rect.height)
            self.get_window().invalidate_rect(offset_rect, True)

    def set_drawer(self, drawer):
        self._drawer = drawer
        r = self._preview_rect
        self._invalidate_client_rect(0, 0, r.width, r.height)

    def center_cursor(self):
        self.set_cursor_pos(2.0, 1.5)

    def set_cursor_pos(self, x, y):
        self._invalidate_cursor()
        self._cursor_pos = (x, y)
        self._invalidate_cursor()
        self._update_mouse_position()

    def get_cursor_pos(self):
        return self._cursor_pos

    def set_click_visible(self, click_visible):
        self._click_visible = click_visible
        self._invalidate_click()

    def set_cursor_visible(self, cursor_visible):
        self._cursor_visible = cursor_visible
        self._invalidate_cursor()

    def get_block_coord(self, x, y):
        # Returns the coordinate of the given board block in terms of
        # 4x3 units.
        if (self._preview_rect.width == 0 or self._preview_rect.height == 0):
            return (0, 0)
        (drawer_x, drawer_y) = self.board_drawer.get_block_coord(x, y)
        preview_x = drawer_x
        preview_y = drawer_y + self._toolbar_rect.height
        out_x = preview_x * 4.0 / self._preview_rect.width
        out_y = preview_y * 3.0 / self._preview_rect.height
        return (out_x, out_y)

    def get_icon_coord(self, index):
        # Returns the coordinate of the given icon in terms of 4x3 units.
        icon_height = self._toolbar_rect.height
        preview_x = icon_height * (index + 0.5)
        preview_y = icon_height * 0.5
        out_x = preview_x * 4.0 / self._preview_rect.width
        out_y = preview_y * 3.0 / self._preview_rect.height
        return (out_x, out_y)

    def _get_cursor_pixel_coords(self):
        (x, y) = self._cursor_pos
        pixel_x = x * self._preview_rect.width / 4
        pixel_y = y * self._preview_rect.height / 3
        return (pixel_x, pixel_y)

    def _invalidate_cursor(self):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        self._invalidate_client_rect(pixel_x, pixel_y, *self._cursor_size)

        if self._click_visible:
            self._invalidate_click()

    def _invalidate_click(self):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        r = self._cursor_size[0] * _CLICK_OUTER_RADIUS
        r2 = r * 2
        self._invalidate_client_rect(pixel_x - r, pixel_y - r, r2, r2)

    def _invalidate_client_rect(self, x, y, width, height):
        if self.get_window():
            rect = Gdk.Rectangle()
            rect.x, rect.y, rect.width, rect.height = (
                int(math.floor(x)) + self._preview_rect.x,
                int(math.floor(y)) + self._preview_rect.y,
                int(math.ceil(width)) + 1, int(math.ceil(height)) + 1)

            self.get_window().invalidate_rect(rect, True)

    def _update_mouse_position(self):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        (x, y) = (pixel_x, pixel_y - self._toolbar_rect.height)
        self.board_drawer.set_mouse_selection(x, y)

    def _size_allocate_cb(self, widget, rect):
        self.width = rect.width
        self.height = rect.height

    def _draw_event_cb(self, widget, cr):
        alloc = self.get_allocation()
        cr.rectangle(0, 0, alloc.width, alloc.height)
        self._draw(cr, alloc.width, alloc.height)

    def _draw(self, cr, width, height):
        cr.set_source_rgb(*_BG_COLOR)
        cr.rectangle(0, 0, width, height)
        cr.fill()

        cr.save()
        cr.rectangle(self._preview_rect.x, self._preview_rect.y,
                     self._preview_rect.width, self._preview_rect.height)
        cr.clip()

        self._draw_toolbar(cr)
        self._draw_grid(cr)
        if self._click_visible:
            self._draw_click(cr)
        if self._cursor_visible:
            self._draw_cursor(cr)

        cr.restore()

    def _draw_toolbar(self, cr):
        cr.set_source_rgb(*_TOOLBAR_COLOR)
        cr.rectangle(self._toolbar_rect.x, self._toolbar_rect.y,
                     self._toolbar_rect.width, self._toolbar_rect.height)
        cr.fill()

        icon_height = self._toolbar_rect.height
        scale = icon_height / 55.0
        for (i, icon_name) in enumerate([
                'new-game',
                'replay-game',
                'edit-undo',
                'edit-redo',
                'easy-level',
                'medium-level',
                'hard-level',
        ]):
            file_path = self._icon_file_func(icon_name)
            handle = _get_icon_handle(file_path)
            cr.save()
            cr.translate(self._toolbar_rect.x + i * icon_height,
                         self._toolbar_rect.y)
            cr.scale(scale, scale)
            handle.render_cairo(cr)
            cr.restore()

    def _draw_grid(self, cr):
        cr.save()
        cr.translate(self._drawer_rect.x, self._drawer_rect.y)
        self._drawer.draw(cr, self._drawer_rect.width,
                          self._drawer_rect.height)
        cr.restore()

    def _draw_click(self, cr):
        width = self._cursor_size[0]
        weight = width * _CLICK_WEIGHT_SCALE
        outline_weight = width * _CLICK_OUTLINE_WEIGHT_SCALE
        r1 = width * _CLICK_INNER_RADIUS + outline_weight
        r2 = width * _CLICK_OUTER_RADIUS - outline_weight
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        x = pixel_x + self._preview_rect.x
        y = pixel_y + self._preview_rect.y

        cr.save()
        cr.translate(x, y)
        cr.set_line_cap(cairo.LINE_CAP_ROUND)
        angle_inc = math.pi * 2.0 / 6
        cr.rotate(angle_inc * 0.75)
        for i in range(6):
            cr.set_line_width(outline_weight)
            cr.set_source_rgb(*_CURSOR_OUTLINE_COLOR)
            cr.move_to(r1, 0)
            cr.line_to(r2, 0)
            cr.stroke()

            cr.set_line_width(weight)
            cr.set_source_rgb(*_CURSOR_COLOR)
            cr.move_to(r1, 0)
            cr.line_to(r2, 0)
            cr.stroke()

            cr.rotate(angle_inc)

        cr.restore()

    def _draw_cursor(self, cr):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        x = pixel_x + self._preview_rect.x
        y = pixel_y + self._preview_rect.y
        (width, height) = self._cursor_size
        weight = width * _CURSOR_WEIGHT_SCALE
        outline_weight = width * _CURSOR_OUTLINE_WEIGHT_SCALE
        hw = outline_weight / 2.0

        def draw_arrow():
            cr.move_to(x + width * 0.9 - hw, y + hw)
            cr.line_to(x + hw, y + hw)
            cr.line_to(x + hw, y + height * 0.9 - hw)
            cr.move_to(x + hw, y + hw)
            cr.line_to(x + width - hw, y + height - hw)
            cr.stroke()

        cr.save()
        cr.set_line_cap(cairo.LINE_CAP_ROUND)
        cr.set_line_join(cairo.LINE_JOIN_ROUND)

        cr.set_line_width(outline_weight)
        cr.set_source_rgb(*_CURSOR_OUTLINE_COLOR)
        draw_arrow()

        cr.set_line_width(weight)
        cr.set_source_rgb(*_CURSOR_COLOR)
        draw_arrow()

        cr.restore()

    def _configure_event_cb(self, widget, event):
        (width, height) = (event.width, event.height)

        actual_width = width - _PREVIEW_TRIM_WIDTH
        actual_height = actual_width * 3 // 4

        self.set_size_request(actual_width, actual_height)

        icon_height = int(math.ceil(actual_height * _ICON_HEIGHT))
        board_height = actual_height - icon_height

        x_offset = (width - actual_width) // 2
        y_offset = (height - actual_height) // 2

        self._preview_rect = Gdk.Rectangle()
        self._preview_rect.x = x_offset
        self._preview_rect.y = y_offset
        self._preview_rect.width = actual_width
        self._preview_rect.height = actual_height

        self._toolbar_rect = Gdk.Rectangle()
        self._toolbar_rect.x = x_offset
        self._toolbar_rect.y = y_offset
        self._toolbar_rect.width = actual_width
        self._toolbar_rect.height = icon_height

        self._drawer_rect = Gdk.Rectangle()
        self._drawer_rect.x = x_offset
        self._drawer_rect.y = y_offset + icon_height
        self._drawer_rect.width = actual_width
        self._drawer_rect.height = board_height

        self.board_drawer.resize(actual_width, board_height)
        self.removal_drawer.resize(actual_width, board_height)
        self.win_drawer.resize(actual_width, board_height)

        cursor_width = actual_height * _CURSOR_SCALE
        self._cursor_size = (cursor_width, cursor_width)

        self._update_mouse_position()
Ejemplo n.º 4
0
class _PreviewWidget(Gtk.DrawingArea):
    def __init__(self, icon_file_func, *args, **kwargs):
        super(_PreviewWidget, self).__init__(*args, **kwargs)

        self.board_drawer = \
            BoardDrawer(get_size_func=self._get_drawer_size,
                        invalidate_rect_func=self._invalidate_drawer_rect)
        self.removal_drawer = \
            RemovalDrawer(get_size_func=self._get_drawer_size,
                          invalidate_rect_func=self._invalidate_drawer_rect)
        self.win_drawer = \
            WinDrawer(get_size_func=self._get_drawer_size,
                      invalidate_rect_func=self._invalidate_drawer_rect)

        self._icon_file_func = icon_file_func

        self._preview_rect = Gdk.Rectangle()
        self._preview_rect.x = self._preview_rect.y = \
            self._preview_rect.width = self._preview_rect.height = 0

        self._toolbar_rect = Gdk.Rectangle()
        self._toolbar_rect.x = self._toolbar_rect.y = \
            self._toolbar_rect.width = self._toolbar_rect.height = 0

        self._drawer_rect = Gdk.Rectangle()
        self._drawer_rect.x = self._drawer_rect.y = \
            self._drawer_rect.width = self._drawer_rect.height = 0

        self._drawer = self.board_drawer

        # Mouse position as a floating point value over the 4x3 unit preview
        # area.
        self._cursor_pos = (0.0, 0.0)

        # Cursor size in pixels.
        self._cursor_size = (0, 0)

        self._click_visible = False
        self._cursor_visible = False

        self.connect('draw', self._draw_event_cb)
        self.connect('configure-event', self._configure_event_cb)
        # self.connect('size-allocate', self._configure_event_cb)

    def _get_drawer_size(self):
        return (self._drawer_rect.width, self._drawer_rect.height)

    def _invalidate_drawer_rect(self, rect):
        if self.get_window():
            (x, y) = (self._drawer_rect.x, self._drawer_rect.y)
            offset_rect = Gdk.Rectangle()
            offset_rect.x, offset_rect.y, = (rect.x + x, rect.y + y)
            offset_rect.width, offset_rect.height = (rect.width, rect.height)
            self.get_window().invalidate_rect(offset_rect, True)

    def set_drawer(self, drawer):
        self._drawer = drawer
        r = self._preview_rect
        self._invalidate_client_rect(0, 0, r.width, r.height)

    def center_cursor(self):
        self.set_cursor_pos(2.0, 1.5)

    def set_cursor_pos(self, x, y):
        self._invalidate_cursor()
        self._cursor_pos = (x, y)
        self._invalidate_cursor()
        self._update_mouse_position()

    def get_cursor_pos(self):
        return self._cursor_pos

    def set_click_visible(self, click_visible):
        self._click_visible = click_visible
        self._invalidate_click()

    def set_cursor_visible(self, cursor_visible):
        self._cursor_visible = cursor_visible
        self._invalidate_cursor()

    def get_block_coord(self, x, y):
        # Returns the coordinate of the given board block in terms of 4x3 units.
        if (self._preview_rect.width == 0
            or self._preview_rect.height == 0):
            return (0, 0)
        (drawer_x, drawer_y) = self.board_drawer.get_block_coord(x, y)
        preview_x = drawer_x
        preview_y = drawer_y + self._toolbar_rect.height
        out_x = preview_x * 4.0 / self._preview_rect.width
        out_y = preview_y * 3.0 / self._preview_rect.height
        return (out_x, out_y)

    def get_icon_coord(self, index):
        # Returns the coordinate of the given icon in terms of 4x3 units.
        icon_height = self._toolbar_rect.height
        preview_x = icon_height * (index + 0.5)
        preview_y = icon_height * 0.5
        out_x = preview_x * 4.0 / self._preview_rect.width
        out_y = preview_y * 3.0 / self._preview_rect.height
        return (out_x, out_y)

    def _get_cursor_pixel_coords(self):
        (x, y) = self._cursor_pos
        pixel_x = x * self._preview_rect.width / 4
        pixel_y = y * self._preview_rect.height / 3
        return (pixel_x, pixel_y)

    def _invalidate_cursor(self):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        self._invalidate_client_rect(pixel_x, pixel_y, *self._cursor_size)

        if self._click_visible:
            self._invalidate_click()

    def _invalidate_click(self):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        r = self._cursor_size[0] * _CLICK_OUTER_RADIUS
        r2 = r * 2
        self._invalidate_client_rect(pixel_x - r, pixel_y - r, r2, r2)

    def _invalidate_client_rect(self, x, y, width, height):
        if self.get_window():
            rect = Gdk.Rectangle()
            rect.x, rect.y, rect.width, rect.height = (
                int(math.floor(x)) + self._preview_rect.x,
                int(math.floor(y)) + self._preview_rect.y,
                int(math.ceil(width)) + 1,
                int(math.ceil(height)) + 1)

            self.get_window().invalidate_rect(rect, True)

    def _update_mouse_position(self):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        (x, y) = (pixel_x, pixel_y - self._toolbar_rect.height)
        self.board_drawer.set_mouse_selection(x, y)

    def _size_allocate_cb(self, widget, rect):
        self.width = rect.width
        self.height = rect.height

    def _draw_event_cb(self, widget, cr):
        alloc = self.get_allocation()
        cr.rectangle(0, 0, alloc.width, alloc.height)
        self._draw(cr, alloc.width, alloc.height)

    def _draw(self, cr, width, height):
        cr.set_source_rgb(*_BG_COLOR)
        cr.rectangle(0, 0, width, height)
        cr.fill()

        cr.save()
        cr.rectangle(self._preview_rect.x,
                     self._preview_rect.y,
                     self._preview_rect.width,
                     self._preview_rect.height)
        cr.clip()

        self._draw_toolbar(cr)
        self._draw_grid(cr)
        if self._click_visible:
            self._draw_click(cr)
        if self._cursor_visible:
            self._draw_cursor(cr)

        cr.restore()

    def _draw_toolbar(self, cr):
        cr.set_source_rgb(*_TOOLBAR_COLOR)
        cr.rectangle(self._toolbar_rect.x,
                     self._toolbar_rect.y,
                     self._toolbar_rect.width,
                     self._toolbar_rect.height)
        cr.fill()

        icon_height = self._toolbar_rect.height
        scale = icon_height / 55.0
        for (i, icon_name) in enumerate(['new-game',
                                         'replay-game',
                                         'edit-undo',
                                         'edit-redo']):
            file_path = self._icon_file_func(icon_name)
            handle = _get_icon_handle(file_path)
            cr.save()
            cr.translate(self._toolbar_rect.x + i * icon_height,
                         self._toolbar_rect.y)
            cr.scale(scale, scale)
            handle.render_cairo(cr)
            cr.restore()

    def _draw_grid(self, cr):
        cr.save()
        cr.translate(self._drawer_rect.x, self._drawer_rect.y)
        self._drawer.draw(cr, self._drawer_rect.width,
                          self._drawer_rect.height)
        cr.restore()

    def _draw_click(self, cr):
        width = self._cursor_size[0]
        weight = width * _CLICK_WEIGHT_SCALE
        outline_weight = width * _CLICK_OUTLINE_WEIGHT_SCALE
        r1 = width * _CLICK_INNER_RADIUS + outline_weight
        r2 = width * _CLICK_OUTER_RADIUS - outline_weight
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        x = pixel_x + self._preview_rect.x
        y = pixel_y + self._preview_rect.y

        cr.save()
        cr.translate(x, y)
        cr.set_line_cap(cairo.LINE_CAP_ROUND)
        angle_inc = math.pi * 2.0 / 6
        cr.rotate(angle_inc * 0.75)
        for i in range(6):
            cr.set_line_width(outline_weight)
            cr.set_source_rgb(*_CURSOR_OUTLINE_COLOR)
            cr.move_to(r1, 0)
            cr.line_to(r2, 0)
            cr.stroke()

            cr.set_line_width(weight)
            cr.set_source_rgb(*_CURSOR_COLOR)
            cr.move_to(r1, 0)
            cr.line_to(r2, 0)
            cr.stroke()

            cr.rotate(angle_inc)

        cr.restore()

    def _draw_cursor(self, cr):
        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
        x = pixel_x + self._preview_rect.x
        y = pixel_y + self._preview_rect.y
        (width, height) = self._cursor_size
        weight = width * _CURSOR_WEIGHT_SCALE
        outline_weight = width * _CURSOR_OUTLINE_WEIGHT_SCALE
        hw = outline_weight / 2.0

        def draw_arrow():
            cr.move_to(x + width * 0.9 - hw, y + hw)
            cr.line_to(x + hw, y + hw)
            cr.line_to(x + hw, y + height * 0.9 - hw)
            cr.move_to(x + hw, y + hw)
            cr.line_to(x + width - hw, y + height - hw)
            cr.stroke()

        cr.save()
        cr.set_line_cap(cairo.LINE_CAP_ROUND)
        cr.set_line_join(cairo.LINE_JOIN_ROUND)

        cr.set_line_width(outline_weight)
        cr.set_source_rgb(*_CURSOR_OUTLINE_COLOR)
        draw_arrow()

        cr.set_line_width(weight)
        cr.set_source_rgb(*_CURSOR_COLOR)
        draw_arrow()

        cr.restore()

    def _configure_event_cb(self, widget, event):
        (width, height) = (event.width, event.height)

        actual_width = width - _PREVIEW_TRIM_WIDTH
        actual_height = actual_width * 3 / 4

        self.set_size_request(actual_width, actual_height)

        icon_height = int(math.ceil(actual_height * _ICON_HEIGHT))
        board_height = actual_height - icon_height

        x_offset = (width - actual_width) / 2
        y_offset = (height - actual_height) / 2

        self._preview_rect = Gdk.Rectangle()
        self._preview_rect.x = x_offset
        self._preview_rect.y = y_offset
        self._preview_rect.width = actual_width
        self._preview_rect.height = actual_height

        self._toolbar_rect = Gdk.Rectangle()
        self._toolbar_rect.x = x_offset
        self._toolbar_rect.y = y_offset
        self._toolbar_rect.width = actual_width
        self._toolbar_rect.height = icon_height

        self._drawer_rect = Gdk.Rectangle()
        self._drawer_rect.x = x_offset
        self._drawer_rect.y = y_offset + icon_height
        self._drawer_rect.width = actual_width
        self._drawer_rect.height = board_height

        self.board_drawer.resize(actual_width, board_height)
        self.removal_drawer.resize(actual_width, board_height)
        self.win_drawer.resize(actual_width, board_height)

        cursor_width = actual_height * _CURSOR_SCALE
        self._cursor_size = (cursor_width, cursor_width)

        self._update_mouse_position()