Beispiel #1
0
 def get_ref_value(cls, shape, ref_key, ref=None):
     ''' computes reference-values (minimum, maxium) for adjustments depending on ref-key '''
     if ref != None and type(ref_key) in [int, float]:
         value = ref_key * ref
     elif ref_key == 'deg':
         value = cm_to_pt(
             1
         )  #convert to pt as setter/getter are converting back -> "double conversion"
     elif ref_key == 'h':
         value = shape.Height
     elif ref_key == 'h/2':
         value = shape.Height / 2
     elif ref_key == 'h/4':
         value = shape.Height / 4
     elif ref_key == 'w':
         value = shape.Width
     elif ref_key == 'w/2':
         value = shape.Width / 2
     elif ref_key == 'min(hw)/2':
         value = min(shape.height, shape.width) / 2
     elif ref_key == 'min(hw)*2':
         value = min(shape.height, shape.width) * 2
     elif ref_key == 'min(hw)':
         value = min(shape.height, shape.width)
     else:
         value = None
     return value
Beispiel #2
0
class SplitShapes(object):
    default_row_sep = cm_to_pt(0.2)
    default_col_sep = cm_to_pt(0.2)
    default_rows = 6
    default_cols = 6

    @classmethod
    def split_shapes(cls, shapes, rows, cols, row_sep, col_sep):
        for shape in shapes:
            cls.split_shape(shape, rows, cols, row_sep, col_sep)

    @classmethod
    def split_shape(cls, shape, rows, cols, row_sep, col_sep):
        shape_width = shape.width
        shape_height = shape.height
        if cols > 1:
            shape_width = (shape.width - (cols - 1) * col_sep) / cols
        if rows > 1:
            shape_height = (shape.height - (rows - 1) * row_sep) / rows

        #shape.width = shape_width
        #shape.height = shape_height

        last_lock_aspect_ratio = shape.LockAspectRatio
        shape.LockAspectRatio = 0

        for row_idx in range(rows):
            for col_idx in range(cols):
                if row_idx == 0 and col_idx == 0:
                    shape_copy = shape
                else:
                    shape_copy = shape.duplicate()
                shape_copy.left = shape.left + col_idx * (shape_width +
                                                          col_sep)
                shape_copy.top = shape.top + row_idx * (shape_height + row_sep)
                shape_copy.width = shape_width
                shape_copy.height = shape_height
                shape_copy.LockAspectRatio = last_lock_aspect_ratio
                shape_copy.select(False)
Beispiel #3
0
 def set_adjustment(cls, shape, num, value):
     ''' sets n's adjustment of shape, where value is assumed to be cm-value '''
     if cls.get_shape_type(
             shape
     ) in cls.allowed_shape_types and shape.adjustments.count >= num:
         if type(value) == str:
             value = float(value.replace(',', '.'))
         # if cls.get_shape_autotype(shape) in cls.auto_shape_type_settings.keys():
         try:
             ref, minimum, maximum = cls.get_ref_min_max(shape, num)
             pt_value = cm_to_pt(value)
             logging.debug('shape adjustment pt value=%s' % pt_value)
             if minimum != None:
                 pt_value = max(minimum, pt_value)
             if maximum != None:
                 pt_value = min(maximum, pt_value)
             shape.adjustments.item[num] = pt_value / ref
         # else:
         except (
                 KeyError, IndexError
         ):  #KeyError = shape type is not in database, IndexError = adjustment number is not in database
             shape.adjustments.item[num] = value / 100
Beispiel #4
0
 def split_shapes(self, sender, event):
     SplitShapes.split_shapes(self.ref_shapes, self._vm.rows,
                              self._vm.columns, cm_to_pt(self._vm.rowsep),
                              cm_to_pt(self._vm.columnsep))
     self.Close()
Beispiel #5
0
 def multiply_shapes(self, sender, event):
     MultiplyShapes.multiply_shapes(self.ref_shapes, self._vm.rows,
                                    self._vm.columns,
                                    cm_to_pt(self._vm.rowsep),
                                    cm_to_pt(self._vm.columnsep))
     self.Close()
