def _highlight_border(self, context: cairo.Context, row: int, col: int): width = self._total_width height = self._total_height line_width = 3 row_rectangles = [ Rectangle(Point(1, row * self.cell_height - line_width / 2), width - 2, line_width), Rectangle(Point(1, (row + 1) * self.cell_height - line_width / 2), width - 2, line_width) ] col_rectangles = [ Rectangle(Point(col * self.cell_width - line_width / 2, 1), line_width, height - 2), Rectangle(Point((col + 1) * self.cell_width - line_width / 2, 1), line_width, height - 2) ] context.save() r, g, b = self.highlight_color context.set_source_rgba(r, g, b, .6) for row_rectangle in row_rectangles: context.rectangle(row_rectangle.start.x, row_rectangle.start.y, row_rectangle.width, row_rectangle.height) context.fill() for col_rectangle in col_rectangles: context.rectangle(col_rectangle.start.x, col_rectangle.start.y, col_rectangle.width, col_rectangle.height) context.fill() context.restore()
def layout(self, context: cairo.Context): super().layout(context) context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(self.title) font_shape = Rectangle(Point(h / 2 + self.distance, self.distance), xa, h) self.__title_start_point = Point(font_shape.start.x, font_shape.start.y + h) outer_font_box = DrawableRectangle( Point(font_shape.start.x - self.distance, font_shape.start.y - self.distance), font_shape.width + 2 * self.distance, font_shape.height + 2 * self.distance) self.__outer_font_box = outer_font_box wrapper_shape = DrawableRectangle( Point(0, outer_font_box.start.y + outer_font_box.height / 2), outer_font_box.start.x + max(outer_font_box.width, self.widget.shape.width) + self.distance, outer_font_box.height / 2 + 2 * self.distance + self.widget.shape.height) self.widget.set_translate( outer_font_box.start.x, outer_font_box.start.y + outer_font_box.height + self.distance) self.__wrapper_shape = wrapper_shape self.shape = DrawableRectangle( Point(0, 0), wrapper_shape.width, wrapper_shape.start.y + wrapper_shape.height)
def __init__(self, crucipixel: core.Crucipixel, start=Point(0,0), cell_size=20, *args, **kwargs): super().__init__(*args,**kwargs) self.translate(start.x,start.y) self.cell_size = cell_size self.grid = CrucipixelGrid(crucipixel, cell_size, cell_size) self.add(self.grid) self._init_guides(crucipixel) def update_guide(orientation: Orientation, index: int, status: GuideStatus): if orientation == Orientation.HORIZONTAL: guide = self.horizontal_guide else: guide = self.vertical_guide guide.change_status(index, status) self.grid.on_guide_update = update_guide self.grid.refresh_guides() self._current_scale = Point(1, 1) self._direction_animations = {} self._movement = dict(global_constants.global_movement_keys)
def _start_selection(self, value: CrucipixelCellValue, row: int, col: int): if self._selection_start_point is None: self._selection_value = value self._selection_start_point = Point(col, row) self._selection_end_point = Point(col, row) self._update_selection_rectangle() self.crucipixel.make_move(self._get_moves())
def on_mouse_down(self, widget, event: MouseEvent): handled = self.grid.visible if 'ctrl' not in event.modifiers: handled = super().on_mouse_down(widget, event) or handled if not handled: self._mouse_down = True self._click_point = Point(event.x, event.y) self._translate_vector = Point(self.crucipixel.fromWidgetCoords.transform_point(0,0))
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, event: MouseEvent): handled = False if 'ctrl' not in event.modifiers: handled = super().on_mouse_down(widget, event) if not handled: self.__mouse_down = True self.__click_point = Point(event.x, event.y) self.__translate_vector = Point( self.__grid.fromWidgetCoords.transform_point(0, 0))
def _update_selection_rectangle(self): if self._selection_start_point is not None and \ self._selection_end_point is not None: s = self._selection_start_point e = self._selection_end_point upper = Point(min(s.col, e.col), min(s.row, e.row)) lower = Point(max(s.col, e.col), max(s.row, e.row)) height = lower.row - upper.row width = lower.col - upper.col self._selection_rectangle = Rectangle(upper, width, height)
def _line_coordinates(self, line_index): if self.orientation == Guides.HORIZONTAL: delta_x = (line_index + 1) * self.cell_size delta_y = -self.line_length return [Point(delta_x, 0), Point(delta_x, delta_y)] elif self.orientation == Guides.VERTICAL: delta_x = -self.line_length delta_y = (line_index + 1) * self.cell_size return [Point(0, delta_y), Point(delta_x, delta_y)] else: raise ValueError("Invalid orientation: {}".format( str(self.orientation)))
def layout(self, context: cairo.Context): super().layout(context) width, height = self.container_size self.__background_rectangle = DrawableRectangle(Point(0, 0), width, height) context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(self.label) padding = self.padding label_start = Point((width - xa)/2, (height - h)/2) self.__label_start = Point(label_start.x, label_start.y + h) label_shape = Rectangle(label_start, xa, h) back_shape = self.__back_button.shape ok_shape = self.__ok_button.shape button_y = label_start.y + label_shape.height + padding/2 total_height = label_shape.height +\ max(back_shape.height, ok_shape.height) +\ 1.5 * padding button_line_width = back_shape.width + ok_shape.width + 2*padding if button_line_width + 2*padding <= label_shape.width: self.__back_button.set_translate( label_start.x + padding, # (width - button_line_width)/2 + back_shape.width, button_y ) self.__ok_button.set_translate( label_start.x + label_shape.width - padding, # (width + button_line_width)/2 - ok_shape.width, button_y ) self.__overlay_shape = DrawableRectangle( Point(label_start.x - padding, label_start.y - padding/2), label_shape.width + 2 * padding, total_height ) else: self.__back_button.set_translate( (width - button_line_width)/2, button_y ) self.__ok_button.set_translate( (width + button_line_width)/2, button_y ) self.__overlay_shape = DrawableRectangle( Point((width - button_line_width)/2 - padding, label_start.y - padding/2), 2*padding + button_line_width, total_height )
def on_draw(self, widget, context): context.save() context.set_line_width(1) width = self._total_width height = self._total_height for row in range(self.number_of_rows): for col in range(self.number_of_cols): value = self.get_cell_value(row, col) rectangle = Rectangle( Point(col * self.cell_width, row * self.cell_height), self.cell_width + 2, self.cell_height + 2) self._draw_cell(context, value, rectangle) context.set_source_rgb(0, 0, 0) context.set_line_cap(cairo.LINE_CAP_SQUARE) context.set_line_width(2.5) DrawableRectangle(Point(0, 0), width, height).draw_on_context(context) context.stroke() if not self.victory_screen: for i, x in enumerate( range(0, width + self.cell_width, self.cell_width)): if i % 5 == 0: context.set_line_width(2.5) else: context.set_line_width(1) context.move_to(x, 0) context.line_to(x, height) context.stroke() for i, y in enumerate( range(0, height + self.cell_height, self.cell_height)): if i % 5 == 0: context.set_line_width(2.5) else: context.set_line_width(1) context.move_to(0, y) context.line_to(width, y) context.stroke() if self._highlight_col is not None and self._highlight_row is not None\ and self._should_highlight and not self.victory_screen: self._highlight_rectangles(context, self._highlight_row, self._highlight_col) context.restore()
def __init__(self, label: str, font_size: int=20, back_label: str="Back", ok_label: str="Ok", background_color: Tuple[Number, Number, Number]=(.3, .3, .3), background_alpha: Number=.5): super().__init__() self.label = label self.font_size = font_size self.background_color = background_color self.background_alpha = background_alpha self.padding = 20 self.__background_rectangle = None self.__overlay_shape = None self.__label_start = Point(0, 0) button_font_size = font_size * .8 self.__back_button = BetterButton(back_label, button_font_size, origin=BetterButton.LEFT) self.__ok_button = BetterButton(ok_label, button_font_size, origin=BetterButton.RIGHT) self.add(self.__back_button) self.add(self.__ok_button)
def get_position_from_uniform_speed(start_position: "Point", speed: "Point", time: "sec"): def single_coord(pos, speed, time): return pos + time * speed return Point(single_coord(start_position.x, speed.x, time), single_coord(start_position.y, speed.y, time))
def _move_selection(self, row: int, col: int): new_point = Point(col, row) if new_point != self._selection_end_point: self._selection_end_point = new_point self._update_selection_rectangle() self.crucipixel.undo_move() self.crucipixel.make_move(self._get_moves())
def on_draw(self,widget,context): if self._down_pos - self.height <= self._up_pos: pass else: context.save() super().on_draw(widget, context) if self.skip + self.fill <= 1: up = self._up_pos + self._up_offset * 2 + 3 down = self._down_pos - self._up_offset * 2 - 3 if up >= down: up -= 2 down += 2 if up < down: height = down - up bar_width = self.width/6 intensity = .2 context.set_source_rgb(intensity, intensity, intensity) rectangle = DrawableRoundedRectangle( Point( self._left_offset - bar_width, up + self.skip * height ), 2*bar_width, max(height * self.fill, 1.5) ) # context.rectangle( # self._left_offset - bar_width, # up + self.skip * height, # 2*bar_width, # max(height * self.fill, 1.5) # ) rectangle.draw_on_context(context) context.fill() context.restore()
def __init__(self, height=40, width=None, padding=None, distance=None): super().__init__() if width is None: # width = (height / 15) * 7 width = (height / 5) * 3 if distance is None: distance = height / 5 if padding is None: padding = height / 8 arrow_width = width - 2 * padding arrow_height = (height - 2 * padding - distance) / 2 self.up_arrow = Arrow(arrow_width, arrow_height, direction=Arrow.UP) self.down_arrow = Arrow(arrow_width, arrow_height, direction=Arrow.DOWN) self.up_arrow.translate(arrow_width / 2 + padding, padding + arrow_height / 2) self.down_arrow.translate(arrow_width / 2 + padding, height - padding - arrow_height / 2) self.add(self.up_arrow) self.add(self.down_arrow) self.shape = DrawableRectangle(Point(0, 0), width, height) self.increment_action = lambda: None self.decrement_action = lambda: None self.__moving_action = None self.__skip = 0
def set_shape_from_context(self, context: cairo.Context): label = self.label padding = self.padding context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(label) width = padding * 2 + xa height = padding * 2 + h height = max(height, self.min_height) if self.origin == self.LEFT: start = Point(0, 0) elif self.origin == self.CENTER: start = Point(-width / 2, 0) else: start = Point(-width, 0) self.shape = DrawableRoundedRectangle(start, width, height)
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)
def layout(self, context: cairo.Context): width, height = self.container_size self.__background_rectangle = DrawableRectangle(Point(0, 0), width, height) context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(self.label) padding = self.padding rectangle_width = xa + 2 * padding rectangle_height = padding + h start_x = (width - rectangle_width) / 2 start_y = (height - rectangle_height) / 2 self.__label_rectangle = DrawableRectangle(Point(start_x, start_y), rectangle_width, rectangle_height)
def get_position_from_uniform_acceleration(start_position: "Point", start_speed: "Point", acc: "Point", time: "sec"): def single_coord(pos, speed, acc, time): return pos + time * (speed + (time * acc) / 2) return Point(single_coord(start_position.x, start_speed.x, acc.x, time), single_coord(start_position.y, start_speed.y, acc.y, time))
def start_crucipixel(self,crucipixel: core.Crucipixel, start=Point(120,100),cell_size=20): self.crucipixel = CompleteCrucipixel(crucipixel, start, cell_size) self.crucipixel.ID="CompleteCrucipixel" self.grid = CrucipixelGridWonWrapper(self.crucipixel.grid, crucipixel) self.grid.visible = False self.add(self.crucipixel) self.add(self.grid)
def __init__(self, width, height, background_color=None, *args, **kwargs): super().__init__(*args, **kwargs) self.width = width self.height = height self.font_size = 10 self.clip_rectangle = Rectangle(Point(0, 0), width, height) self._text = "" self._background_color = background_color
def on_mouse_down(self, w, e): p = Point(e.x, e.y) if self.is_point_in(p): self.selected = True self._deltaP = p return True else: return False
def __init__(self, label: str, position: Point = Point(0, 0)): self.label = label self.position = position self.is_wrong = False self.is_done = False self.is_cancelled = False self.width = 0 self.height = 0
def on_mouse_down(self, w, e): p = Point(e.x, e.y) for line in self.elements: for e in line: if e.wide_cell.is_point_in(p): e.cancelled = not e.cancelled self.invalidate() return True
def __init__(self, centerP, inner, outer, iters=36): super().__init__(outer * 2, outer * 2) self._centerP = Point(0, 0) self.centerP = centerP self.inner = inner self.outer = outer self.iters = iters self.selected = False self.ID = "Donut"
def append_line(line: str): nonlocal start_y if not line: start_y += self.padding else: _, yb, _, h, _, _ = context.text_extents(line) start_y += h - (yb * .75) self.__text_lines.append( _TextLine(line, Point(self.padding, start_y)))
def layout(self, context: cairo.Context): if self.father is None: return width = self.father.container_size[0] - 2 * self.padding self._set_font(context) def fit_check(l: List[str]) -> bool: l = " ".join(l) xb, yb, w, h, xa, ya = context.text_extents(l) if xa > width: return False else: return True self.__text_lines = [] start_y = self.padding / 2 def append_line(line: str): nonlocal start_y if not line: start_y += self.padding else: _, yb, _, h, _, _ = context.text_extents(line) start_y += h - (yb * .75) self.__text_lines.append( _TextLine(line, Point(self.padding, start_y))) # context.move_to(self.padding, start_y + h + yb) # context.show_text(line) for paragraph in self.text: words = paragraph.split(" ") start = 0 while start < len(words): pivot = start end = len(words) if fit_check(islice(words, start, end)): append_line(" ".join(islice(words, start, end))) start = len(words) elif not fit_check([words[start]]): append_line(words[start]) start += 1 else: while end > pivot + 1: t = (end + pivot) // 2 if not fit_check(islice(words, start, t)): end = t else: pivot = t append_line(" ".join(islice(words, start, pivot))) start = pivot append_line("") self.shape = DrawableRectangle(Point(0, 0), width + 2 * self.padding, start_y + self.padding / 2)
def new_point(time): return Point(calc_pos(self._start_point.x, self._speed.x, self._acc.x, time), calc_pos(self._start_point.y, self._speed.y, self._acc.y, time) )
def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) self.ID = "MainArea" self.crucipixel = None self.grid = None self.selector = None self._mouse_down = False self._click_point = Point(0,0) self.navigator = None self.buttons = None self.zoom = None