def show_landmarks(self, widget): if not self.display_landmarks: return offset = widget.focus_region_width landmarks = self.geo_data.landmarks if not landmarks: return with widget.canvas: for x, y, size, name, label in landmarks: x, y = dp(x), dp(y) size = dp(size) x += offset if name: Color(1, 1, 1, .6) Rectangle(pos=(x - size / 2., y - size / 2.), size=(size, size), source=resource_find('{}.png'.format(name))) if label: label_wid = Label(text=label, pos=(x - size / 2., y + size / 2.), font_size=dp(15)) widget.add_widget(label_wid) def set_size(*largs, obj=label_wid, center=x): obj.size = obj.texture_size obj.center_x = center label_wid.fbind('texture_size', set_size)
class WidgetShape(ShowMoreBehavior, BoxLayout): '''The widget displayed for and associated with a :class:`ceed.shape.CeedShape` instance. ''' painter = ObjectProperty(None, rebind=True) '''The :class:`CeedPainter` this shape belongs to. ''' shape = ObjectProperty(None, rebind=True) '''The :class:`ceed.shape.CeedShape` instance associated with the widget. ''' label = None '''The label widget that displays the name of the shape in the center of the shape in the drawing area. ''' show_label = BooleanProperty(False) '''Whether :attr:`label` is currently displayed. ''' centroid_x = NumericProperty(0) '''The x center of the shape (e.g. the x-center of the polygon). ''' centroid_y = NumericProperty(0) '''The y center of the shape (e.g. the y-center of the polygon). ''' area = NumericProperty(0) '''The area in the shape (e.g. the area of the polygon). ''' selected = BooleanProperty(False) '''Whether the shape is :attr:`cplcom.painter.PaintShape.selected`. ''' _shape_update_trigger = None def __init__(self, **kwargs): super(WidgetShape, self).__init__(**kwargs) self.show_label = self.painter.show_label self.label = Label() trigger = Clock.create_trigger(self._shape_update, 0) self._shape_update_trigger = lambda *largs: trigger() and False @property def name(self): '''The :attr:`cplcom.painter.PaintShape.name` of the shape. ''' return self.shape.name def show_widget(self, index=None): '''Displays this widget in the list of shape widgets. ''' if index is None: knspace.shapes.add_widget(self) else: knspace.shapes.add_widget( self, index=len(knspace.shapes.children) - index) self.fbind('show_label', self._show_label) self.shape.fbind('name', self._label_text) f = self._shape_update_trigger self.shape.fbind('on_update', f) self.label.fbind('size', f) f() self._label_text() self._show_label() def hide_widget(self): '''Hides this widget from the list of shape widgets. ''' self.shape.funbind('on_update', self._shape_update_trigger) knspace.shapes.remove_widget(self) label = self.label label.funbind('size', self._shape_update_trigger) self.funbind('show_label', self._show_label) self.shape.funbind('name', self._label_text) self._show_label(force_hide=True) def _show_label(self, *largs, force_hide=False): '''Displays/hides the label in the shapes center containing the name of shape. ''' if self.show_label and not force_hide: if self.label.parent is not None: # already showing return self.painter.add_widget(self.label) self._shape_update_trigger() self._label_text() elif self.label.parent is not None: self.painter.remove_widget(self.label) def _label_text(self, *largs): '''Updates the :attr:`label` with the current name of the shape. ''' if self.show_label: self.label.text = self.shape.name def _show_more(self, *largs): '''Shows the settings ''' super(WidgetShape, self)._show_more(*largs) if self.show_more: self._shape_update_trigger() def _shape_update(self, *largs): '''Update the centroids and area when the shape is changed. ''' if not self.shape.finished: return self.centroid_x, self.centroid_y = tuple( map(round, self.shape.centroid)) self.area = round(self.shape.area) if self.show_label: self.label.center = self.shape.centroid def _update_centroid(self, x=None, y=None): '''Sets the centroid from the GUI. ''' x1, y1 = map(round, self.shape.centroid) dx = 0 if x is None else x - x1 dy = 0 if y is None else y - y1 if dx or dy: self.shape.translate(dpos=(dx, dy)) def _update_area(self, area): '''Sets the area from the GUI. ''' if not math.isclose(area, self.area): self.shape.set_area(area)
class WidgetShape(ShowMoreBehavior, BoxLayout): """The widget displayed for and associated with a :class:`~ceed.shape.CeedShape` instance. """ painter: CeedPainter = ObjectProperty(None, rebind=True) '''The :class:`CeedPainter` this shape belongs to. ''' shape: CeedShape = ObjectProperty(None, rebind=True) '''The :class:`~ceed.shape.CeedShape` instance associated with the widget. ''' label = None '''The label widget that displays the name of the shape in the center of the shape, in the drawing area, when enabled. ''' show_label = BooleanProperty(False) '''Whether :attr:`label` is currently displayed. ''' centroid_x = NumericProperty(0) '''The x center of the shape (e.g. the x-center of the polygon). ''' centroid_y = NumericProperty(0) '''The y center of the shape (e.g. the y-center of the polygon). ''' area = NumericProperty(0) '''The enclosed area of the shape (e.g. the area of the polygon). ''' selected = BooleanProperty(False) '''Whether the shape is :attr:`kivy_garden.painter.PaintShape.selected`. ''' _shape_update_trigger = None def __init__(self, **kwargs): super(WidgetShape, self).__init__(**kwargs) self.show_label = self.painter.show_label self.label = Label() trigger = Clock.create_trigger(self._shape_update, 0) self._shape_update_trigger = lambda *largs: trigger() and False @property def name(self): """The :attr:`kivy_garden.painter.PaintShape.name` of the shape. """ return self.shape.name def show_widget(self, index=None): """Displays this widget in the list of shape widgets at the given index. The index is in the same order as the shapes, i.e. zero is shape zero etc. """ if index is None: App.get_running_app().shapes_container.add_widget(self) else: App.get_running_app().shapes_container.add_widget( self, index=len( App.get_running_app().shapes_container.children) - index) self.fbind('show_label', self._show_label) self.shape.fbind('name', self._label_text) f = self._shape_update_trigger self.shape.fbind('on_update', f) self.label.fbind('size', f) f() self._label_text() self._show_label() def hide_widget(self): """Hides this widget from the list of shape widgets. """ self.shape.funbind('on_update', self._shape_update_trigger) App.get_running_app().shapes_container.remove_widget(self) label = self.label label.funbind('size', self._shape_update_trigger) self.funbind('show_label', self._show_label) self.shape.funbind('name', self._label_text) self._show_label(force_hide=True) def _show_label(self, *largs, force_hide=False): """Displays/hides the label in the shapes center containing the name of shape. """ if self.show_label and not force_hide: if self.label.parent is not None: # already showing return self.painter.add_widget(self.label) self._shape_update_trigger() self._label_text() elif self.label.parent is not None: self.painter.remove_widget(self.label) def _label_text(self, *largs): """Updates the :attr:`label` with the current name of the shape. """ if self.show_label: self.label.text = self.shape.name def _show_more(self, *largs): super(WidgetShape, self)._show_more(*largs) if self.show_more: self._shape_update_trigger() def _shape_update(self, *largs): """Update the centroids and area when the shape is changed. """ if not self.shape.finished: return self.centroid_x, self.centroid_y = tuple( map(round, self.shape.centroid)) self.area = round(self.shape.area) if self.show_label: self.label.center = self.shape.centroid def _update_centroid(self, x=None, y=None): """Sets the centroid from the GUI. """ x1, y1 = map(round, self.shape.centroid) dx = 0 if x is None else x - x1 dy = 0 if y is None else y - y1 if dx or dy: self.shape.translate(dpos=(dx, dy)) def _update_area(self, area): """Sets the area from the GUI. """ if not math.isclose(area, self.area): self.shape.set_area(area)