properties_material_gpencil.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. # <pep8 compliant>
  19. import bpy
  20. from bpy.types import Menu, Panel, UIList
  21. from rna_prop_ui import PropertyPanel
  22. from bl_ui.utils import PresetPanel
  23. from bl_ui.properties_grease_pencil_common import (
  24. GreasePencilMaterialsPanel,
  25. )
  26. class GPENCIL_MT_color_context_menu(Menu):
  27. bl_label = "Layer"
  28. def draw(self, _context):
  29. layout = self.layout
  30. layout.operator("gpencil.color_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
  31. layout.operator("gpencil.color_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
  32. layout.separator()
  33. layout.operator("gpencil.color_lock_all", icon='LOCKED', text="Lock All")
  34. layout.operator("gpencil.color_unlock_all", icon='UNLOCKED', text="UnLock All")
  35. layout.operator("gpencil.stroke_lock_color", text="Lock Unselected")
  36. layout.operator("gpencil.lock_layer", text="Lock Unused")
  37. class GPENCIL_UL_matslots(UIList):
  38. def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
  39. slot = item
  40. ma = slot.material
  41. if (ma is not None) and (ma.grease_pencil is not None):
  42. gpcolor = ma.grease_pencil
  43. if self.layout_type in {'DEFAULT', 'COMPACT'}:
  44. if gpcolor.lock:
  45. layout.active = False
  46. row = layout.row(align=True)
  47. row.enabled = not gpcolor.lock
  48. row.prop(ma, "name", text="", emboss=False, icon_value=icon)
  49. row = layout.row(align=True)
  50. row.prop(gpcolor, "lock", text="", emboss=False)
  51. row.prop(gpcolor, "hide", text="", emboss=False)
  52. if gpcolor.ghost is True:
  53. icon = 'ONIONSKIN_OFF'
  54. else:
  55. icon = 'ONIONSKIN_ON'
  56. row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False)
  57. elif self.layout_type == 'GRID':
  58. layout.alignment = 'CENTER'
  59. layout.label(text="", icon_value=icon)
  60. class GPMaterialButtonsPanel:
  61. bl_space_type = 'PROPERTIES'
  62. bl_region_type = 'WINDOW'
  63. bl_context = "material"
  64. @classmethod
  65. def poll(cls, context):
  66. ma = context.material
  67. return ma and ma.grease_pencil
  68. class MATERIAL_PT_gpencil_slots(GreasePencilMaterialsPanel, Panel):
  69. bl_label = "Grease Pencil Material Slots"
  70. bl_space_type = 'PROPERTIES'
  71. bl_region_type = 'WINDOW'
  72. bl_context = "material"
  73. bl_options = {'HIDE_HEADER'}
  74. @classmethod
  75. def poll(cls, context):
  76. ob = context.object
  77. ma = context.material
  78. return (ma and ma.grease_pencil) or (ob and ob.type == 'GPENCIL')
  79. # Used as parent for "Stroke" and "Fill" panels
  80. class MATERIAL_PT_gpencil_surface(GPMaterialButtonsPanel, Panel):
  81. bl_label = "Surface"
  82. def draw_header_preset(self, _context):
  83. MATERIAL_PT_gpencil_material_presets.draw_panel_header(self.layout)
  84. def draw(self, _context):
  85. layout = self.layout
  86. layout.use_property_split = True
  87. class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel):
  88. bl_label = "Stroke"
  89. bl_parent_id = 'MATERIAL_PT_gpencil_surface'
  90. def draw_header(self, context):
  91. ma = context.material
  92. if ma is not None and ma.grease_pencil is not None:
  93. gpcolor = ma.grease_pencil
  94. self.layout.prop(gpcolor, "show_stroke", text="")
  95. def draw(self, context):
  96. layout = self.layout
  97. layout.use_property_split = True
  98. ma = context.material
  99. if ma is not None and ma.grease_pencil is not None:
  100. gpcolor = ma.grease_pencil
  101. col = layout.column()
  102. col.active = not gpcolor.lock
  103. col.prop(gpcolor, "mode")
  104. col.prop(gpcolor, "stroke_style", text="Style")
  105. if gpcolor.stroke_style == 'TEXTURE':
  106. row = col.row()
  107. row.enabled = not gpcolor.lock
  108. col = row.column(align=True)
  109. col.template_ID(gpcolor, "stroke_image", open="image.open")
  110. if gpcolor.mode == 'LINE':
  111. col.prop(gpcolor, "pixel_size", text="UV Factor")
  112. col.prop(gpcolor, "use_stroke_pattern", text="Use As Stencil Mask")
  113. if gpcolor.use_stroke_pattern is False:
  114. col.prop(gpcolor, "use_stroke_texture_mix", text="Mix Color")
  115. if gpcolor.use_stroke_texture_mix is True:
  116. col.prop(gpcolor, "mix_stroke_factor", text="Factor")
  117. if (
  118. gpcolor.stroke_style == 'SOLID' or
  119. gpcolor.use_stroke_pattern or
  120. gpcolor.use_stroke_texture_mix
  121. ):
  122. col.prop(gpcolor, "color", text="Color")
  123. if gpcolor.mode in {'DOTS', 'BOX'}:
  124. col.prop(gpcolor, "alignment_mode")
  125. class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
  126. bl_label = "Fill"
  127. bl_parent_id = 'MATERIAL_PT_gpencil_surface'
  128. def draw_header(self, context):
  129. ma = context.material
  130. gpcolor = ma.grease_pencil
  131. self.layout.prop(gpcolor, "show_fill", text="")
  132. def draw(self, context):
  133. layout = self.layout
  134. layout.use_property_split = True
  135. ma = context.material
  136. gpcolor = ma.grease_pencil
  137. # color settings
  138. col = layout.column()
  139. col.active = not gpcolor.lock
  140. col.prop(gpcolor, "fill_style", text="Style")
  141. if gpcolor.fill_style == 'GRADIENT':
  142. col.prop(gpcolor, "gradient_type")
  143. if gpcolor.fill_style != 'TEXTURE':
  144. col.prop(gpcolor, "fill_color", text="Color")
  145. if gpcolor.fill_style in {'GRADIENT', 'CHECKER'}:
  146. col.prop(gpcolor, "mix_color", text="Secondary Color")
  147. if gpcolor.fill_style == 'GRADIENT':
  148. col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
  149. if gpcolor.fill_style in {'GRADIENT', 'CHECKER'}:
  150. col.prop(gpcolor, "flip", text="Flip Colors")
  151. col.prop(gpcolor, "pattern_shift", text="Location")
  152. col.prop(gpcolor, "pattern_scale", text="Scale")
  153. if gpcolor.gradient_type == 'RADIAL' and gpcolor.fill_style not in {'SOLID', 'CHECKER'}:
  154. col.prop(gpcolor, "pattern_radius", text="Radius")
  155. else:
  156. if gpcolor.fill_style != 'SOLID':
  157. col.prop(gpcolor, "pattern_angle", text="Angle")
  158. if gpcolor.fill_style == 'CHECKER':
  159. col.prop(gpcolor, "pattern_gridsize", text="Box Size")
  160. # Texture
  161. if gpcolor.fill_style == 'TEXTURE' or (gpcolor.use_fill_texture_mix is True and gpcolor.fill_style == 'SOLID'):
  162. col.template_ID(gpcolor, "fill_image", open="image.open")
  163. if gpcolor.fill_style == 'TEXTURE':
  164. col.prop(gpcolor, "use_fill_pattern", text="Use As Stencil Mask")
  165. if gpcolor.use_fill_pattern is True:
  166. col.prop(gpcolor, "fill_color", text="Color")
  167. col.prop(gpcolor, "texture_offset", text="Offset")
  168. col.prop(gpcolor, "texture_scale", text="Scale")
  169. col.prop(gpcolor, "texture_angle")
  170. col.prop(gpcolor, "texture_opacity")
  171. col.prop(gpcolor, "texture_clamp", text="Clip Image")
  172. if gpcolor.use_fill_pattern is False:
  173. col.prop(gpcolor, "use_fill_texture_mix", text="Mix With Color")
  174. if gpcolor.use_fill_texture_mix is True:
  175. col.prop(gpcolor, "fill_color", text="Mix Color")
  176. col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
  177. class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel):
  178. bl_label = "Preview"
  179. COMPAT_ENGINES = {'BLENDER_EEVEE'}
  180. bl_options = {'DEFAULT_CLOSED'}
  181. def draw(self, context):
  182. ma = context.material
  183. self.layout.label(text=ma.name)
  184. self.layout.template_preview(ma)
  185. class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel):
  186. COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  187. _context_path = "object.active_material"
  188. _property_type = bpy.types.Material
  189. class MATERIAL_PT_gpencil_options(GPMaterialButtonsPanel, Panel):
  190. bl_label = "Options"
  191. bl_options = {'DEFAULT_CLOSED'}
  192. def draw(self, context):
  193. layout = self.layout
  194. layout.use_property_split = True
  195. ma = context.material
  196. gpcolor = ma.grease_pencil
  197. layout.prop(gpcolor, "pass_index")
  198. class MATERIAL_PT_gpencil_material_presets(PresetPanel, Panel):
  199. """Material settings"""
  200. bl_label = "Material Presets"
  201. preset_subdir = "gpencil_material"
  202. preset_operator = "script.execute_preset"
  203. preset_add_operator = "scene.gpencil_material_preset_add"
  204. classes = (
  205. GPENCIL_UL_matslots,
  206. GPENCIL_MT_color_context_menu,
  207. MATERIAL_PT_gpencil_slots,
  208. MATERIAL_PT_gpencil_preview,
  209. MATERIAL_PT_gpencil_material_presets,
  210. MATERIAL_PT_gpencil_surface,
  211. MATERIAL_PT_gpencil_strokecolor,
  212. MATERIAL_PT_gpencil_fillcolor,
  213. MATERIAL_PT_gpencil_options,
  214. MATERIAL_PT_gpencil_custom_props,
  215. )
  216. if __name__ == "__main__": # only for live edit.
  217. from bpy.utils import register_class
  218. for cls in classes:
  219. register_class(cls)