Пример #1
0
 def react(self, event) -> int:
     # Checks, based on the cursor position whether we can insert before, into or after the node
     # Returns 0, 1 or 2 respectively
     # It is mostly with respect to the nodes head element known as the strip except for --- case * --- below
     self.clear_indicators()
     # The cursor is at the top edge of the node so we can attempt to insert before it
     if event.y_root < self.strip.winfo_rooty() + 5:
         self.tree.edge_indicator.top(
             upscale_bounds(bounds(self.strip), self))
         return self.InsertType.INSERT_BEFORE
     # The cursor is at the center of the node so we can attempt a direct insert into the node
     if self.strip.winfo_rooty(
     ) + 5 < event.y_root < self.strip.winfo_rooty(
     ) + self.strip.height - 5:
         if not self._is_terminal:
             # If node is terminal then id does not support children and consequently insertion
             self.highlight()
             return self.InsertType.INSERT_INTO
     # The cursor is at the bottom edge of the node so we attempt to insert immediately after the node
     elif self._expanded:  # --- Case * ---
         # If the node is expanded we would want to edge indicate at the very bottom after its last child
         if event.y_root > self.winfo_rooty() + self.height - 5:
             self.tree.edge_indicator.bottom(bounds(self))
             return self.InsertType.INSERT_AFTER
     else:
         self.tree.edge_indicator.bottom(
             upscale_bounds(bounds(self.strip), self))
         return self.InsertType.INSERT_AFTER
Пример #2
0
 def _location_analysis(self, bounds):
     self.clear_indicators()
     self._edge_indicator.update_idletasks()
     bounds = geometry.relative_bounds(bounds, self.container)
     x, y = bounds[0], bounds[1]
     col, row = self.container.grid_location(x, y)
     x, y = geometry.upscale_bounds(bounds, self.container)[:2]
     slaves = self.container.grid_slaves(max(0, row), max(0, col))
     if len(slaves) == 0:
         self.container.update_idletasks()
         bbox = self.container.grid_bbox(col, row)
         bounds = *bbox[:2], bbox[0] + bbox[2], bbox[1] + bbox[3]
         # Make bounds relative to designer
         bounds = geometry.upscale_bounds(bounds, self.container)
     else:
         bounds = geometry.bounds(slaves[0])
     y_offset, x_offset = 10, 10  # 0.15*(bounds[3] - bounds[1]), 0.15*(bounds[2] - bounds[0])
     # If the position is empty no need to alter the row or column
     resize = 1 if len(slaves) else 0
     if y - bounds[1] < y_offset:
         self._edge_indicator.top(bounds)
         return row, col, resize, 0
     elif bounds[3] - y < y_offset:
         self._edge_indicator.bottom(bounds)
         return row + resize, col, resize, 0
     elif x - bounds[0] < x_offset:
         self._edge_indicator.left(bounds)
         return row, col, 0, resize
     elif bounds[2] - x < x_offset:
         self._edge_indicator.right(bounds)
         return row, col + resize, 0, resize
     else:
         self._highlighter.highlight_bounds(bounds)
         return row, col, 0, 0
Пример #3
0
 def layout_at(self, bounds):
     for container in sorted(filter(lambda x: isinstance(x, Container) and x != self.current_obj, self.objects),
                             key=lambda x: len(self.objects) - x.level):
         if isinstance(self.current_obj, Container) and self.current_obj.level < container.level:
             continue
         if self.compute_overlap(geometry.bounds(container), bounds):
             return container
     return None
Пример #4
0
 def initialize(self, former_strategy=None):
     # create a list of children and their bounds which won't change during iteration
     bounding_map = [(child, geometry.bounds(child))
                     for child in self.children]
     if former_strategy:
         former_strategy.clear_all()
     for child, bounds in bounding_map:
         self.add_widget(child, bounds)
Пример #5
0
 def _stop_displace(self, _):
     if self._displace_active:
         # this ensures event is added to undo redo stack
         self._on_release(geometry.bounds(self.current_obj))
         # mark the latest action as designer displace
         latest = self.studio.last_action()
         if latest is not None:
             latest.key = "designer_displace"
         self._displace_active = False
Пример #6
0
 def displace(self, side):
     if not self.current_obj:
         return
     bounds = geometry.bounds(self.current_obj)
     x1, y1, x2, y2 = bounds
     if side == 'right':
         bounds = x1 + 1, y1, x2 + 1, y2
     elif side == 'left':
         bounds = x1 - 1, y1, x2 - 1, y2
     elif side == 'up':
         bounds = x1, y1 - 1, x2, y2 - 1
     elif side == 'down':
         bounds = x1, y1 + 1, x2, y2 + 1
     self._on_move(bounds)
     self._on_release(bounds)
Пример #7
0
    def displace(self, side):
        if not self.current_obj:
            return
        if time.time() - self._last_displace < .5:
            self.studio.pop_last_action("designer_displace")

        self._on_start()
        self._displace_active = True
        self._last_displace = time.time()
        bounds = geometry.bounds(self.current_obj)
        x1, y1, x2, y2 = bounds
        if side == 'right':
            bounds = x1 + 1, y1, x2 + 1, y2
        elif side == 'left':
            bounds = x1 - 1, y1, x2 - 1, y2
        elif side == 'up':
            bounds = x1, y1 - 1, x2, y2 - 1
        elif side == 'down':
            bounds = x1, y1 + 1, x2, y2 + 1
        self._on_move(bounds)
Пример #8
0
 def bbox(self, child):
     # return the canvas bbox if possible else use the normal bound
     # canvas bbox is more accurate
     if self._child_map.get(child) is not None:
         return self._frame.bbox(self._child_map[child])
     return geometry.relative_bounds(geometry.bounds(child), self._frame)
Пример #9
0
 def bounds(self):
     return geometry.bounds(self.container)