GPencil: Smooth and Subdivision variable/setting naming
[blender.git] / release / scripts / startup / bl_ui / properties_grease_pencil_common.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
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.
7 #
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.
12 #
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.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21
22 from bpy.types import Menu, UIList
23
24
25 def gpencil_stroke_placement_settings(context, layout):
26     if context.space_data.type == 'VIEW_3D':
27         propname = "gpencil_stroke_placement_view3d"
28     elif context.space_data.type == 'SEQUENCE_EDITOR':
29         propname = "gpencil_stroke_placement_sequencer_preview"
30     elif context.space_data.type == 'IMAGE_EDITOR':
31         propname = "gpencil_stroke_placement_image_editor"
32     else:
33         propname = "gpencil_stroke_placement_view2d"
34
35     ts = context.tool_settings
36
37     col = layout.column(align=True)
38
39     col.label(text="Stroke Placement:")
40
41     row = col.row(align=True)
42     row.prop_enum(ts, propname, 'VIEW')
43     row.prop_enum(ts, propname, 'CURSOR')
44
45     if context.space_data.type == 'VIEW_3D':
46         row = col.row(align=True)
47         row.prop_enum(ts, propname, 'SURFACE')
48         row.prop_enum(ts, propname, 'STROKE')
49
50         row = col.row(align=False)
51         row.active = getattr(ts, propname) in {'SURFACE', 'STROKE'}
52         row.prop(ts, "use_gpencil_stroke_endpoints")
53
54
55 class GreasePencilDrawingToolsPanel:
56     # subclass must set
57     # bl_space_type = 'IMAGE_EDITOR'
58     bl_label = "Grease Pencil"
59     bl_category = "Grease Pencil"
60     bl_region_type = 'TOOLS'
61
62     @staticmethod
63     def draw(self, context):
64         layout = self.layout
65
66         col = layout.column(align=True)
67
68         col.label(text="Draw:")
69         row = col.row(align=True)
70         row.operator("gpencil.draw", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
71         row.operator("gpencil.draw", icon='FORCE_CURVE', text="Erase").mode = 'ERASER'  # XXX: Needs a dedicated icon
72
73         row = col.row(align=True)
74         row.operator("gpencil.draw", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
75         row.operator("gpencil.draw", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
76
77         sub = col.column(align=True)
78         sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
79         sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
80
81         col.separator()
82         col.separator()
83
84         if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}:
85             col.separator()
86             col.label("Data Source:")
87             row = col.row(align=True)
88             if context.space_data.type == 'VIEW_3D':
89                 row.prop(context.tool_settings, "grease_pencil_source", expand=True)
90             elif context.space_data.type == 'CLIP_EDITOR':
91                 row.prop(context.space_data, "grease_pencil_source", expand=True)
92
93         col.separator()
94         col.separator()
95
96         gpencil_stroke_placement_settings(context, col)
97
98         gpd = context.gpencil_data
99
100         if gpd:
101             layout.separator()
102             layout.separator()
103
104             col = layout.column(align=True)
105             col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
106
107         if context.space_data.type == 'VIEW_3D':
108             col.separator()
109             col.separator()
110
111             col.label(text="Tools:")
112             col.operator("gpencil.convert", text="Convert...")
113             col.operator("view3d.ruler")
114
115
116 class GreasePencilStrokeEditPanel:
117     # subclass must set
118     # bl_space_type = 'IMAGE_EDITOR'
119     bl_label = "Edit Strokes"
120     bl_category = "Grease Pencil"
121     bl_region_type = 'TOOLS'
122     bl_options = {'DEFAULT_CLOSED'}
123
124     @classmethod
125     def poll(cls, context):
126         if context.gpencil_data is None:
127             return False
128
129         gpd = context.gpencil_data
130         return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
131
132     @staticmethod
133     def draw(self, context):
134         layout = self.layout
135
136         layout.label(text="Select:")
137         col = layout.column(align=True)
138         col.operator("gpencil.select_all", text="Select All")
139         col.operator("gpencil.select_border")
140         col.operator("gpencil.select_circle")
141
142         layout.separator()
143
144         col = layout.column(align=True)
145         col.operator("gpencil.select_linked")
146         col.operator("gpencil.select_more")
147         col.operator("gpencil.select_less")
148
149         layout.separator()
150
151         layout.label(text="Edit:")
152         row = layout.row(align=True)
153         row.operator("gpencil.copy", text="Copy")
154         row.operator("gpencil.paste", text="Paste")
155
156         col = layout.column(align=True)
157         col.operator("gpencil.delete", text="Delete")
158         col.operator("gpencil.duplicate_move", text="Duplicate")
159         col.operator("transform.mirror", text="Mirror")
160
161         layout.separator()
162
163         col = layout.column(align=True)
164         col.operator("transform.translate")                # icon='MAN_TRANS'
165         col.operator("transform.rotate")                   # icon='MAN_ROT'
166         col.operator("transform.resize", text="Scale")     # icon='MAN_SCALE'
167
168         layout.separator()
169
170         col = layout.column(align=True)
171         col.operator("transform.bend", text="Bend")
172         col.operator("transform.shear", text="Shear")
173         col.operator("transform.tosphere", text="To Sphere")
174
175
176 class GreasePencilStrokeSculptPanel:
177     # subclass must set
178     # bl_space_type = 'IMAGE_EDITOR'
179     bl_label = "Sculpt Strokes"
180     bl_category = "Grease Pencil"
181     bl_region_type = 'TOOLS'
182
183     @classmethod
184     def poll(cls, context):
185         if context.gpencil_data is None:
186             return False
187
188         gpd = context.gpencil_data
189         return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
190
191     @staticmethod
192     def draw(self, context):
193         layout = self.layout
194
195         settings = context.tool_settings.gpencil_sculpt
196         tool = settings.tool
197         brush = settings.brush
198
199         layout.column().prop(settings, "tool", expand=True)
200
201         col = layout.column()
202         col.prop(brush, "size", slider=True)
203         row = col.row(align=True)
204         row.prop(brush, "strength", slider=True)
205         row.prop(brush, "use_pressure_strength", text="")
206         col.prop(brush, "use_falloff")
207
208         layout.separator()
209
210         if settings.tool == 'THICKNESS':
211             layout.row().prop(brush, "direction", expand=True)
212         elif settings.tool == 'PINCH':
213             row = layout.row(align=True)
214             row.prop_enum(brush, "direction", 'ADD', text="Pinch")
215             row.prop_enum(brush, "direction", 'SUBTRACT', text="Inflate")
216         elif settings.tool == 'TWIST':
217             row = layout.row(align=True)
218             row.prop_enum(brush, "direction", 'SUBTRACT', text="CW")
219             row.prop_enum(brush, "direction", 'ADD', text="CCW")
220
221         layout.separator()
222         layout.prop(settings, "use_select_mask")
223
224         if settings.tool == 'SMOOTH':
225             layout.prop(brush, "affect_pressure")
226
227
228 ###############################
229
230 class GPENCIL_PIE_tool_palette(Menu):
231     """A pie menu for quick access to Grease Pencil tools"""
232     bl_label = "Grease Pencil Tools"
233
234     def draw(self, context):
235         layout = self.layout
236
237         pie = layout.menu_pie()
238         gpd = context.gpencil_data
239
240         # W - Drawing Types
241         col = pie.column()
242         col.operator("gpencil.draw", text="Draw", icon='GREASEPENCIL').mode = 'DRAW'
243         col.operator("gpencil.draw", text="Straight Lines", icon='LINE_DATA').mode = 'DRAW_STRAIGHT'
244         col.operator("gpencil.draw", text="Poly", icon='MESH_DATA').mode = 'DRAW_POLY'
245
246         # E - Eraser
247         # XXX: needs a dedicated icon...
248         col = pie.column()
249         col.operator("gpencil.draw", text="Eraser", icon='FORCE_CURVE').mode = 'ERASER'
250
251         # E - "Settings" Palette is included here too, since it needs to be in a stable position...
252         if gpd and gpd.layers.active:
253             col.separator()
254             col.operator("wm.call_menu_pie", text="Settings...", icon='SCRIPTWIN').name = "GPENCIL_PIE_settings_palette"
255
256         # Editing tools
257         if gpd:
258             if gpd.use_stroke_edit_mode and context.editable_gpencil_strokes:
259                 # S - Exit Edit Mode
260                 pie.operator("gpencil.editmode_toggle", text="Exit Edit Mode", icon='EDIT')
261
262                 # N - Transforms
263                 col = pie.column()
264                 row = col.row(align=True)
265                 row.operator("transform.translate", icon='MAN_TRANS')
266                 row.operator("transform.rotate", icon='MAN_ROT')
267                 row.operator("transform.resize", text="Scale", icon='MAN_SCALE')
268                 row = col.row(align=True)
269                 row.label("Proportional Edit:")
270                 row.prop(context.tool_settings, "proportional_edit", text="", icon_only=True)
271                 row.prop(context.tool_settings, "proportional_edit_falloff", text="", icon_only=True)
272
273                 # NW - Select (Non-Modal)
274                 col = pie.column()
275                 col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT')
276                 col.operator("gpencil.select_all", text="Select Inverse", icon='BLANK1')
277                 col.operator("gpencil.select_linked", text="Select Linked", icon='LINKED')
278
279                 # NE - Select (Modal)
280                 col = pie.column()
281                 col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT')
282                 col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY')
283                 col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO')
284
285                 # SW - Edit Tools
286                 col = pie.column()
287                 col.operator("gpencil.duplicate_move", icon='PARTICLE_PATH', text="Duplicate")
288                 col.operator("gpencil.delete", icon='X', text="Delete...")
289
290                 # SE - More Tools
291                 pie.operator("wm.call_menu_pie", text="More...").name = "GPENCIL_PIE_tools_more"
292             else:
293                 # Toggle Edit Mode
294                 pie.operator("gpencil.editmode_toggle", text="Enable Stroke Editing", icon='EDIT')
295
296
297 class GPENCIL_PIE_settings_palette(Menu):
298     """A pie menu for quick access to Grease Pencil settings"""
299     bl_label = "Grease Pencil Settings"
300
301     @classmethod
302     def poll(cls, context):
303         return bool(context.gpencil_data and context.active_gpencil_layer)
304
305     def draw(self, context):
306         layout = self.layout
307
308         pie = layout.menu_pie()
309         # gpd = context.gpencil_data
310         gpl = context.active_gpencil_layer
311
312         # W - Stroke draw settings
313         col = pie.column(align=True)
314         col.label(text="Stroke")
315         col.prop(gpl, "color", text="")
316         col.prop(gpl, "alpha", text="", slider=True)
317
318         # E - Fill draw settings
319         col = pie.column(align=True)
320         col.label(text="Fill")
321         col.prop(gpl, "fill_color", text="")
322         col.prop(gpl, "fill_alpha", text="", slider=True)
323
324         # S - Layer settings
325         col = pie.column()
326         col.prop(gpl, "line_width", slider=True)
327         # col.prop(gpl, "use_volumetric_strokes")
328         col.prop(gpl, "use_onion_skinning")
329
330         # N - Active Layer
331         col = pie.column()
332         col.label("Active Layer:      ")
333
334         row = col.row()
335         row.operator_context = 'EXEC_REGION_WIN'
336         row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL')
337         row.prop(gpl, "info", text="")
338         row.operator("gpencil.layer_remove", text="", icon='X')
339
340         row = col.row()
341         row.prop(gpl, "lock")
342         row.prop(gpl, "hide")
343
344
345 class GPENCIL_PIE_tools_more(Menu):
346     """A pie menu for accessing more Grease Pencil tools"""
347     bl_label = "More Grease Pencil Tools"
348
349     @classmethod
350     def poll(cls, context):
351         gpd = context.gpencil_data
352         return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes)
353
354     def draw(self, context):
355         layout = self.layout
356
357         pie = layout.menu_pie()
358         # gpd = context.gpencil_data
359
360         col = pie.column(align=True)
361         col.operator("gpencil.copy", icon='COPYDOWN', text="Copy")
362         col.operator("gpencil.paste", icon='PASTEDOWN', text="Paste")
363
364         col = pie.column(align=True)
365         col.operator("gpencil.select_more", icon='ZOOMIN')
366         col.operator("gpencil.select_less", icon='ZOOMOUT')
367
368         pie.operator("transform.mirror", icon='MOD_MIRROR')
369         pie.operator("transform.bend", icon='MOD_SIMPLEDEFORM')
370         pie.operator("transform.shear", icon='MOD_TRIANGULATE')
371         pie.operator("transform.tosphere", icon='MOD_MULTIRES')
372
373         pie.operator("gpencil.convert", icon='OUTLINER_OB_CURVE', text="Convert...")
374         pie.operator("wm.call_menu_pie", text="Back to Main Palette...").name = "GPENCIL_PIE_tool_palette"
375
376
377 class GPENCIL_PIE_sculpt(Menu):
378     """A pie menu for accessing Grease Pencil stroke sculpting settings"""
379     bl_label = "Grease Pencil Sculpt"
380
381     @classmethod
382     def poll(cls, context):
383         gpd = context.gpencil_data
384         return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes)
385
386     def draw(self, context):
387         layout = self.layout
388
389         pie = layout.menu_pie()
390
391         settings = context.tool_settings.gpencil_sculpt
392         brush = settings.brush
393
394         # W - Launch Sculpt Mode
395         col = pie.column()
396         # col.label("Tool:")
397         col.prop(settings, "tool", text="")
398         col.operator("gpencil.brush_paint", text="Sculpt", icon='SCULPTMODE_HLT')
399
400         # E - Common Settings
401         col = pie.column(align=True)
402         col.prop(brush, "size", slider=True)
403         row = col.row(align=True)
404         row.prop(brush, "strength", slider=True)
405         # row.prop(brush, "use_pressure_strength", text="", icon_only=True)
406         col.prop(brush, "use_falloff")
407
408         # S - Change Brush Type Shortcuts
409         row = pie.row()
410         row.prop_enum(settings, "tool", value='GRAB')
411         row.prop_enum(settings, "tool", value='PUSH')
412         row.prop_enum(settings, "tool", value='CLONE')
413
414         # N - Change Brush Type Shortcuts
415         row = pie.row()
416         row.prop_enum(settings, "tool", value='SMOOTH')
417         row.prop_enum(settings, "tool", value='THICKNESS')
418         row.prop_enum(settings, "tool", value='RANDOMIZE')
419
420
421 ###############################
422
423
424 class GPENCIL_MT_snap(Menu):
425     bl_label = "Snap"
426
427     def draw(self, context):
428         layout = self.layout
429
430         layout.operator("gpencil.snap_to_grid", text="Selection to Grid")
431         layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor").use_offset = False
432         layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
433
434         layout.separator()
435
436         layout.operator("gpencil.snap_cursor_to_selected", text="Cursor to Selected")
437         layout.operator("view3d.snap_cursor_to_center", text="Cursor to Center")
438         layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
439
440
441 ###############################
442
443
444 class GPENCIL_UL_layer(UIList):
445     def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
446         # assert(isinstance(item, bpy.types.GPencilLayer)
447         gpl = item
448
449         if self.layout_type in {'DEFAULT', 'COMPACT'}:
450             if gpl.lock:
451                 layout.active = False
452
453             split = layout.split(percentage=0.25)
454             row = split.row(align=True)
455             row.prop(gpl, "color", text="", emboss=gpl.is_stroke_visible)
456             row.prop(gpl, "fill_color", text="", emboss=gpl.is_fill_visible)
457             split.prop(gpl, "info", text="", emboss=False)
458
459             row = layout.row(align=True)
460             row.prop(gpl, "lock", text="", emboss=False)
461             row.prop(gpl, "hide", text="", emboss=False)
462         elif self.layout_type == 'GRID':
463             layout.alignment = 'CENTER'
464             layout.label(text="", icon_value=icon)
465
466
467 class GPENCIL_MT_layer_specials(Menu):
468     bl_label = "Layer"
469
470     def draw(self, context):
471         layout = self.layout
472
473         layout.operator("gpencil.layer_duplicate", icon='COPY_ID')  # XXX: needs a dedicated icon
474
475         layout.separator()
476
477         layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
478         layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
479
480         layout.separator()
481
482         layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
483         layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
484
485
486 class GreasePencilDataPanel:
487     # subclass must set
488     # bl_space_type = 'IMAGE_EDITOR'
489     bl_label = "Grease Pencil"
490     bl_region_type = 'UI'
491
492     @staticmethod
493     def draw_header(self, context):
494         self.layout.prop(context.space_data, "show_grease_pencil", text="")
495
496     @staticmethod
497     def draw(self, context):
498         layout = self.layout
499
500         # owner of Grease Pencil data
501         gpd_owner = context.gpencil_data_owner
502         gpd = context.gpencil_data
503
504         # Owner Selector
505         if context.space_data.type == 'VIEW_3D':
506             layout.prop(context.tool_settings, "grease_pencil_source", expand=True)
507         elif context.space_data.type == 'CLIP_EDITOR':
508             layout.prop(context.space_data, "grease_pencil_source", expand=True)
509
510         # Grease Pencil data selector
511         layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink")
512
513         # Grease Pencil data...
514         if (gpd is None) or (not gpd.layers):
515             layout.operator("gpencil.layer_add", text="New Layer")
516         else:
517             self.draw_layers(context, layout, gpd)
518
519     def draw_layers(self, context, layout, gpd):
520         row = layout.row()
521
522         col = row.column()
523         if len(gpd.layers) >= 2:
524             layer_rows = 5
525         else:
526             layer_rows = 2
527         col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
528
529         col = row.column()
530
531         sub = col.column(align=True)
532         sub.operator("gpencil.layer_add", icon='ZOOMIN', text="")
533         sub.operator("gpencil.layer_remove", icon='ZOOMOUT', text="")
534
535         gpl = context.active_gpencil_layer
536         if gpl:
537             sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="")
538
539             if len(gpd.layers) > 1:
540                 col.separator()
541
542                 sub = col.column(align=True)
543                 sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
544                 sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
545
546                 col.separator()
547
548                 sub = col.column(align=True)
549                 sub.operator("gpencil.layer_isolate", icon='SOLO_OFF', text="").affect_visibility = False
550                 sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
551
552         if gpl:
553             self.draw_layer(layout, gpl)
554
555     def draw_layer(self, layout, gpl):
556         # layer settings
557         split = layout.split(percentage=0.5)
558         split.active = not gpl.lock
559
560         # Column 1 - Stroke
561         col = split.column(align=True)
562         col.label(text="Stroke:")
563         col.prop(gpl, "color", text="")
564         col.prop(gpl, "alpha", slider=True)
565
566         # Column 2 - Fill
567         col = split.column(align=True)
568         col.label(text="Fill:")
569         col.prop(gpl, "fill_color", text="")
570         col.prop(gpl, "fill_alpha", text="Opacity", slider=True)
571
572         # Options
573         split = layout.split(percentage=0.5)
574         split.active = not gpl.lock
575
576         col = split.column(align=True)
577         col.prop(gpl, "line_width", slider=True)
578         col.prop(gpl, "use_volumetric_strokes")
579
580         col = split.column(align=True)
581         col.prop(gpl, "show_x_ray")
582         col.prop(gpl, "show_points", text="Points")
583
584         layout.separator()
585
586         # Full-Row - Frame Locking (and Delete Frame)
587         row = layout.row(align=True)
588         row.active = not gpl.lock
589
590         if gpl.active_frame:
591             lock_status = "Locked" if gpl.lock_frame else "Unlocked"
592             lock_label = "Frame: %d (%s)" % (gpl.active_frame.frame_number, lock_status)
593         else:
594             lock_label = "Lock Frame"
595         row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')
596         row.operator("gpencil.active_frame_delete", text="", icon='X')
597
598         layout.separator()
599
600         # Onion skinning
601         col = layout.column(align=True)
602         col.active = not gpl.lock
603
604         row = col.row()
605         row.prop(gpl, "use_onion_skinning")
606         row.prop(gpl, "use_ghost_custom_colors", text="", icon='COLOR')
607
608         split = col.split(percentage=0.5)
609         split.active = gpl.use_onion_skinning
610
611         # - Before Frames
612         sub = split.column(align=True)
613         row = sub.row(align=True)
614         row.active = gpl.use_ghost_custom_colors
615         row.prop(gpl, "before_color", text="")
616         sub.prop(gpl, "ghost_before_range", text="Before")
617
618         # - After Frames
619         sub = split.column(align=True)
620         row = sub.row(align=True)
621         row.active = gpl.use_ghost_custom_colors
622         row.prop(gpl, "after_color", text="")
623         sub.prop(gpl, "ghost_after_range", text="After")
624
625         # Smooth and subdivide new strokes
626         layout.separator()
627         col = layout.column(align=True)
628         col.label(text="New Stroke Quality:")
629         col.prop(gpl, "pen_smooth_factor")
630         col.prop(gpl, "pen_subdivision_steps")
631
632
633 class GreasePencilToolsPanel:
634     # subclass must set
635     # bl_space_type = 'IMAGE_EDITOR'
636     # bl_options = {'DEFAULT_CLOSED'}
637     bl_label = "Grease Pencil Settings"
638     bl_region_type = 'UI'
639
640     @classmethod
641     def poll(cls, context):
642         return (context.gpencil_data is not None)
643
644     @staticmethod
645     def draw(self, context):
646         layout = self.layout
647
648         # gpd_owner = context.gpencil_data_owner
649         gpd = context.gpencil_data
650
651         layout.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
652
653         layout.separator()
654
655         layout.label("Proportional Edit:")
656         row = layout.row()
657         row.prop(context.tool_settings, "proportional_edit", text="")
658         row.prop(context.tool_settings, "proportional_edit_falloff", text="")
659
660         layout.separator()
661         layout.separator()
662
663         gpencil_stroke_placement_settings(context, layout)