1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
21 from bpy
.props
import (
30 from .ui_panels
import GP_PT_sidebarPanel
32 def get_addon_prefs():
34 addon_name
= os
.path
.splitext(__name__
)[0]
35 addon_prefs
= bpy
.context
.preferences
.addons
[addon_name
].preferences
38 from .timeline_scrub
import GPTS_timeline_settings
, draw_ts_pref
40 ## Addons Preferences Update Panel
41 def update_panel(self
, context
):
43 bpy
.utils
.unregister_class(GP_PT_sidebarPanel
)
46 GP_PT_sidebarPanel
.bl_category
= get_addon_prefs().category
47 bpy
.utils
.register_class(GP_PT_sidebarPanel
)
49 ## keymap binder for rotate canvas
50 def auto_rebind(self
, context
):
54 class GreasePencilAddonPrefs(bpy
.types
.AddonPreferences
):
55 bl_idname
= os
.path
.splitext(__name__
)[0] #'greasepencil-addon' ... __package__ ?
56 # bl_idname = __name__
58 ts
: PointerProperty(type=GPTS_timeline_settings
)
60 category
: StringProperty(
62 description
="Choose a name for the category of the panel",
63 default
="Grease Pencil",
67 use_clic_drag
: BoolProperty(
68 name
='Use click drag directly on points',
69 description
="Change the active tool to 'tweak' during modal, Allow to direct clic-drag points of the box",
72 default_deform_type
: EnumProperty(
73 items
=(('KEY_LINEAR', "Linear (perspective mode)", "Linear interpolation, like corner deform / perspective tools of classic 2D", 'IPO_LINEAR',0),
74 ('KEY_BSPLINE', "Spline (smooth deform)", "Spline interpolation transformation\nBest when lattice is subdivided", 'IPO_CIRC',1),
76 name
='Starting Interpolation', default
='KEY_LINEAR', description
='Choose default interpolation when entering mode')
78 # About interpolation : https://docs.blender.org/manual/en/2.83/animation/shape_keys/shape_keys_panel.html#fig-interpolation-type
80 auto_swap_deform_type
: BoolProperty(
81 name
='Auto swap interpolation mode',
82 description
="Automatically set interpolation to 'spline' when subdividing lattice\n Back to 'linear' when",
85 ## rotate canvas variables
88 canvas_use_hud
: BoolProperty(
90 description
= "Display angle lines and angle value as text on viewport",
93 canvas_use_view_center
: BoolProperty(
94 name
= "Rotate From View Center In Camera",
95 description
= "Rotate from view center in camera view, Else rotate from camera center",
99 canvas_use_shortcut
: BoolProperty(
100 name
= "Use Default Shortcut",
101 description
= "Use default shortcut: mouse double-click + modifier",
105 mouse_click
: EnumProperty(
106 name
="Mouse button", description
="click on right/left/middle mouse button in combination with a modifier to trigger alignement",
107 default
='MIDDLEMOUSE',
109 ('RIGHTMOUSE', 'Right click', 'Use click on Right mouse button', 'MOUSE_RMB', 0),
110 ('LEFTMOUSE', 'Left click', 'Use click on Left mouse button', 'MOUSE_LMB', 1),
111 ('MIDDLEMOUSE', 'Mid click', 'Use click on Mid mouse button', 'MOUSE_MMB', 2),
115 use_shift
: BoolProperty(
116 name
= "combine with shift",
117 description
= "add shift",
121 use_alt
: BoolProperty(
122 name
= "combine with alt",
123 description
= "add alt",
127 use_ctrl
: BoolProperty(
128 name
= "combine with ctrl",
129 description
= "add ctrl",
133 rc_angle_step
: FloatProperty(
135 description
="Step the rotation using this angle when using rotate canvas step modifier",
136 default
=0.2617993877991494, # 15
137 min=0.01745329238474369, # 1
138 max=3.1415927410125732, # 180
139 soft_min
=0.01745329238474369, # 1
140 soft_max
=1.5707963705062866, # 90
141 step
=10, precision
=1, subtype
='ANGLE', unit
='ROTATION')
143 def draw(self
, context
):
144 prefs
= get_addon_prefs()
146 # layout.use_property_split = True
147 row
= layout
.row(align
=True)
151 row
= box
.row(align
=True)
152 row
.label(text
="Panel Category:")
153 row
.prop(self
, "category", text
="")
157 row
= box
.row(align
=True)
158 row
.label(text
='Box Deform:')
159 row
.operator("wm.call_menu", text
="", icon
='QUESTION').name
= "GPT_MT_box_deform_doc"
160 box
.prop(self
, "use_clic_drag")
162 box
.prop(self
, "default_deform_type")
163 box
.label(text
="Deformer type can be changed during modal with 'M' key, this is for default behavior", icon
='INFO')
165 box
.prop(self
, "auto_swap_deform_type")
166 box
.label(text
="Once 'M' is hit, auto swap is desactivated to stay in your chosen mode", icon
='INFO')
170 box
.label(text
='Rotate canvas:')
172 box
.prop(self
, "canvas_use_shortcut", text
='Bind Shortcuts')
174 if self
.canvas_use_shortcut
:
177 row
.label(text
="(Auto rebind when changing shortcut)")#icon=""
178 # row.operator("prefs.rebind_shortcut", text='Bind/Rebind shortcuts', icon='FILE_REFRESH')#EVENT_SPACEKEY
179 row
= box
.row(align
= True)
180 row
.prop(self
, "use_ctrl", text
='Ctrl')#, expand=True
181 row
.prop(self
, "use_alt", text
='Alt')#, expand=True
182 row
.prop(self
, "use_shift", text
='Shift')#, expand=True
183 row
.prop(self
, "mouse_click",text
='')#expand=True
185 if not self
.use_ctrl
and not self
.use_alt
and not self
.use_shift
:
186 box
.label(text
="Choose at least one modifier to combine with click (default: Ctrl+Alt)", icon
="ERROR")# INFO
188 if not all((self
.use_ctrl
, self
.use_alt
, self
.use_shift
)):
189 row
= box
.row(align
= True)
191 if not self
.use_ctrl
:
192 snap_key_list
.append('Ctrl')
193 if not self
.use_shift
:
194 snap_key_list
.append('Shift')
196 snap_key_list
.append('Alt')
198 row
.label(text
=f
"Step rotation with: {' or '.join(snap_key_list)}", icon
='DRIVER_ROTATIONAL_DIFFERENCE')
199 row
.prop(self
, "rc_angle_step", text
='Angle Steps')
203 box
.label(text
="No hotkey has been set automatically. Following operators needs to be set manually:", icon
="ERROR")
204 box
.label(text
="view3d.rotate_canvas")
205 box
.prop(self
, 'canvas_use_view_center')
206 box
.prop(self
, 'canvas_use_hud')
210 draw_ts_pref(prefs
.ts
, box
)
214 class GPT_MT_box_deform_doc(bpy
.types
.Menu
):
215 # bl_idname = "OBJECT_MT_custom_menu"
216 bl_label
= "Box Deform Infos Sheet"
218 def draw(self
, context
):
221 #layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
222 #**Behavior from context mode**
223 col
= layout
.column()
224 col
.label(text
='Box Deform Tool')
225 col
.label(text
="Usage:", icon
='MOD_LATTICE')
226 col
.label(text
="Use the shortcut 'Ctrl+T' in available modes (listed below)")
227 col
.label(text
="The lattice box is generated facing your view (be sure to face canvas if you want to stay on it)")
228 col
.label(text
="Use shortcuts below to deform (a help will be displayed in the topbar)")
231 col
.label(text
="Shortcuts:", icon
='HAND')
232 col
.label(text
="Spacebar / Enter : Confirm")
233 col
.label(text
="Shift + Spacebar / Enter : Confirm and let the lattice in place")
234 col
.label(text
="Delete / Backspace / Tab(twice) / Ctrl+T : Cancel")
235 col
.label(text
="M : Toggle between Linear and Spline mode at any moment")
236 col
.label(text
="1-9 top row number : Subdivide the box")
237 col
.label(text
="Ctrl + arrows-keys : Subdivide the box incrementally in individual X/Y axis")
240 col
.label(text
="Modes and deformation target:", icon
='PIVOT_BOUNDBOX')
241 col
.label(text
="- Object mode : The whole GP object is deformed (including all frames)")
242 col
.label(text
="- GPencil Edit mode : Deform Selected points")
243 col
.label(text
="- Gpencil Paint : Deform last Strokes")
244 # col.label(text="- Lattice edit : Revive the modal after a ctrl+Z")
247 col
.label(text
="Notes:", icon
='TEXT')
248 col
.label(text
="- If you return in box deform after applying (with a ctrl+Z), you need to hit 'Ctrl+T' again to revive the modal.")
249 col
.label(text
="- A cancel warning will be displayed the first time you hit Tab")
251 ### rotate canvas keymap
254 def register_keymaps():
255 pref
= get_addon_prefs()
256 if not pref
.canvas_use_shortcut
:
258 addon
= bpy
.context
.window_manager
.keyconfigs
.addon
260 km
= addon
.keymaps
.new(name
= "3D View", space_type
= "VIEW_3D")
262 if 'view3d.rotate_canvas' not in km
.keymap_items
:
263 km
= addon
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
264 kmi
= km
.keymap_items
.new('view3d.rotate_canvas',
265 type=pref
.mouse_click
, value
="PRESS", alt
=pref
.use_alt
, ctrl
=pref
.use_ctrl
, shift
=pref
.use_shift
, any
=False)
267 addon_keymaps
.append((km
, kmi
))
269 def unregister_keymaps():
270 for km
, kmi
in addon_keymaps
:
271 km
.keymap_items
.remove(kmi
)
272 addon_keymaps
.clear()
278 GPTS_timeline_settings
,
279 GPT_MT_box_deform_doc
,
280 GreasePencilAddonPrefs
,
285 bpy
.utils
.register_class(cls
)
286 # Force box deform running to false
287 bpy
.context
.preferences
.addons
[os
.path
.splitext(__name__
)[0]].preferences
.boxdeform_running
= False
292 for cls
in reversed(classes
):
293 bpy
.utils
.unregister_class(cls
)