Cleanup
[carla.git] / source / frontend / patchcanvas / __init__.py
blob4c651cb326b9cb3e5bb5c183f5fbde50224edfb8
1 #!/usr/bin/env python3
2 # SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # ------------------------------------------------------------------------------------------------------------
6 # Imports (Global)
8 from qt_compat import qt_config
10 if qt_config == 5:
11 from PyQt5.QtCore import QPointF, QRectF
12 from PyQt5.QtWidgets import QGraphicsItem
13 elif qt_config == 6:
14 from PyQt6.QtCore import QPointF, QRectF
15 from PyQt6.QtWidgets import QGraphicsItem
17 # ------------------------------------------------------------------------------------------------------------
18 # Imports (Theme)
20 from .theme import getDefaultThemeName
22 # ------------------------------------------------------------------------------------------------------------
24 # Maximum Id for a plugin, treated as invalid/zero if above this value
25 MAX_PLUGIN_ID_ALLOWED = 0x7FF
27 # Port Mode
28 PORT_MODE_NULL = 0
29 PORT_MODE_INPUT = 1
30 PORT_MODE_OUTPUT = 2
32 # Port Type
33 PORT_TYPE_NULL = 0
34 PORT_TYPE_AUDIO_JACK = 1
35 PORT_TYPE_MIDI_JACK = 2
36 PORT_TYPE_MIDI_ALSA = 3
37 PORT_TYPE_PARAMETER = 4
39 # Callback Action
40 ACTION_GROUP_INFO = 0 # group_id, N, N
41 ACTION_GROUP_RENAME = 1 # group_id, N, N
42 ACTION_GROUP_SPLIT = 2 # group_id, N, N
43 ACTION_GROUP_JOIN = 3 # group_id, N, N
44 ACTION_GROUP_POSITION = 4 # group_id, N, N, "x1:y1:x2:y2"
45 ACTION_PORT_INFO = 5 # group_id, port_id, N
46 ACTION_PORT_RENAME = 6 # group_id, port_id, N
47 ACTION_PORTS_CONNECT = 7 # N, N, "outG:outP:inG:inP"
48 ACTION_PORTS_DISCONNECT = 8 # conn_id, N, N
49 ACTION_PLUGIN_CLONE = 9 # plugin_id, N, N
50 ACTION_PLUGIN_EDIT = 10 # plugin_id, N, N
51 ACTION_PLUGIN_RENAME = 11 # plugin_id, N, N
52 ACTION_PLUGIN_REPLACE = 12 # plugin_id, N, N
53 ACTION_PLUGIN_REMOVE = 13 # plugin_id, N, N
54 ACTION_PLUGIN_SHOW_UI = 14 # plugin_id, N, N
55 ACTION_BG_RIGHT_CLICK = 15 # N, N, N
56 ACTION_INLINE_DISPLAY = 16 # plugin_id, N, N
58 # Icon
59 ICON_APPLICATION = 0
60 ICON_HARDWARE = 1
61 ICON_DISTRHO = 2
62 ICON_FILE = 3
63 ICON_PLUGIN = 4
64 ICON_LADISH_ROOM = 5
66 # Split Option
67 SPLIT_UNDEF = 0
68 SPLIT_NO = 1
69 SPLIT_YES = 2
71 # Antialiasing Option
72 ANTIALIASING_NONE = 0
73 ANTIALIASING_SMALL = 1
74 ANTIALIASING_FULL = 2
76 # Eye-Candy Option
77 EYECANDY_NONE = 0
78 EYECANDY_SMALL = 1
79 EYECANDY_FULL = 2
81 # ------------------------------------------------------------------------------------------------------------
83 # object types
84 CanvasBoxType = QGraphicsItem.UserType + 1
85 CanvasIconType = QGraphicsItem.UserType + 2
86 CanvasPortType = QGraphicsItem.UserType + 3
87 CanvasLineType = QGraphicsItem.UserType + 4
88 CanvasBezierLineType = QGraphicsItem.UserType + 5
89 CanvasLineMovType = QGraphicsItem.UserType + 6
90 CanvasBezierLineMovType = QGraphicsItem.UserType + 7
91 CanvasRubberbandType = QGraphicsItem.UserType + 8
93 # ------------------------------------------------------------------------------------------------------------
95 # Canvas options
96 class options_t(object):
97 __slots__ = [
98 'theme_name',
99 'auto_hide_groups',
100 'auto_select_items',
101 'use_bezier_lines',
102 'antialiasing',
103 'eyecandy',
104 'inline_displays'
107 # Canvas features
108 class features_t(object):
109 __slots__ = [
110 'group_info',
111 'group_rename',
112 'port_info',
113 'port_rename',
114 'handle_group_pos'
117 # Main Canvas object
118 class Canvas(object):
119 def __init__(self):
120 self.qobject = None
121 self.settings = None
122 self.theme = None
123 self.initiated = False
125 self.group_list = []
126 self.port_list = []
127 self.connection_list = []
128 self.animation_list = []
129 self.group_plugin_map = {}
130 self.old_group_pos = {}
132 self.callback = self.callback
133 self.debug = False
134 self.scene = None
135 self.last_z_value = 0
136 self.last_connection_id = 0
137 self.initial_pos = QPointF(0, 0)
138 self.size_rect = QRectF()
140 def callback(self, action, value1, value2, value_str):
141 print("Canvas::callback({}, {}, {}, {})".format(action, value1, value2, value_str))
143 # ------------------------------------------------------------------------------------------------------------
145 # object lists
146 class group_dict_t(object):
147 __slots__ = [
148 'group_id',
149 'group_name',
150 'split',
151 'icon',
152 'plugin_id',
153 'plugin_ui',
154 'plugin_inline',
155 'widgets'
158 class port_dict_t(object):
159 __slots__ = [
160 'group_id',
161 'port_id',
162 'port_name',
163 'port_mode',
164 'port_type',
165 'is_alternate',
166 'widget'
169 class connection_dict_t(object):
170 __slots__ = [
171 'connection_id',
172 'group_in_id',
173 'port_in_id',
174 'group_out_id',
175 'port_out_id',
176 'widget'
179 class animation_dict_t(object):
180 __slots__ = [
181 'animation',
182 'item'
185 # ------------------------------------------------------------------------------------------------------------
187 # Internal functions
188 def bool2str(check):
189 return "True" if check else "False"
191 def port_mode2str(port_mode):
192 if port_mode == PORT_MODE_NULL:
193 return "PORT_MODE_NULL"
194 elif port_mode == PORT_MODE_INPUT:
195 return "PORT_MODE_INPUT"
196 elif port_mode == PORT_MODE_OUTPUT:
197 return "PORT_MODE_OUTPUT"
198 else:
199 return "PORT_MODE_???"
201 def port_type2str(port_type):
202 if port_type == PORT_TYPE_NULL:
203 return "PORT_TYPE_NULL"
204 elif port_type == PORT_TYPE_AUDIO_JACK:
205 return "PORT_TYPE_AUDIO_JACK"
206 elif port_type == PORT_TYPE_MIDI_JACK:
207 return "PORT_TYPE_MIDI_JACK"
208 elif port_type == PORT_TYPE_MIDI_ALSA:
209 return "PORT_TYPE_MIDI_ALSA"
210 elif port_type == PORT_TYPE_PARAMETER:
211 return "PORT_TYPE_MIDI_PARAMETER"
212 else:
213 return "PORT_TYPE_???"
215 def icon2str(icon):
216 if icon == ICON_APPLICATION:
217 return "ICON_APPLICATION"
218 elif icon == ICON_HARDWARE:
219 return "ICON_HARDWARE"
220 elif icon == ICON_DISTRHO:
221 return "ICON_DISTRHO"
222 elif icon == ICON_FILE:
223 return "ICON_FILE"
224 elif icon == ICON_PLUGIN:
225 return "ICON_PLUGIN"
226 elif icon == ICON_LADISH_ROOM:
227 return "ICON_LADISH_ROOM"
228 else:
229 return "ICON_???"
231 def split2str(split):
232 if split == SPLIT_UNDEF:
233 return "SPLIT_UNDEF"
234 elif split == SPLIT_NO:
235 return "SPLIT_NO"
236 elif split == SPLIT_YES:
237 return "SPLIT_YES"
238 else:
239 return "SPLIT_???"
241 # ------------------------------------------------------------------------------------------------------------
243 # Global objects
244 canvas = Canvas()
246 options = options_t()
247 options.theme_name = getDefaultThemeName()
248 options.auto_hide_groups = False
249 options.auto_select_items = False
250 options.use_bezier_lines = True
251 options.antialiasing = ANTIALIASING_SMALL
252 options.eyecandy = EYECANDY_SMALL
253 options.inline_displays = False
255 features = features_t()
256 features.group_info = False
257 features.group_rename = False
258 features.port_info = False
259 features.port_rename = False
260 features.handle_group_pos = False
262 # PatchCanvas API
263 def setOptions(new_options):
264 if canvas.initiated: return
265 options.theme_name = new_options.theme_name
266 options.auto_hide_groups = new_options.auto_hide_groups
267 options.auto_select_items = new_options.auto_select_items
268 options.use_bezier_lines = new_options.use_bezier_lines
269 options.antialiasing = new_options.antialiasing
270 options.eyecandy = new_options.eyecandy
271 options.inline_displays = new_options.inline_displays
273 def setFeatures(new_features):
274 if canvas.initiated: return
275 features.group_info = new_features.group_info
276 features.group_rename = new_features.group_rename
277 features.port_info = new_features.port_info
278 features.port_rename = new_features.port_rename
279 features.handle_group_pos = new_features.handle_group_pos