Beispiel #6
0
class CircularArrangement(object):
    DEBUG = False

    midpoint = [0, 0]

    rotated = False
    fixed_radius = False
    centerpoint = False

    width = cm_to_pt(10.0)
    height = cm_to_pt(8.5)
    segment_start = 0

    @classmethod
    def _draw_debug_point(cls, shape, point, text=None):
        if not cls.DEBUG:
            return
        dot = shape.parent.shapes.addshape(
            9,  #msoShapeOval
            point[0] - 5,
            point[1] - 5,
            10,
            10)
        dot.TextFrame2.TextRange.Font.Size = 8
        if text:
            dot.TextFrame2.TextRange.Text = text

    @classmethod
    def _draw_debug_circle(cls, shape, point, width, height):
        if not cls.DEBUG:
            return
        dot = shape.parent.shapes.addshape(
            9,  #msoShapeOval
            point[0] - width / 2,
            point[1] - height / 2,
            width,
            height)
        dot.fill.visible = 0
        dot.line.ForeColor.RGB = 255

    @classmethod
    def arrange_circular(cls, shapes):
        midpoint, width, height, segment_start = cls.get_ellipse_params(shapes)
        cls.arrange_circular_wargs(shapes, midpoint, width, height,
                                   segment_start)

    @classmethod
    def get_ellipse_params(cls, shapes):
        # compute weightend midpoint
        # shape_midpoints = [ [s.left+s.width/2.0, s.top+s.height/2.0] for s in shapes]
        # cls.midpoint = algorithms.mid_point(shape_midpoints)
        cls.midpoint = algorithms.mid_point_shapes(shapes)

        if cls.fixed_radius:
            cls.height = cls.width

        return (cls.midpoint, cls.width, cls.height, cls.segment_start)

    @classmethod
    def determine_ellipse_params(cls, shapes):
        # compute weightend midpoint
        shape_midpoints = [[s.left + s.width / 2, s.top + s.height / 2]
                           for s in shapes]
        cls.midpoint = algorithms.mid_point(shape_midpoints)

        # compute if centerpoint exists
        if algorithms.is_close(shape_midpoints[0][0], cls.midpoint[0],
                               0.1) and algorithms.is_close(
                                   shape_midpoints[0][1], cls.midpoint[1],
                                   0.1):
            cls.centerpoint = True
            #exclude centerpoint from further calculations
            del shape_midpoints[0]
            shapes = shapes[1:]
        else:
            cls.centerpoint = False

        # compute all vectors from midpoints to shapes
        vectors = [[sm[0] - cls.midpoint[0], sm[1] - cls.midpoint[1]]
                   for sm in shape_midpoints]

        # interpolate segment start (angle to frist vector)
        cls.segment_start = math.degrees(
            math.atan2(vectors[0][1], vectors[0][0]) +
            math.pi / 2)  #add pi/2 as 90° is subtracted in determine_points
        if cls.segment_start <= 0:
            cls.segment_start = (
                360 + cls.segment_start) % 360  #ensure positive value

        # interpolate radius as max for each vector part
        cls.width = max([v[0] for v in vectors]) * 2
        cls.height = max([v[1] for v in vectors]) * 2

        # # determine points
        # points = cls.determine_points(shapes, cls.midpoint, 2, 2, 90)

        # # compute radius
        # # x-stretch faktor for every point
        # factors = [ 1.0* (shape_midpoints[i][0]-cls.midpoint[0])/(points[i][0]-cls.midpoint[0])  for i in range(0, len(shapes)) if (points[i][0]-cls.midpoint[0]) != 0]
        # # middle strech factor
        # radius_x = sum(factors)/len(factors)
        # cls.width = 2*radius_x

        # # y-stretch faktor for every point
        # factors = [ 1.0* (shape_midpoints[i][1]-cls.midpoint[1])/(points[i][1]-cls.midpoint[1])  for i in range(0, len(shapes)) if (points[i][1]-cls.midpoint[1]) != 0]
        # # middle strech factor
        # radius_y = sum(factors)/len(factors)
        # cls.height = 2*radius_y

        # compute options
        cls.fixed_radius = algorithms.is_close(cls.height, cls.width, 0.1)
        cls.rotated = any(shapes[0].rotation != s.rotation for s in shapes)

        #debug drawings
        cls._draw_debug_circle(shapes[0], cls.midpoint, cls.width, cls.height)
        cls._draw_debug_point(shapes[0], cls.midpoint, "C")
        cls._draw_debug_point(shapes[0], shape_midpoints[0], "1")

        return (cls.midpoint, cls.width, cls.height, cls.segment_start)

    @classmethod
    def set_circ_width(cls, shapes, value):
        value = float(max(0, value))
        cls.width = value
        if cls.fixed_radius:
            cls.height = value
        cls.arrange_circular(shapes)

    @classmethod
    def get_circ_width(cls, shapes):
        return cls.width

    @classmethod
    def set_circ_height(cls, shapes, value):
        value = float(max(0, value))
        cls.height = value
        if cls.fixed_radius:
            cls.width = value
        cls.arrange_circular(shapes)

    @classmethod
    def get_circ_height(cls, shapes):
        return cls.height

    @classmethod
    def get_segment_start(cls, shapes):
        return round(cls.segment_start, 1)

    @classmethod
    def set_segment_start(cls, shapes, value):
        #ensure that value is positive and between 0 and 359
        cls.segment_start = value if 0 <= value < 360 else (360 + value) % 360
        cls.arrange_circular(shapes)

    @classmethod
    def determine_points(cls, shapes, midpoint, width, height, segment_start):
        # # Nullpunkt als Mittelpunkt verwenden, mit Radius 1
        # segments = bezier.kreisSegmente(len(shapes), 1, [0,0])
        # points = [ [s[0][0][0], s[0][0][1]] for s in segments]

        # # Segments starten rechts im Kreis
        # # Alle Punkte um 90 Grad nach links drehen, damit erstes Objekt oben steht
        # cls._draw_debug_point(shapes[0], midpoint, "C")
        # cls._draw_debug_point(shapes[0], points[0], "A")
        # points = [ algorithms.rotate_point(p[0], p[1], 0, 0, segment_start)  for p in points]
        # cls._draw_debug_point(shapes[0], points[0], "B")

        # # Punkte skalieren (Höhe/Breite)
        # points = [ [ width/2 * p[0], height/2 * p[1] ]   for p in points]

        # # Punkte verschieben anhand midpoint
        # points = [ [ p[0] + midpoint[0], p[1] + midpoint[1] ]   for p in points]

        # if centerpoint-shape is active, lead first shape out for remaining calculation
        if cls.centerpoint:
            shapes = shapes[1:]

        points = algorithms.get_ellipse_points(len(shapes), width / 2.0,
                                               height / 2.0,
                                               segment_start - 90, midpoint)
        return points

    @classmethod
    def arrange_circular_wargs(cls, shapes, midpoint, width, height,
                               segment_start):
        points = cls.determine_points(shapes, midpoint, width, height,
                                      segment_start)

        if cls.centerpoint:
            center_shape = shapes.pop(0)
            center_shape.left = midpoint[0] - center_shape.width / 2
            center_shape.top = midpoint[1] - center_shape.height / 2

        for i in range(0, len(shapes)):
            shapes[i].left = points[i][0] - shapes[i].width / 2
            shapes[i].top = points[i][1] - shapes[i].height / 2

            if cls.rotated:
                shapes[i].rotation = (360 / len(shapes) * i +
                                      segment_start) % 360
            else:
                shapes[i].rotation = shapes[0].rotation

    @classmethod
    def arrange_circular_rotated(cls, pressed):
        cls.rotated = pressed

    @classmethod
    def arrange_circular_rotated_pressed(cls):
        return cls.rotated

    @classmethod
    def arrange_circular_fixed(cls, pressed):
        cls.fixed_radius = pressed

    @classmethod
    def arrange_circular_fixed_pressed(cls):
        return cls.fixed_radius

    @classmethod
    def arrange_circular_centerpoint(cls, pressed):
        cls.centerpoint = pressed

    @classmethod
    def arrange_circular_centerpoint_pressed(cls):
        return cls.centerpoint