1 # SPDX-FileCopyrightText: 2020-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
7 from bpy
.props
import (
16 from .ui_panels
import GP_PT_sidebarPanel
18 def get_addon_prefs():
20 addon_name
= os
.path
.splitext(__name__
)[0]
21 addon_prefs
= bpy
.context
.preferences
.addons
[addon_name
].preferences
24 from .timeline_scrub
import GPTS_timeline_settings
, draw_ts_pref
25 from .layer_navigator
import GPNAV_layer_navigator_settings
, draw_nav_pref
27 ## Addons Preferences Update Panel
28 def update_panel(self
, context
):
30 bpy
.utils
.unregister_class(GP_PT_sidebarPanel
)
33 GP_PT_sidebarPanel
.bl_category
= get_addon_prefs().category
34 bpy
.utils
.register_class(GP_PT_sidebarPanel
)
36 ## keymap binder for rotate canvas
37 def auto_rebind(self
, context
):
41 class GreasePencilAddonPrefs(bpy
.types
.AddonPreferences
):
42 bl_idname
= os
.path
.splitext(__name__
)[0] #__package__
44 ts
: PointerProperty(type=GPTS_timeline_settings
)
45 nav
: PointerProperty(type=GPNAV_layer_navigator_settings
)
48 category
: StringProperty(
50 description
="Choose a name for the category of the panel",
51 default
="Grease Pencil",
55 pref_tab
: EnumProperty(
56 name
="Preference Tool Tab", description
="Choose tool preferences to display",
57 default
='canvas_rotate',
59 ('canvas_rotate', 'Rotate Canvas', 'Canvas Rotate tool shortcut and prefs', 0),
60 ('box_deform', 'Box Deform', 'Box Deform tool prefs', 1),
61 ('timeline_scrub', 'Timeline Scrub', 'Timeline Scrub tool shortcut and prefs', 2),
62 ('layer_navigator', 'Layer Navigator', 'Layer Navigation tool shortcut and prefs', 3),
68 use_clic_drag
: BoolProperty(
69 name
='Use click drag directly on points',
70 description
="Change the active tool to 'tweak' during modal, Allow to direct clic-drag points of the box",
73 default_deform_type
: EnumProperty(
74 items
=(('KEY_LINEAR', "Linear (perspective mode)", "Linear interpolation, like corner deform / perspective tools of classic 2D", 'IPO_LINEAR',0),
75 ('KEY_BSPLINE', "Spline (smooth deform)", "Spline interpolation transformation\nBest when lattice is subdivided", 'IPO_CIRC',1),
77 name
='Starting Interpolation', default
='KEY_LINEAR', description
='Choose default interpolation when entering mode')
79 # About interpolation : https://docs.blender.org/manual/en/2.83/animation/shape_keys/shape_keys_panel.html#fig-interpolation-type
81 auto_swap_deform_type
: BoolProperty(
82 name
='Auto swap interpolation mode',
83 description
="Automatically set interpolation to 'spline' when subdividing lattice\n Back to 'linear' when",
86 ## rotate canvas variables
89 canvas_use_hud
: BoolProperty(
91 description
= "Display angle lines and angle value as text on viewport",
94 canvas_use_view_center
: BoolProperty(
95 name
= "Rotate From View Center In Camera",
96 description
= "Rotate from view center in camera view, Else rotate from camera center",
100 canvas_use_shortcut
: BoolProperty(
101 name
= "Use Default Shortcut",
102 description
= "Use default shortcut: mouse double-click + modifier",
106 mouse_click
: EnumProperty(
107 name
="Mouse button", description
="click on right/left/middle mouse button in combination with a modifier to trigger alignment",
108 default
='MIDDLEMOUSE',
110 ('RIGHTMOUSE', 'Right click', 'Use click on Right mouse button', 'MOUSE_RMB', 0),
111 ('LEFTMOUSE', 'Left click', 'Use click on Left mouse button', 'MOUSE_LMB', 1),
112 ('MIDDLEMOUSE', 'Mid click', 'Use click on Mid mouse button', 'MOUSE_MMB', 2),
116 use_shift
: BoolProperty(
117 name
= "combine with shift",
118 description
= "add shift",
122 use_alt
: BoolProperty(
123 name
= "combine with alt",
124 description
= "add alt",
128 use_ctrl
: BoolProperty(
129 name
= "combine with ctrl",
130 description
= "add ctrl",
134 rc_angle_step
: FloatProperty(
136 description
="Step the rotation using this angle when using rotate canvas step modifier",
137 default
=0.2617993877991494, # 15
138 min=0.01745329238474369, # 1
139 max=3.1415927410125732, # 180
140 soft_min
=0.01745329238474369, # 1
141 soft_max
=1.5707963705062866, # 90
142 step
=10, precision
=1, subtype
='ANGLE', unit
='ROTATION')
144 def draw(self
, context
):
145 prefs
= get_addon_prefs()
147 # layout.use_property_split = True
148 row
= layout
.row(align
=True)
152 row
= box
.row(align
=True)
153 row
.label(text
="Panel Category:")
154 row
.prop(self
, "category", text
="")
156 row
= layout
.row(align
=True)
157 row
.prop(self
, "pref_tab", expand
=True)
159 if self
.pref_tab
== 'box_deform':
163 row
= box
.row(align
=True)
164 row
.label(text
='Box Deform:')
165 row
.operator("wm.call_menu", text
="", icon
='QUESTION').name
= "GPT_MT_box_deform_doc"
166 box
.prop(self
, "use_clic_drag")
168 box
.prop(self
, "default_deform_type")
169 box
.label(text
="Deformer type can be changed during modal with 'M' key, this is for default behavior", icon
='INFO')
171 box
.prop(self
, "auto_swap_deform_type")
172 box
.label(text
="Once 'M' is hit, auto swap is deactivated to stay in your chosen mode", icon
='INFO')
174 if self
.pref_tab
== 'canvas_rotate':
177 box
.label(text
='Rotate Canvas:')
179 box
.prop(self
, "canvas_use_shortcut", text
='Bind Shortcuts')
181 if self
.canvas_use_shortcut
:
184 row
.label(text
="(Auto rebind when changing shortcut)")#icon=""
185 # row.operator("prefs.rebind_shortcut", text='Bind/Rebind shortcuts', icon='FILE_REFRESH')#EVENT_SPACEKEY
186 row
= box
.row(align
= True)
187 row
.prop(self
, "use_ctrl", text
='Ctrl')#, expand=True
188 row
.prop(self
, "use_alt", text
='Alt')#, expand=True
189 row
.prop(self
, "use_shift", text
='Shift')#, expand=True
190 row
.prop(self
, "mouse_click",text
='')#expand=True
192 if not self
.use_ctrl
and not self
.use_alt
and not self
.use_shift
:
193 box
.label(text
="Choose at least one modifier to combine with click (default: Ctrl+Alt)", icon
="ERROR")# INFO
195 if not all((self
.use_ctrl
, self
.use_alt
, self
.use_shift
)):
196 row
= box
.row(align
= True)
198 if not self
.use_ctrl
:
199 snap_key_list
.append('Ctrl')
200 if not self
.use_shift
:
201 snap_key_list
.append('Shift')
203 snap_key_list
.append('Alt')
205 row
.label(text
=f
"Step rotation with: {' or '.join(snap_key_list)}", icon
='DRIVER_ROTATIONAL_DIFFERENCE')
206 row
.prop(self
, "rc_angle_step", text
='Angle Steps')
209 box
.label(text
="No hotkey has been set automatically. Following operators needs to be set manually:", icon
="ERROR")
210 box
.label(text
="view3d.rotate_canvas")
211 box
.prop(self
, 'canvas_use_view_center')
212 box
.prop(self
, 'canvas_use_hud')
214 if self
.pref_tab
== 'timeline_scrub':
217 draw_ts_pref(prefs
.ts
, box
)
219 if self
.pref_tab
== 'layer_navigator':
222 draw_nav_pref(prefs
.nav
, box
)
226 class GPT_MT_box_deform_doc(bpy
.types
.Menu
):
227 # bl_idname = "OBJECT_MT_custom_menu"
228 bl_label
= "Box Deform Infos Sheet"
230 def draw(self
, context
):
233 #layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
234 #**Behavior from context mode**
235 col
= layout
.column()
236 col
.label(text
='Box Deform Tool')
237 col
.label(text
="Usage:", icon
='MOD_LATTICE')
238 col
.label(text
="Use the shortcut 'Ctrl+T' in available modes (listed below)")
239 col
.label(text
="The lattice box is generated facing your view (be sure to face canvas if you want to stay on it)")
240 col
.label(text
="Use shortcuts below to deform (a help will be displayed in the topbar)")
243 col
.label(text
="Shortcuts:", icon
='HAND')
244 col
.label(text
="Spacebar / Enter : Confirm")
245 col
.label(text
="Shift + Spacebar / Enter : Confirm and let the lattice in place")
246 col
.label(text
="Delete / Backspace / Tab(twice) / Ctrl+T : Cancel")
247 col
.label(text
="M : Toggle between Linear and Spline mode at any moment")
248 col
.label(text
="1-9 top row number : Subdivide the box")
249 col
.label(text
="Ctrl + arrows-keys : Subdivide the box incrementally in individual X/Y axis")
252 col
.label(text
="Modes and deformation target:", icon
='PIVOT_BOUNDBOX')
253 col
.label(text
="- Object mode : The whole GP object is deformed (including all frames)")
254 col
.label(text
="- GPencil Edit mode : Deform Selected points")
255 col
.label(text
="- Gpencil Paint : Deform last Strokes")
256 # col.label(text="- Lattice edit : Revive the modal after a ctrl+Z")
259 col
.label(text
="Notes:", icon
='TEXT')
260 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.")
261 col
.label(text
="- A cancel warning will be displayed the first time you hit Tab")
263 ### rotate canvas keymap
266 def register_keymaps():
267 pref
= get_addon_prefs()
268 if not pref
.canvas_use_shortcut
:
270 kc
= bpy
.context
.window_manager
.keyconfigs
.addon
274 km
= kc
.keymaps
.new(name
= "3D View", space_type
= "VIEW_3D")
276 if 'view3d.rotate_canvas' not in km
.keymap_items
:
277 km
= kc
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
278 kmi
= km
.keymap_items
.new('view3d.rotate_canvas',
279 type=pref
.mouse_click
, value
="PRESS", alt
=pref
.use_alt
, ctrl
=pref
.use_ctrl
, shift
=pref
.use_shift
, any
=False)
281 addon_keymaps
.append((km
, kmi
))
283 def unregister_keymaps():
284 for km
, kmi
in addon_keymaps
:
285 km
.keymap_items
.remove(kmi
)
286 addon_keymaps
.clear()
292 GPTS_timeline_settings
,
293 GPNAV_layer_navigator_settings
,
294 GPT_MT_box_deform_doc
,
295 GreasePencilAddonPrefs
,
300 bpy
.utils
.register_class(cls
)
301 # Force box deform running to false
302 bpy
.context
.preferences
.addons
[os
.path
.splitext(__name__
)[0]].preferences
.boxdeform_running
= False
307 for cls
in reversed(classes
):
308 bpy
.utils
.unregister_class(cls
)