1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3
4# PatchBay Canvas engine using QGraphicsView/Scene
5# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of
10# the License, or any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# For a full copy of the GNU General Public License see the doc/GPL.txt file.
18
19# ------------------------------------------------------------------------------------------------------------
20# Imports (Global)
21
22from PyQt5.QtCore import qCritical, QPointF, QTimer
23
24# ------------------------------------------------------------------------------------------------------------
25# Imports (Custom)
26
27from . import bool2str, canvas, CanvasBoxType
28from .canvasfadeanimation import CanvasFadeAnimation
29
30# ------------------------------------------------------------------------------------------------------------
31
32def CanvasGetNewGroupPos(horizontal):
33    if canvas.debug:
34        print("PatchCanvas::CanvasGetNewGroupPos(%s)" % bool2str(horizontal))
35
36    new_pos = QPointF(canvas.initial_pos)
37    items = canvas.scene.items()
38
39    #break_loop = False
40    while True:
41        break_for = False
42        for i, item in enumerate(items):
43            if item and item.type() == CanvasBoxType:
44                if item.sceneBoundingRect().adjusted(-5, -5, 5, 5).contains(new_pos):
45                    itemRect = item.boundingRect()
46                    if horizontal:
47                        new_pos += QPointF(itemRect.width() + 50, 0)
48                    else:
49                        itemHeight = itemRect.height()
50                        if itemHeight < 30:
51                            new_pos += QPointF(0, itemHeight + 50)
52                        else:
53                            new_pos.setY(item.scenePos().y() + itemHeight + 20)
54                    break_for = True
55                    break
56        else:
57            if not break_for:
58                break
59            #break_loop = True
60
61    return new_pos
62
63def CanvasGetFullPortName(group_id, port_id):
64    if canvas.debug:
65        print("PatchCanvas::CanvasGetFullPortName(%i, %i)" % (group_id, port_id))
66
67    for port in canvas.port_list:
68        if port.group_id == group_id and port.port_id == port_id:
69            group_id = port.group_id
70            for group in canvas.group_list:
71                if group.group_id == group_id:
72                    return group.group_name + ":" + port.port_name
73            break
74
75    qCritical("PatchCanvas::CanvasGetFullPortName(%i, %i) - unable to find port" % (group_id, port_id))
76    return ""
77
78def CanvasGetPortConnectionList(group_id, port_id):
79    if canvas.debug:
80        print("PatchCanvas::CanvasGetPortConnectionList(%i, %i)" % (group_id, port_id))
81
82    conn_list = []
83
84    for connection in canvas.connection_list:
85        if connection.group_out_id == group_id and connection.port_out_id == port_id:
86            conn_list.append((connection.connection_id, connection.group_in_id, connection.port_in_id))
87        elif connection.group_in_id == group_id and connection.port_in_id == port_id:
88            conn_list.append((connection.connection_id, connection.group_out_id, connection.port_out_id))
89
90    return conn_list
91
92def CanvasCallback(action, value1, value2, value_str):
93    if canvas.debug:
94        print("PatchCanvas::CanvasCallback(%i, %i, %i, %s)" % (action, value1, value2, value_str.encode()))
95
96    canvas.callback(action, value1, value2, value_str)
97
98def CanvasItemFX(item, show, destroy):
99    if canvas.debug:
100        print("PatchCanvas::CanvasItemFX(%s, %s, %s)" % (item, bool2str(show), bool2str(destroy)))
101
102    # Check if the item already has an animation
103    for animation in canvas.animation_list:
104        if animation.item() == item:
105            animation.forceStop()
106            canvas.animation_list.remove(animation)
107            del animation
108            break
109
110    animation = CanvasFadeAnimation(item, show)
111    animation.setDuration(750 if show else 500)
112
113    if show:
114        animation.finished.connect(canvas.qobject.AnimationFinishedShow)
115    else:
116        if destroy:
117            animation.finished.connect(canvas.qobject.AnimationFinishedDestroy)
118        else:
119            animation.finished.connect(canvas.qobject.AnimationFinishedHide)
120
121    canvas.animation_list.append(animation)
122
123    animation.start()
124
125def CanvasRemoveItemFX(item):
126    if canvas.debug:
127        print("PatchCanvas::CanvasRemoveItemFX(%s)" % item)
128
129    if item.type() == CanvasBoxType:
130        item.removeIconFromScene()
131
132    canvas.scene.removeItem(item)
133    del item
134
135    QTimer.singleShot(0, canvas.scene.update)
136
137# ------------------------------------------------------------------------------------------------------------
138