"Fossies" - the Fresh Open Source Software Archive

Member "sk1-2.0rc4/src/sk1/document/controllers/editor_polygon.py" (25 May 2019, 8309 Bytes) of package /linux/misc/sk1-2.0rc4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "editor_polygon.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.0rc3_vs_2.0rc4.

    1 # -*- coding: utf-8 -*-
    2 #
    3 #  Copyright (C) 2015 by Igor E. Novikov
    4 #
    5 #  This program is free software: you can redistribute it and/or modify
    6 #  it under the terms of the GNU General Public License as published by
    7 #  the Free Software Foundation, either version 3 of the License, or
    8 #  (at your option) any later version.
    9 #
   10 #  This program is distributed in the hope that it will be useful,
   11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13 #  GNU General Public License for more details.
   14 #
   15 #  You should have received a copy of the GNU General Public License
   16 #  along with this program.  If not, see <https://www.gnu.org/licenses/>.
   17 
   18 import math
   19 
   20 from uc2 import libgeom
   21 
   22 from sk1 import _, modes, config, events
   23 from generic import AbstractController
   24 
   25 
   26 class PolygonEditor(AbstractController):
   27     mode = modes.POLYGON_EDITOR_MODE
   28     target = None
   29 
   30     corner_points = []
   31     midpoints = []
   32 
   33     orig_angle1 = 0.0
   34     orig_angle2 = 0.0
   35     orig_coef1 = 1.0
   36     orig_coef2 = 1.0
   37 
   38     midpoint_index = None
   39     corner_index = None
   40     selected_obj = None
   41 
   42     def __init__(self, canvas, presenter):
   43         AbstractController.__init__(self, canvas, presenter)
   44 
   45     def start_(self):
   46         self.snap = self.presenter.snap
   47         self.target = self.selection.objs[0]
   48         self.selected_obj = None
   49         self.api.set_mode()
   50         self.update_points()
   51         self.selection.clear()
   52         msg = _('Polygon in editing')
   53         events.emit(events.APP_STATUS, msg)
   54 
   55     def stop_(self):
   56         self.selection.set([self.target, ])
   57         self.target = None
   58         self.selected_obj = None
   59 
   60     def escape_pressed(self):
   61         self.canvas.set_mode()
   62 
   63     def store_props(self):
   64         self.orig_angle1 = self.target.angle1
   65         self.orig_angle2 = self.target.angle2
   66         self.orig_coef1 = self.target.coef1
   67         self.orig_coef2 = self.target.coef2
   68 
   69     def update_points(self):
   70         self.corner_points = []
   71         self.midpoints = []
   72         coef1 = self.target.coef1
   73         coef2 = self.target.coef2
   74         angle1 = self.target.angle1
   75         angle2 = self.target.angle2
   76         corners_num = self.target.corners_num
   77         center = [0.5, 0.5]
   78         corner_angle = 2.0 * math.pi / float(corners_num)
   79         corners_start = [0.5, 0.5 + 0.5 * coef1]
   80         midpoint_start = [0.5, 0.5 + 0.5 * coef2 * math.cos(corner_angle / 2.0)]
   81 
   82         corner_angle_shift = angle1
   83         midpoint_angle_shift = corner_angle / 2.0 + angle2
   84 
   85         for i in range(0, corners_num):
   86             angle = float(i) * corner_angle + corner_angle_shift
   87             point = libgeom.rotate_point(center, corners_start, angle)
   88             self.corner_points.append(CornerPoint(self.canvas,
   89                                                   self.target, point, i))
   90 
   91             angle = float(i) * corner_angle + midpoint_angle_shift
   92             point = libgeom.rotate_point(center, midpoint_start, angle)
   93             self.midpoints.append(CornerPoint(self.canvas,
   94                                               self.target, point, i))
   95         msg = _('Polygon in editing')
   96         events.emit(events.APP_STATUS, msg)
   97 
   98     # ----- REPAINT
   99     def repaint(self):
  100         x0, y0, x1, y1 = self.target.cache_bbox
  101         p0 = self.canvas.point_doc_to_win([x0, y0])
  102         p1 = self.canvas.point_doc_to_win([x1, y1])
  103         self.canvas.renderer.draw_frame(p0, p1)
  104         for item in self.corner_points:
  105             item.repaint()
  106         for item in self.midpoints:
  107             item.repaint()
  108 
  109     # ----- CHANGE APPLY
  110     def apply_corner_change(self, point, index, control=False, final=False):
  111         wpoint = self.canvas.point_win_to_doc(point)
  112         invtrafo = libgeom.invert_trafo(self.target.trafo)
  113         x, y = libgeom.apply_trafo_to_point(wpoint, invtrafo)
  114         radius = self.target.get_corner_radius()
  115         angle = self.target.get_corner_angle(index)
  116         coef1 = libgeom.get_point_radius([x, y]) / radius
  117         if control:
  118             props = [self.orig_angle1, self.orig_angle2,
  119                      coef1, self.orig_coef2]
  120         else:
  121             angle1 = libgeom.get_point_angle([x, y]) - angle
  122             props = [angle1, self.orig_angle2,
  123                      coef1, self.orig_coef2]
  124         if final:
  125             props_before = [self.orig_angle1, self.orig_angle2,
  126                             self.orig_coef1, self.orig_coef2]
  127             self.api.set_polygon_properties_final(props, props_before,
  128                                                   self.target)
  129         else:
  130             self.api.set_polygon_properties(props, self.target)
  131         self.update_points()
  132 
  133     def apply_midpoint_change(self, point, index, control=False, final=False):
  134         wpoint = self.canvas.point_win_to_doc(point)
  135         invtrafo = libgeom.invert_trafo(self.target.trafo)
  136         x, y = libgeom.apply_trafo_to_point(wpoint, invtrafo)
  137         radius = self.target.get_midpoint_radius()
  138         angle = self.target.get_midpoint_angle(index)
  139         coef2 = libgeom.get_point_radius([x, y]) / radius
  140         if control:
  141             props = [self.orig_angle1, self.orig_angle2,
  142                      self.orig_coef1, coef2]
  143         else:
  144             angle2 = libgeom.get_point_angle([x, y]) - angle
  145             props = [self.orig_angle1, angle2,
  146                      self.orig_coef1, coef2]
  147         if final:
  148             props_before = [self.orig_angle1, self.orig_angle2,
  149                             self.orig_coef1, self.orig_coef2]
  150             self.api.set_polygon_properties_final(props, props_before,
  151                                                   self.target)
  152         else:
  153             self.api.set_polygon_properties(props, self.target)
  154         self.update_points()
  155 
  156     # ----- MOUSE CONTROLLING
  157     def mouse_down(self, event):
  158         self.selected_obj = None
  159         self.corner_index = None
  160         self.midpoint_index = None
  161         for item in self.corner_points:
  162             if item.is_pressed(event.get_point()):
  163                 self.corner_index = item.index
  164                 self.store_props()
  165                 return
  166         for item in self.midpoints:
  167             if item.is_pressed(event.get_point()):
  168                 self.midpoint_index = item.index
  169                 self.store_props()
  170                 return
  171         objs = self.canvas.pick_at_point(event.get_point())
  172         if objs and not objs[0] == self.target and objs[0].is_primitive:
  173             self.selected_obj = objs[0]
  174 
  175     def mouse_up(self, event):
  176         if self.corner_index is not None:
  177             self.apply_corner_change(event.get_point(), self.corner_index,
  178                                      event.is_ctrl(), True)
  179             self.corner_index = None
  180         elif self.midpoint_index is not None:
  181             self.apply_midpoint_change(event.get_point(), self.midpoint_index,
  182                                        event.is_ctrl(), True)
  183             self.midpoint_index = None
  184         elif self.selected_obj:
  185             self.target = self.selected_obj
  186             self.selected_obj = None
  187             self.canvas.set_mode(modes.SHAPER_MODE)
  188 
  189     def mouse_move(self, event):
  190         if self.corner_index is not None:
  191             self.apply_corner_change(event.get_point(), self.corner_index,
  192                                      event.is_ctrl())
  193         elif self.midpoint_index is not None:
  194             self.apply_midpoint_change(event.get_point(), self.midpoint_index,
  195                                        event.is_ctrl())
  196 
  197 
  198 class CornerPoint:
  199     canvas = None
  200     target = None
  201     point = []
  202     index = 0
  203 
  204     def __init__(self, canvas, target, point, index):
  205         self.canvas = canvas
  206         self.target = target
  207         self.point = point
  208         self.index = index
  209 
  210     def get_point(self):
  211         return libgeom.apply_trafo_to_point(self.point, self.target.trafo)
  212 
  213     def get_screen_point(self):
  214         return self.canvas.point_doc_to_win(self.get_point())
  215 
  216     def is_pressed(self, win_point):
  217         wpoint = self.canvas.point_doc_to_win(self.get_point())
  218         bbox = libgeom.bbox_for_point(wpoint, config.point_sensitivity_size)
  219         return libgeom.is_point_in_bbox(win_point, bbox)
  220 
  221     def repaint(self):
  222         self.canvas.renderer.draw_polygon_point(self.get_screen_point())