Skip to content

Commit

Permalink
Implement relative dimensions for place layout
Browse files Browse the repository at this point in the history
  • Loading branch information
ObaraEmmanuel committed Feb 20, 2024
1 parent c0a63ab commit e076b62
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 81 deletions.
54 changes: 36 additions & 18 deletions studio/feature/design.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from hoverset.util.execution import Action, as_thread

from studio.lib import NameGenerator
from studio.lib.layouts import PlaceLayoutStrategy
from studio.lib.layouts import BaseLayoutStrategy, PlaceLayoutStrategy
from studio.lib.pseudo import PseudoWidget, Container, Groups
from studio.parsers.loader import DesignBuilder, BaseStudioAdapter
from studio.ui import geometry
Expand All @@ -33,6 +33,21 @@

class DesignLayoutStrategy(PlaceLayoutStrategy):
name = "DesignLayout"
DEFINITION = {
**BaseLayoutStrategy.DEFINITION,
"x": {
"display_name": "x",
"type": "dimension",
"name": "x",
"default": None
},
"y": {
"display_name": "y",
"type": "dimension",
"name": "y",
"default": None
}
}

def add_new(self, widget, x, y):
self.container.add(widget, x, y, layout=self.container)
Expand All @@ -41,14 +56,15 @@ def resize_widget(self, widget, direction, delta):
info = self._info_with_delta(widget, direction, delta)
self.container.place_child(widget, **info)

def _move(self, widget, bounds):
self.container.position(widget, self.container.canvas_bounds(bounds))
def move_widget(self, widget, delta):
self.container.position(widget, self.container.canvas_bounds(self.bounds_from_delta(widget, delta)))

def add_widget(self, widget, bounds=None, **kwargs):
super(PlaceLayoutStrategy, self).add_widget(widget, bounds=bounds, **kwargs)
super(PlaceLayoutStrategy, self).remove_widget(widget)
if bounds:
self.move_widget(widget, bounds)
bounds = geometry.relative_bounds(bounds, self.container.body)
self.container.position(widget, bounds)
else:
x = kwargs.get("x", 10)
y = kwargs.get("y", 10)
Expand Down Expand Up @@ -79,12 +95,6 @@ def get_restore(self, widget):
"container": self,
}

def get_def(self, widget):
definition = dict(self.DEFINITION)
# We don't need bordermode
definition.pop("bordermode")
return definition

def info(self, widget):
bounds = self.container.bbox(widget)
width, height = geometry.dimensions(bounds)
Expand Down Expand Up @@ -404,15 +414,15 @@ def _on_handle_active(self, widget, direction):
self._all_bound = geometry.overall_bounds([w.get_bounds() for w in self._move_selection])
self._realtime_layout_update = True
for obj in self._move_selection:
obj.layout.change_start(obj)
obj.layout.start_move(obj)
# disable realtime layout update if any widget's layout doesn't support it
if not obj.layout.layout_strategy.realtime_support:
self._realtime_layout_update = False
else:
for obj in self._selected:
if not obj.layout.allow_resize:
continue
obj.layout.change_start(obj)
obj.layout.start_resize(obj)

if all(w.layout.layout_strategy.realtime_support for w in self._selected):
self._realtime_layout_update = True
Expand All @@ -436,7 +446,11 @@ def _on_handle_inactive(self, widget, direction):
if obj.is_toplevel and container != self:
toplevel_warning = True
continue
container.add_widget(obj, obj.get_bounds())
if widget.layout != container:
widget.layout.remove_widget(widget)
container.add_widget(obj, obj.get_bounds())
else:
container.end_move(obj)
layouts_changed.append(obj)
if obj == self.root_obj and container != self:
self.root_obj = container
Expand Down Expand Up @@ -495,18 +509,22 @@ def _on_handle_move(self, _, delta):
self._all_bound = all_bound

if container != current and current is not None:
current.end_move()
current.layout_strategy.on_move_exit()
current.clear_highlight()

if container is not None and container != current:
container.show_highlight()
self.current_container = current = container

realtime_update = self._realtime_layout_update

for w in objs:
x1, y1, x2, y2 = w.get_bounds()
current.move_widget(w, [x1 + dx, y1 + dy, x2 + dx, y2 + dy])
current.move_widget(w, delta)
if self._realtime_layout_update and current != w.layout:
# we can no longer attempt to provide realtime position info
realtime_update = False

if self.current_container.layout_strategy.realtime_support:
if realtime_update:
self.studio.widgets_layout_changed(objs)

def set_active_container(self, container):
Expand Down Expand Up @@ -776,7 +794,7 @@ def selected(self):
def _on_start(self):
obj = self.current_obj
if obj is not None:
obj.layout.change_start(obj)
obj.layout.start_move(obj)

def create_restore(self, widgets):
if not widgets:
Expand Down
4 changes: 2 additions & 2 deletions studio/feature/stylepane.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def _apply_action(self, prop, value, widgets, data):
has_change = True

if has_change:
self.style_pane._layout_group.on_widgets_change(self.widgets)
self.style_pane._layout_group.on_widgets_change()

def can_optimize(self):
classes = set(w.__class__ for w in self.widgets)
Expand Down Expand Up @@ -774,4 +774,4 @@ def new_action(self, action):
self.studio.new_action(action)

def widgets_modified(self, widgets):
self.studio.widgets_modified(widgets, None)
self.studio.widgets_modified(widgets, self)
Loading

0 comments on commit e076b62

Please sign in to comment.