Compare commits
77 Commits
main
...
soc-2013-u
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3a654c7d0d | ||
![]() |
13be174b2e | ||
![]() |
7e495c7d87 | ||
![]() |
6d5ba79f58 | ||
![]() |
689c91b05f | ||
![]() |
51fbcf519c | ||
![]() |
2750ec3d36 | ||
![]() |
f3cd07cd8f | ||
![]() |
6406f0f3c2 | ||
![]() |
9cdee6a0bf | ||
![]() |
3e77afd1b4 | ||
![]() |
0e15b28abb | ||
![]() |
cc5c3c65e4 | ||
![]() |
8ad8c253cf | ||
![]() |
1fce345840 | ||
![]() |
29d494d083 | ||
![]() |
6255447154 | ||
![]() |
1565fbff6f | ||
![]() |
8826b1b187 | ||
![]() |
f151c98bde | ||
![]() |
ca63536a41 | ||
![]() |
a8ee1b7f54 | ||
![]() |
a8db9bcf5f | ||
![]() |
29acbff903 | ||
![]() |
74bcc074af | ||
![]() |
53177d1650 | ||
![]() |
76b91a29f5 | ||
![]() |
d2815ece39 | ||
![]() |
db292ba7ac | ||
![]() |
ce1c83a5cf | ||
![]() |
8729239ba6 | ||
![]() |
8a56c889c0 | ||
![]() |
bc47687213 | ||
![]() |
2a38a84df7 | ||
![]() |
92d7d11062 | ||
![]() |
facf2cd856 | ||
![]() |
f6eee435bd | ||
![]() |
b4bff20a41 | ||
![]() |
9b597b954f | ||
![]() |
329adf15e9 | ||
![]() |
f43a42409c | ||
![]() |
548953ebeb | ||
![]() |
82a5690ff0 | ||
![]() |
33dd7102ad | ||
![]() |
13e8ede337 | ||
![]() |
12388139f9 | ||
![]() |
ee9d4579c1 | ||
![]() |
0fcc95cd99 | ||
![]() |
c35efb4b1f | ||
![]() |
20e6c810b7 | ||
![]() |
cecb600a0f | ||
![]() |
d37943d428 | ||
![]() |
8834459baf | ||
![]() |
8904c1a031 | ||
![]() |
bfca99a84d | ||
![]() |
b67df628f8 | ||
![]() |
e436f31e05 | ||
![]() |
94a5d7489f | ||
![]() |
29082fae71 | ||
![]() |
637e66077e | ||
![]() |
94401da0b7 | ||
![]() |
599ff8ee92 | ||
![]() |
a3c110e800 | ||
![]() |
e6662f5570 | ||
![]() |
ecc53fb6f8 | ||
![]() |
4834fae5d3 | ||
![]() |
61bfa2b3e8 | ||
![]() |
6a22944311 | ||
![]() |
88728a4b98 | ||
![]() |
1e26319c7b | ||
![]() |
36ac9f4fef | ||
![]() |
74baa2c697 | ||
![]() |
cd0c7edc99 | ||
![]() |
15c669d51c | ||
![]() |
95fe4ca034 | ||
![]() |
115157812c | ||
8929c1f33d |
@@ -6,3 +6,6 @@ BASEDIR=$(dirname $0)
|
||||
inkscape $BASEDIR/blender_icons.svg --export-dpi=90 --without-gui --export-png=$BASEDIR/blender_icons16.png
|
||||
inkscape $BASEDIR/blender_icons.svg --export-dpi=180 --without-gui --export-png=$BASEDIR/blender_icons32.png
|
||||
|
||||
inkscape $BASEDIR/blender_operator_icons.svg --export-dpi=90 --without-gui --export-png=$BASEDIR/blender_operator_icons16.png
|
||||
inkscape $BASEDIR/blender_operator_icons.svg --export-dpi=180 --without-gui --export-png=$BASEDIR/blender_operator_icons32.png
|
||||
|
||||
|
46498
release/datafiles/blender_operator_icons.svg
Normal file
46498
release/datafiles/blender_operator_icons.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 1.6 MiB |
BIN
release/datafiles/blender_operator_icons16.png
Normal file
BIN
release/datafiles/blender_operator_icons16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
release/datafiles/blender_operator_icons32.png
Normal file
BIN
release/datafiles/blender_operator_icons32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
@@ -743,6 +743,10 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
|
||||
filter_ext=lambda ext: ext.lower() in {".py", ".xml"})
|
||||
|
||||
|
||||
class MenuBar(StructRNA, _GenericUI, metaclass=RNAMeta):
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
class Region(StructRNA):
|
||||
__slots__ = ()
|
||||
|
||||
|
@@ -76,6 +76,7 @@ _modules = [
|
||||
"space_userpref",
|
||||
"space_view3d",
|
||||
"space_view3d_toolbar",
|
||||
"space_view3d_menubar",
|
||||
]
|
||||
|
||||
import bpy
|
||||
|
@@ -73,39 +73,45 @@ class UnifiedPaintPanel():
|
||||
def brush_texture_settings(layout, brush, sculpt):
|
||||
tex_slot = brush.texture_slot
|
||||
|
||||
layout.label(text="Brush Mapping:")
|
||||
col = layout.column(align=True)
|
||||
row = col.row()
|
||||
row.label(text="Mapping:")
|
||||
|
||||
# map_mode
|
||||
if sculpt:
|
||||
layout.row().prop(tex_slot, "map_mode", text="")
|
||||
layout.separator()
|
||||
row.prop(tex_slot, "map_mode", text="")
|
||||
else:
|
||||
layout.row().prop(tex_slot, "tex_paint_map_mode", text="")
|
||||
layout.separator()
|
||||
row.prop(tex_slot, "tex_paint_map_mode", text="")
|
||||
|
||||
if tex_slot.map_mode == 'STENCIL':
|
||||
if brush.texture and brush.texture.type == 'IMAGE':
|
||||
layout.operator("brush.stencil_fit_image_aspect")
|
||||
layout.operator("brush.stencil_reset_transform")
|
||||
col.separator()
|
||||
|
||||
# angle and texture_angle_source
|
||||
col = layout.column()
|
||||
col.active = brush.brush_capabilities.has_texture_angle_source
|
||||
col.label(text="Angle:")
|
||||
row = col.row()
|
||||
row.active = brush.brush_capabilities.has_texture_angle_source
|
||||
row.label(text="Angle:")
|
||||
sub = row.column()
|
||||
if brush.brush_capabilities.has_random_texture_angle:
|
||||
if sculpt:
|
||||
if brush.sculpt_capabilities.has_random_texture_angle:
|
||||
col.prop(brush, "texture_angle_source_random", text="")
|
||||
sub.prop(brush, "texture_angle_source_random", text="")
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_no_random", text="")
|
||||
sub.prop(brush, "texture_angle_source_no_random", text="")
|
||||
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_random", text="")
|
||||
sub.prop(brush, "texture_angle_source_random", text="")
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_no_random", text="")
|
||||
col = layout.column()
|
||||
col.active = brush.brush_capabilities.has_texture_angle
|
||||
col.prop(tex_slot, "angle", text="")
|
||||
sub.prop(brush, "texture_angle_source_no_random", text="")
|
||||
# row = layout.column()
|
||||
sub.active = brush.brush_capabilities.has_texture_angle
|
||||
sub.prop(tex_slot, "angle", text="")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.separator()
|
||||
|
||||
if tex_slot.map_mode == 'STENCIL':
|
||||
if brush.texture and brush.texture.type == 'IMAGE':
|
||||
col.operator("brush.stencil_fit_image_aspect")
|
||||
col.operator("brush.stencil_reset_transform")
|
||||
|
||||
# scale and offset
|
||||
split = layout.split()
|
||||
|
@@ -37,7 +37,7 @@ class INFO_HT_header(Header):
|
||||
if context.area.show_menus:
|
||||
sub = row.row(align=True)
|
||||
sub.menu("INFO_MT_file")
|
||||
sub.menu("INFO_MT_add")
|
||||
# sub.menu("INFO_MT_add")
|
||||
if rd.use_game_engine:
|
||||
sub.menu("INFO_MT_game")
|
||||
else:
|
||||
|
1626
release/scripts/startup/bl_ui/space_view3d_menubar.py
Normal file
1626
release/scripts/startup/bl_ui/space_view3d_menubar.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -28,16 +28,24 @@ class View3DPanel():
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
# ********** common tools for two or more modes ****************
|
||||
|
||||
# **************** standard tool clusters ******************
|
||||
def history_panel(mode):
|
||||
class cls(View3DPanel, Panel):
|
||||
bl_context = mode
|
||||
bl_label = "History"
|
||||
|
||||
# History/Repeat tools
|
||||
def draw_repeat_tools(context, layout):
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Repeat:")
|
||||
col.operator("screen.repeat_last")
|
||||
col.operator("screen.repeat_history", text="History...")
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
# col = layout.column(align=True, button_height=1.5)
|
||||
# col.operator("screen.redo_last", text="Change last")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.operator("screen.repeat_last")
|
||||
col.operator("screen.repeat_history", text="History...")
|
||||
|
||||
cls.__name__ = "VIEW3D_PT_tools_%s_history" % mode
|
||||
return cls
|
||||
|
||||
# Keyframing tools
|
||||
def draw_keyframing_tools(context, layout):
|
||||
@@ -47,76 +55,74 @@ def draw_keyframing_tools(context, layout):
|
||||
row.operator("anim.keyframe_insert_menu", text="Insert")
|
||||
row.operator("anim.keyframe_delete_v3d", text="Remove")
|
||||
|
||||
|
||||
# Grease Pencil tools
|
||||
def draw_gpencil_tools(context, layout):
|
||||
col = layout.column(align=True)
|
||||
|
||||
col.label(text="Grease Pencil:")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
|
||||
row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
|
||||
|
||||
row = col.row(align=True)
|
||||
row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
|
||||
row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(context.tool_settings, "use_grease_pencil_sessions")
|
||||
|
||||
col.operator("view3d.ruler")
|
||||
|
||||
|
||||
# ********** default tools for object-mode ****************
|
||||
|
||||
class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
|
||||
# VIEW3D_PT_tools_objectmode_modes = switch_panel("objectmode");
|
||||
|
||||
class VIEW3D_PT_tools_objectmode_transform(View3DPanel, Panel):
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Object Tools"
|
||||
bl_label = "Transform"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Transform:")
|
||||
col.operator("transform.translate")
|
||||
col.operator("transform.rotate")
|
||||
col.operator("transform.resize", text="Scale")
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
row.operator("transform.translate", text="", single_unit=False, icon='MAN_TRANS', shortcut=False)
|
||||
row.operator("transform.rotate", text="", single_unit=False, icon='MAN_ROT', shortcut=False)
|
||||
row.operator("transform.resize", text="", single_unit=False, icon='MAN_SCALE', shortcut=False)
|
||||
col.operator("object.origin_set", text="Origin")
|
||||
|
||||
class VIEW3D_PT_tools_objectmode_add(View3DPanel, Panel):
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Add & Delete"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Object:")
|
||||
col.operator("object.duplicate_move")
|
||||
col.operator("object.delete")
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
row.operator("wm.call_menu", text="", single_unit=False, shortcut=False, icon='ADD').name = 'INFO_MT_add'
|
||||
row.operator("object.duplicate_move", text="", shortcut=False, single_unit=False, icon='DUP')
|
||||
row.operator("object.duplicate_move_linked", text="", shortcut=False, single_unit=False, icon='DUP_LINKED')
|
||||
row.operator("object.delete", text="", shortcut=False, single_unit=False, icon='DELETE')
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.operator("object.join")
|
||||
|
||||
active_object = context.active_object
|
||||
if active_object and active_object.type in {'MESH', 'CURVE', 'SURFACE'}:
|
||||
class VIEW3D_PT_tools_objectmode_adjust(View3DPanel, Panel):
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Adjust"
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Shading:")
|
||||
row = col.row(align=True)
|
||||
row.operator("object.shade_smooth", text="Smooth")
|
||||
row.operator("object.shade_flat", text="Flat")
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
#active_object = context.active_object
|
||||
#if active_object and active_object.type in {'MESH', 'CURVE', 'SURFACE'}:
|
||||
col = layout.column(align=True)
|
||||
col.operator("object.shade_smooth", text="Shade smooth")
|
||||
col.operator("object.shade_flat", text="Shade flat")
|
||||
|
||||
VIEW3D_PT_tools_objectmode_history = history_panel("objectmode")
|
||||
|
||||
draw_keyframing_tools(context, layout)
|
||||
class VIEW3D_PT_tools_objectmode_animation(View3DPanel, Panel):
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Animation"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Motion Paths:")
|
||||
row = col.row(align=True)
|
||||
row.operator("object.paths_calculate", text="Calculate")
|
||||
row.operator("object.paths_clear", text="Clear")
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
|
||||
draw_repeat_tools(context, layout)
|
||||
|
||||
draw_gpencil_tools(context, layout)
|
||||
row.operator("anim.keyframe_insert_menu", text="", single_unit=False, shortcut=False, icon='KEY_HLT')
|
||||
row.operator("anim.keyframe_delete_v3d", text="", single_unit=False, shortcut=False, icon='KEY_DEHLT')
|
||||
|
||||
col.operator("object.paths_calculate", text="Calculate motion")
|
||||
col.operator("object.paths_clear", text="Clear motion")
|
||||
|
||||
class VIEW3D_PT_tools_rigidbody(View3DPanel, Panel):
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Rigid Body Tools"
|
||||
bl_label = "Rigid Body"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
@@ -139,86 +145,118 @@ class VIEW3D_PT_tools_rigidbody(View3DPanel, Panel):
|
||||
col.label(text="Constraints:")
|
||||
col.operator("rigidbody.connect", text="Connect")
|
||||
|
||||
|
||||
# ********** default tools for editmode_mesh ****************
|
||||
|
||||
# VIEW3D_PT_tools_editmode_modes = switch_panel("mesh_edit");
|
||||
|
||||
class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
|
||||
class VIEW3D_PT_tools_editmode_transform(View3DPanel, Panel):
|
||||
bl_context = "mesh_edit"
|
||||
bl_label = "Mesh Tools"
|
||||
bl_label = "Transform"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Transform:")
|
||||
col.operator("transform.translate")
|
||||
col.operator("transform.rotate")
|
||||
col.operator("transform.resize", text="Scale")
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
row.operator("transform.translate", text="", single_unit=False, icon='MAN_TRANS', shortcut=False)
|
||||
row.operator("transform.rotate", text="", single_unit=False, icon='MAN_ROT', shortcut=False)
|
||||
row.operator("transform.resize", text="", single_unit=False, icon='MAN_SCALE', shortcut=False)
|
||||
col.operator("transform.shrink_fatten", text="Shrink/Fatten")
|
||||
col.operator("transform.push_pull", text="Push/Pull")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Deform:")
|
||||
row = col.row(align=True)
|
||||
row.operator("transform.edge_slide", text="Slide Edge")
|
||||
row.operator("transform.vert_slide", text="Vertex")
|
||||
col.operator("mesh.noise")
|
||||
col.operator("mesh.vertices_smooth")
|
||||
col.operator("transform.edge_slide", text="Slide edge")
|
||||
col.operator("transform.vert_slide", text="Slide vertex")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Add:")
|
||||
col.operator("mesh.vertices_smooth", text="Smooth vertices")
|
||||
|
||||
col.menu("VIEW3D_MT_edit_mesh_extrude")
|
||||
col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region")
|
||||
col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
|
||||
col.operator("mesh.subdivide")
|
||||
col.operator("mesh.loopcut_slide")
|
||||
col.operator("mesh.duplicate_move", text="Duplicate")
|
||||
row = col.row(align=True)
|
||||
row.operator("mesh.spin")
|
||||
row.operator("mesh.screw")
|
||||
class VIEW3D_PT_tools_editmode_add(View3DPanel, Panel):
|
||||
bl_context = "mesh_edit"
|
||||
bl_label = "Add & Delete"
|
||||
|
||||
row = col.row(align=True)
|
||||
props = row.operator("mesh.knife_tool", text="Knife")
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
row.operator("wm.call_menu", text="", single_unit=False, shortcut=False, icon='ADD').name = 'INFO_MT_mesh_add'
|
||||
row.operator("mesh.duplicate_move", text="", single_unit=False, shortcut=False, icon='DUP')
|
||||
row.operator("wm.call_menu", text="", single_unit=False, shortcut=False, icon='DELETE').name = 'VIEW3D_MT_edit_mesh_delete'
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_editmode_mesh(View3DPanel, Panel):
|
||||
bl_context = "mesh_edit"
|
||||
bl_label = "Mesh"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
row.operator("view3d.edit_mesh_extrude_move_normal", text="", single_unit=False, shortcut=False)
|
||||
row.operator("view3d.edit_mesh_extrude_individual_move", text="", single_unit=False, shortcut=False)
|
||||
col.operator("wm.call_menu", text="Extrude...", single_unit=False, shortcut=False).name = 'VIEW3D_MT_edit_mesh_extrude'
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True, button_height=1.5)
|
||||
|
||||
props = row.operator("mesh.knife_tool", text="", single_unit=False, shortcut=False, icon='KNIFE')
|
||||
props.use_occlude_geometry = True
|
||||
props.only_selected = False
|
||||
props = row.operator("mesh.knife_tool", text="Select")
|
||||
|
||||
row.operator("mesh.loopcut_slide", text="", single_unit=False, shortcut=False, icon='LOOPCUT')
|
||||
|
||||
props = col.operator("mesh.knife_tool", text="Knife select")
|
||||
props.use_occlude_geometry = False
|
||||
props.only_selected = True
|
||||
|
||||
col.operator("mesh.knife_project")
|
||||
col.operator("mesh.bisect")
|
||||
col.operator("mesh.subdivide")
|
||||
col.operator("mesh.spin")
|
||||
col.operator("mesh.screw")
|
||||
col.operator("mesh.bisect") # NOTE: new op?
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Remove:")
|
||||
col.menu("VIEW3D_MT_edit_mesh_delete")
|
||||
col.operator_menu_enum("mesh.merge", "type")
|
||||
col.operator("mesh.remove_doubles")
|
||||
# col.operator_enum("mesh.merge", "type")
|
||||
col.operator("mesh.merge", text="Merge...")
|
||||
|
||||
class VIEW3D_PT_tools_editmode_adjust(View3DPanel, Panel):
|
||||
bl_context = "mesh_edit"
|
||||
bl_label = "Adjust"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column(align=True)
|
||||
col.operator("mesh.faces_shade_smooth", text="Smooth faces")
|
||||
col.operator("mesh.faces_shade_flat", text="Flat faces")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Normals:")
|
||||
col.operator("mesh.normals_make_consistent", text="Recalculate")
|
||||
col.operator("mesh.flip_normals", text="Flip Direction")
|
||||
col.operator("mesh.normals_make_consistent", text="Recalculate normals")
|
||||
col.operator("mesh.flip_normals", text="Flip normals")
|
||||
|
||||
class VIEW3D_PT_tools_editmode_uv(View3DPanel, Panel):
|
||||
bl_context = "mesh_edit"
|
||||
bl_label = "UV & Seams"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="UV Mapping:")
|
||||
col.menu("VIEW3D_MT_uv_map", text="Unwrap")
|
||||
col.operator("mesh.mark_seam").clear = False
|
||||
col.operator("mesh.mark_seam", text="Clear Seam").clear = True
|
||||
col.operator("wm.call_menu", text="Unwrap...", single_unit=False, shortcut=False).name = 'VIEW3D_MT_uv_map'
|
||||
col.operator("mesh.mark_seam", text="Mark seam").clear = False
|
||||
col.operator("mesh.mark_seam", text="Clear seam").clear = True
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Shading:")
|
||||
row = col.row(align=True)
|
||||
row.operator("mesh.faces_shade_smooth", text="Smooth")
|
||||
row.operator("mesh.faces_shade_flat", text="Flat")
|
||||
|
||||
draw_repeat_tools(context, layout)
|
||||
|
||||
draw_gpencil_tools(context, layout)
|
||||
VIEW3D_PT_tools_editmode_history = history_panel("mesh_edit")
|
||||
|
||||
# print(VIEW3D_PT_tools_editmode_history.bl_context)
|
||||
|
||||
class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
|
||||
bl_context = "mesh_edit"
|
||||
bl_label = "Mesh Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -252,6 +290,7 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for editmode_curve ****************
|
||||
|
||||
# VIEW3D_PT_tools_curvemode_modes = switch_panel("curve_edit");
|
||||
|
||||
class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
|
||||
bl_context = "curve_edit"
|
||||
@@ -300,6 +339,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for editmode_surface ****************
|
||||
|
||||
# VIEW3D_PT_tools_surfacemode_modes = switch_panel("surface_edit");
|
||||
|
||||
class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
|
||||
bl_context = "surface_edit"
|
||||
@@ -332,6 +372,7 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for editmode_text ****************
|
||||
|
||||
# VIEW3D_PT_tools_textmode_modes = switch_panel("text_edit");
|
||||
|
||||
class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
|
||||
bl_context = "text_edit"
|
||||
@@ -362,6 +403,7 @@ class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for editmode_armature ****************
|
||||
|
||||
# VIEW3D_PT_tools_armaturemode_modes = switch_panel("armature_edit");
|
||||
|
||||
class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
|
||||
bl_context = "armature_edit"
|
||||
@@ -391,7 +433,6 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
|
||||
|
||||
draw_gpencil_tools(context, layout)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
|
||||
bl_context = "armature_edit"
|
||||
bl_label = "Armature Options"
|
||||
@@ -403,6 +444,7 @@ class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for editmode_mball ****************
|
||||
|
||||
# VIEW3D_PT_tools_mballmode_modes = switch_panel("mball_edit");
|
||||
|
||||
class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
|
||||
bl_context = "mball_edit"
|
||||
@@ -423,6 +465,7 @@ class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for editmode_lattice ****************
|
||||
|
||||
# VIEW3D_PT_tools_latticemode_modes = switch_panel("lattice_edit");
|
||||
|
||||
class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
|
||||
bl_context = "lattice_edit"
|
||||
@@ -444,9 +487,9 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
|
||||
|
||||
draw_gpencil_tools(context, layout)
|
||||
|
||||
|
||||
# ********** default tools for pose-mode ****************
|
||||
|
||||
# VIEW3D_PT_tools_posemode_modes = switch_panel("posemode");
|
||||
|
||||
class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
|
||||
bl_context = "posemode"
|
||||
@@ -489,7 +532,6 @@ class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
|
||||
|
||||
draw_gpencil_tools(context, layout)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
|
||||
bl_context = "posemode"
|
||||
bl_label = "Pose Options"
|
||||
@@ -501,12 +543,14 @@ class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
|
||||
|
||||
# ********** default tools for paint modes ****************
|
||||
|
||||
# VIEW3D_PT_tools_imagepaint_modes = switch_panel("imagepaint");
|
||||
# VIEW3D_PT_tools_weightpaint_modes = switch_panel("weightpaint");
|
||||
# VIEW3D_PT_tools_vertexpaint_modes = switch_panel("vertexpaint");
|
||||
|
||||
class View3DPaintPanel(UnifiedPaintPanel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
bl_label = "Brush"
|
||||
|
||||
@@ -523,6 +567,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
|
||||
if not context.particle_edit_object:
|
||||
col = layout.split().column()
|
||||
# col.template_ID_preview_compact(settings, "brush", new="brush.add", rows=5, cols=8)
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
|
||||
|
||||
# Particle Mode #
|
||||
@@ -532,7 +577,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
layout.column().prop(settings, "tool", expand=True)
|
||||
|
||||
if tool != 'NONE':
|
||||
col = layout.column()
|
||||
col = layout.column(align=True)
|
||||
col.prop(brush, "size", slider=True)
|
||||
if tool != 'ADD':
|
||||
col.prop(brush, "strength", slider=True)
|
||||
@@ -556,7 +601,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
elif context.sculpt_object and brush:
|
||||
capabilities = brush.sculpt_capabilities
|
||||
|
||||
col = layout.column()
|
||||
col = layout.column(align=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
@@ -575,7 +620,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
|
||||
# strength, use_strength_pressure, and use_strength_attenuation
|
||||
if capabilities.has_strength:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
|
||||
if capabilities.has_space_attenuation:
|
||||
@@ -589,27 +633,22 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
|
||||
# auto_smooth_factor and use_inverse_smooth_pressure
|
||||
if capabilities.has_auto_smooth:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "auto_smooth_factor", slider=True)
|
||||
row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
|
||||
|
||||
# normal_weight
|
||||
if capabilities.has_normal_weight:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "normal_weight", slider=True)
|
||||
|
||||
# crease_pinch_factor
|
||||
if capabilities.has_pinch_factor:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
|
||||
|
||||
# use_original_normal and sculpt_plane
|
||||
if capabilities.has_sculpt_plane:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
|
||||
if brush.use_original_normal:
|
||||
@@ -624,7 +663,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
|
||||
# plane_offset, use_offset_pressure, use_plane_trim, plane_trim
|
||||
if capabilities.has_plane_offset:
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "plane_offset", slider=True)
|
||||
row.prop(brush, "use_offset_pressure", text="")
|
||||
|
||||
@@ -674,14 +712,11 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
col.operator("sculpt.set_persistent_base")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Overlay:")
|
||||
|
||||
|
||||
row = col.row(align=True)
|
||||
if brush.use_cursor_overlay:
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="",
|
||||
icon=('RESTRICT_VIEW_OFF' if brush.use_cursor_overlay else 'RESTRICT_VIEW_ON'))
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
|
||||
sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
|
||||
@@ -695,6 +730,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
col.template_color_picker(brush, "color", value_slider=True)
|
||||
col.prop(brush, "color", text="")
|
||||
|
||||
col = layout.column(align=True)
|
||||
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
|
||||
self.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
@@ -703,29 +740,26 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
col.prop(brush, "blend", text="")
|
||||
|
||||
col = layout.column()
|
||||
col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
|
||||
col.prop(brush, "use_alpha")
|
||||
col.prop(brush, "use_alpha", text="Use Alpha")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Overlay:")
|
||||
|
||||
row = col.row(align=True)
|
||||
if brush.use_cursor_overlay:
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="",
|
||||
icon=('RESTRICT_VIEW_OFF' if brush.use_cursor_overlay else 'RESTRICT_VIEW_ON'))
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
|
||||
sub.prop(brush, "cursor_overlay_alpha", text="Overlay")
|
||||
sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
|
||||
|
||||
# Weight Paint Mode #
|
||||
elif context.weight_paint_object and brush:
|
||||
|
||||
col = layout.column()
|
||||
col = layout.column(align=True)
|
||||
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_weight(row, context, brush, "weight", slider=True, text="Weight")
|
||||
@@ -738,9 +772,9 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
col.prop(brush, "vertex_tool", text="Blend")
|
||||
col.prop(brush, "vertex_tool", text="")
|
||||
|
||||
col = layout.column()
|
||||
col = layout.column(align=True)
|
||||
col.prop(toolsettings, "use_auto_normalize", text="Auto Normalize")
|
||||
col.prop(toolsettings, "use_multipaint", text="Multi-Paint")
|
||||
|
||||
@@ -750,6 +784,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
col.template_color_picker(brush, "color", value_slider=True)
|
||||
col.prop(brush, "color", text="")
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
|
||||
self.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
@@ -758,27 +793,24 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
col.prop(brush, "vertex_tool", text="")
|
||||
|
||||
# XXX - TODO
|
||||
#row = col.row(align=True)
|
||||
#row.prop(brush, "jitter", slider=True)
|
||||
#row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "vertex_tool", text="Blend")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Overlay:")
|
||||
# col.label(text="Overlay:")
|
||||
|
||||
row = col.row(align=True)
|
||||
if brush.use_cursor_overlay:
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
|
||||
row.prop(brush, "use_cursor_overlay", toggle=True, text="",
|
||||
icon=('RESTRICT_VIEW_OFF' if brush.use_cursor_overlay else 'RESTRICT_VIEW_ON'))
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
|
||||
sub.prop(brush, "cursor_overlay_alpha", text="Overlay")
|
||||
sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
||||
bl_label = "Texture"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -798,65 +830,27 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
|
||||
col.template_ID_preview_compact(brush, "texture", new="texture.new", rows=3, cols=8)
|
||||
|
||||
col.separator()
|
||||
|
||||
brush_texture_settings(col, brush, context.sculpt_object)
|
||||
|
||||
# use_texture_overlay and texture_overlay_alpha
|
||||
col = layout.column(align=True)
|
||||
col.active = brush.brush_capabilities.has_overlay
|
||||
col.label(text="Overlay:")
|
||||
|
||||
|
||||
row = col.row(align=True)
|
||||
if tex_slot.map_mode != 'STENCIL':
|
||||
if brush.use_primary_overlay:
|
||||
row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
row.prop(brush, "use_primary_overlay", toggle=True, text="",
|
||||
icon='RESTRICT_VIEW_OFF' if brush.use_primary_overlay else 'RESTRICT_VIEW_ON')
|
||||
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.prop(brush, "texture_overlay_alpha", text="Alpha")
|
||||
sub.prop(brush, "texture_overlay_alpha", text="Overlay")
|
||||
sub.prop(brush, "use_primary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
|
||||
bl_context = "imagepaint"
|
||||
bl_label = "Texture Mask"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
return (context.image_paint_object and brush)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
tex_slot_alpha = brush.mask_texture_slot
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.template_ID_preview(brush, "mask_texture", new="texture.new", rows=3, cols=8)
|
||||
|
||||
brush_mask_texture_settings(col, brush)
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = brush.brush_capabilities.has_overlay
|
||||
col.label(text="Overlay:")
|
||||
|
||||
row = col.row(align=True)
|
||||
if tex_slot_alpha.map_mode != 'STENCIL':
|
||||
if brush.use_secondary_overlay:
|
||||
row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.prop(brush, "mask_overlay_alpha", text="Alpha")
|
||||
sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
bl_label = "Stroke"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -879,31 +873,34 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.label(text="Stroke Method:")
|
||||
row = col.row()
|
||||
row.label(text="Method:")
|
||||
|
||||
if context.sculpt_object:
|
||||
col.prop(brush, "sculpt_stroke_method", text="")
|
||||
row.prop(brush, "sculpt_stroke_method", text="")
|
||||
else:
|
||||
col.prop(brush, "stroke_method", text="")
|
||||
row.prop(brush, "stroke_method", text="")
|
||||
|
||||
col = layout.column(align=True)
|
||||
|
||||
if brush.use_anchor:
|
||||
col.separator()
|
||||
# col.separator()
|
||||
col.prop(brush, "use_edge_to_edge", "Edge To Edge")
|
||||
|
||||
if brush.use_airbrush:
|
||||
col.separator()
|
||||
# col.separator()
|
||||
col.prop(brush, "rate", text="Rate", slider=True)
|
||||
|
||||
if brush.use_space:
|
||||
col.separator()
|
||||
# col.separator()
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
# col.separator()
|
||||
if context.sculpt_object:
|
||||
if brush.sculpt_capabilities.has_jitter:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
if brush.use_relative_jitter:
|
||||
@@ -914,9 +911,9 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
if brush.sculpt_capabilities.has_smooth_stroke:
|
||||
col = layout.column()
|
||||
# smooth stroke
|
||||
col = layout.column(align=True)
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
|
||||
sub = col.column()
|
||||
@@ -924,8 +921,6 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
else:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
if brush.use_relative_jitter:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
@@ -935,7 +930,8 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col = layout.column()
|
||||
# smooth stroke
|
||||
col = layout.column(align=True)
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
@@ -945,7 +941,6 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
|
||||
bl_label = "Curve"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -972,6 +967,42 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
|
||||
row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE'
|
||||
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
|
||||
|
||||
class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
|
||||
bl_context = "imagepaint"
|
||||
bl_label = "Texture Mask"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
return (context.image_paint_object and brush)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
tex_slot_alpha = brush.mask_texture_slot
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.template_ID_preview(brush, "mask_texture", new="texture.new", rows=3, cols=8)
|
||||
|
||||
brush_mask_texture_settings(col, brush)
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = brush.brush_capabilities.has_overlay
|
||||
col.label(text="Overlay:")
|
||||
|
||||
row = col.row()
|
||||
if tex_slot_alpha.map_mode != 'STENCIL':
|
||||
if brush.use_secondary_overlay:
|
||||
row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
|
||||
sub = row.row()
|
||||
sub.prop(brush, "mask_overlay_alpha", text="Alpha")
|
||||
sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
|
||||
|
||||
class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
|
||||
bl_label = "Topology"
|
||||
@@ -1002,7 +1033,6 @@ class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
|
||||
col.prop(sculpt, "symmetrize_direction")
|
||||
col.operator("sculpt.symmetrize")
|
||||
|
||||
|
||||
class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
|
||||
bl_label = "Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -1032,7 +1062,6 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
|
||||
|
||||
self.unified_paint_settings(layout, context)
|
||||
|
||||
|
||||
class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
|
||||
bl_label = "Symmetry"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -1056,7 +1085,6 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
|
||||
layout.column().prop(sculpt, "radial_symmetry", text="Radial")
|
||||
layout.prop(sculpt, "use_symmetry_feather", text="Feather")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
|
||||
bl_label = "Appearance"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -1103,7 +1131,6 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
|
||||
|
||||
# ********** default tools for weight-paint ****************
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
|
||||
bl_context = "weightpaint"
|
||||
bl_label = "Weight Tools"
|
||||
@@ -1111,7 +1138,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column()
|
||||
col = layout.column(align=True)
|
||||
col.operator("object.vertex_group_normalize_all", text="Normalize All")
|
||||
col.operator("object.vertex_group_normalize", text="Normalize")
|
||||
col.operator("object.vertex_group_mirror", text="Mirror")
|
||||
@@ -1124,10 +1151,10 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
|
||||
col.operator("object.vertex_group_fix", text="Fix Deforms")
|
||||
col.operator("paint.weight_gradient")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
|
||||
bl_context = "weightpaint"
|
||||
bl_label = "Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1161,10 +1188,10 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
|
||||
|
||||
# ********** default tools for vertex-paint ****************
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
|
||||
class VIEW3D_PT_tools_vertexpaint_options(Panel, View3DPaintPanel):
|
||||
bl_context = "vertexpaint"
|
||||
bl_label = "Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1252,7 +1279,6 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
|
||||
col.operator("paint.project_image", text="Apply Camera Image")
|
||||
col.operator("image.save_dirty", text="Save All Edited")
|
||||
|
||||
|
||||
class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
|
||||
bl_label = "Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -1267,7 +1293,6 @@ class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
|
||||
col = layout.column()
|
||||
self.unified_paint_settings(col, context)
|
||||
|
||||
|
||||
class VIEW3D_MT_tools_projectpaint_clone(Menu):
|
||||
bl_label = "Clone Layer"
|
||||
|
||||
@@ -1279,7 +1304,6 @@ class VIEW3D_MT_tools_projectpaint_clone(Menu):
|
||||
props.data_path = "active_object.data.uv_texture_clone_index"
|
||||
props.value = i
|
||||
|
||||
|
||||
class VIEW3D_MT_tools_projectpaint_stencil(Menu):
|
||||
bl_label = "Mask Layer"
|
||||
|
||||
@@ -1290,7 +1314,6 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu):
|
||||
props.data_path = "active_object.data.uv_texture_stencil_index"
|
||||
props.value = i
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
|
||||
"""Default tools for particle mode"""
|
||||
bl_context = "particlemode"
|
||||
|
@@ -62,6 +62,7 @@ struct ReportList;
|
||||
struct Scene;
|
||||
struct Main;
|
||||
struct ID;
|
||||
struct wmOperator;
|
||||
|
||||
int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *reports);
|
||||
|
||||
@@ -91,10 +92,12 @@ int blender_test_break(void);
|
||||
|
||||
/* global undo */
|
||||
extern void BKE_write_undo(struct bContext *C, const char *name);
|
||||
extern void BKE_write_undo_op(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
extern void BKE_undo_step(struct bContext *C, int step);
|
||||
extern void BKE_undo_op(struct bContext *C, const struct wmOperator *op);
|
||||
extern void BKE_undo_name(struct bContext *C, const char *name);
|
||||
extern int BKE_undo_valid(const char *name);
|
||||
extern void BKE_reset_undo(void);
|
||||
extern void BKE_reset_undo(struct bContext *C);
|
||||
extern void BKE_undo_number(struct bContext *C, int nr);
|
||||
extern const char *BKE_undo_get_name(int nr, int *active);
|
||||
extern int BKE_undo_save_file(const char *filename);
|
||||
|
@@ -36,6 +36,7 @@
|
||||
struct ARegion;
|
||||
struct Header;
|
||||
struct ListBase;
|
||||
struct OperatorListItem;
|
||||
struct Menu;
|
||||
struct Panel;
|
||||
struct Scene;
|
||||
@@ -150,6 +151,9 @@ typedef struct ARegionType {
|
||||
/* header type definitions */
|
||||
ListBase headertypes;
|
||||
|
||||
/* toolbar menu type definitions */
|
||||
ListBase menubartypes;
|
||||
|
||||
/* hardcoded constraints, smaller than these values region is not visible */
|
||||
int minsizex, minsizey;
|
||||
/* when new region opens (region prefsizex/y are zero then */
|
||||
@@ -257,6 +261,29 @@ typedef struct Menu {
|
||||
struct uiLayout *layout; /* runtime for drawing */
|
||||
} Menu;
|
||||
|
||||
/* menu bar types */
|
||||
|
||||
typedef struct MenuBar {
|
||||
struct MenuBarType *type; /* runtime */
|
||||
struct uiLayout *layout; /* runtime for drawing */
|
||||
} MenuBar;
|
||||
|
||||
typedef struct MenuBarType {
|
||||
struct MenuBarType *next, *prev;
|
||||
|
||||
char idname[BKE_ST_MAXNAME]; /* unique name */
|
||||
char context[BKE_ST_MAXNAME];
|
||||
|
||||
int space_type;
|
||||
int region_type;
|
||||
|
||||
/* draw entirely, view changes should be handled here */
|
||||
void (*draw)(const struct bContext *, struct MenuBar *);
|
||||
|
||||
/* RNA integration */
|
||||
ExtensionRNA ext;
|
||||
} MenuBarType;
|
||||
|
||||
/* spacetypes */
|
||||
struct SpaceType *BKE_spacetype_from_id(int spaceid);
|
||||
struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid);
|
||||
@@ -277,6 +304,7 @@ void BKE_screen_area_free(struct ScrArea *sa);
|
||||
|
||||
struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
|
||||
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
|
||||
struct ARegion *BKE_spacelink_find_region_type(struct SpaceLink *sl, int type);
|
||||
struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min);
|
||||
|
||||
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);
|
||||
@@ -291,5 +319,8 @@ float BKE_screen_view3d_zoom_from_fac(float zoomfac);
|
||||
void BKE_screen_free(struct bScreen *sc);
|
||||
unsigned int BKE_screen_visible_layers(struct bScreen *screen, struct Scene *scene);
|
||||
|
||||
/* custom operator button items */
|
||||
void BKE_operator_list_item_free(struct OperatorListItem *oli);
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -94,6 +94,7 @@
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie
|
||||
#include "WM_types.h" // This is temporarily necessary until the undo stacks are integrated and operators are an integral part of it ~ ack-err
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
@@ -558,8 +559,11 @@ int blender_test_break(void)
|
||||
|
||||
#define UNDO_DISK 0
|
||||
|
||||
/* N.B. the pointer to the wmOperator needs to be third so that it
|
||||
* maps correctly to the UndoElem in wm.c. This is far from pretty. */
|
||||
typedef struct UndoElem {
|
||||
struct UndoElem *next, *prev;
|
||||
wmOperator * op;
|
||||
char str[FILE_MAX];
|
||||
char name[BKE_UNDO_STR_MAX];
|
||||
MemFile memfile;
|
||||
@@ -574,6 +578,7 @@ static int read_undosave(bContext *C, UndoElem *uel)
|
||||
{
|
||||
char mainstr[sizeof(G.main->name)];
|
||||
int success = 0, fileflags;
|
||||
ListBase included_ops;
|
||||
|
||||
/* This is needed so undoing/redoing doesn't crash with threaded previews going */
|
||||
WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
|
||||
@@ -592,6 +597,10 @@ static int read_undosave(bContext *C, UndoElem *uel)
|
||||
BLI_strncpy(G.main->name, mainstr, sizeof(G.main->name)); /* restore */
|
||||
G.fileflags = fileflags;
|
||||
|
||||
included_ops.first = undobase.first;
|
||||
included_ops.last = uel;
|
||||
WM_operator_build_stack(C, &included_ops, true);
|
||||
|
||||
if (success) {
|
||||
/* important not to update time here, else non keyed tranforms are lost */
|
||||
DAG_on_visible_update(G.main, FALSE);
|
||||
@@ -600,13 +609,18 @@ static int read_undosave(bContext *C, UndoElem *uel)
|
||||
return success;
|
||||
}
|
||||
|
||||
/* name can be a dynamic string */
|
||||
void BKE_write_undo(bContext *C, const char *name)
|
||||
{
|
||||
BKE_write_undo_op(C, name, NULL);
|
||||
}
|
||||
|
||||
/* name can be a dynamic string */
|
||||
void BKE_write_undo_op(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
uintptr_t maxmem, totmem, memused;
|
||||
int nr /*, success */ /* UNUSED */;
|
||||
UndoElem *uel;
|
||||
|
||||
|
||||
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -620,6 +634,10 @@ void BKE_write_undo(bContext *C, const char *name)
|
||||
uel = undobase.last;
|
||||
BLI_remlink(&undobase, uel);
|
||||
BLO_free_memfile(&uel->memfile);
|
||||
/* Don't remove the op if it is a repeat, and the
|
||||
* uel->op is the same as the function's argument op. */
|
||||
if(uel->op && uel->op != op)
|
||||
WM_operator_free(uel->op);
|
||||
MEM_freeN(uel);
|
||||
}
|
||||
|
||||
@@ -627,6 +645,9 @@ void BKE_write_undo(bContext *C, const char *name)
|
||||
curundo = uel = MEM_callocN(sizeof(UndoElem), "undo file");
|
||||
BLI_strncpy(uel->name, name, sizeof(uel->name));
|
||||
BLI_addtail(&undobase, uel);
|
||||
if (op && op->type && op->type->flag & OPTYPE_REGISTER && op->type->flag & OPTYPE_UNDO) {
|
||||
uel->op = op;
|
||||
}
|
||||
|
||||
/* and limit amount to the maximum */
|
||||
nr = 0;
|
||||
@@ -642,6 +663,8 @@ void BKE_write_undo(bContext *C, const char *name)
|
||||
BLI_remlink(&undobase, first);
|
||||
/* the merge is because of compression */
|
||||
BLO_merge_memfile(&first->memfile, &first->next->memfile);
|
||||
if(first->op)
|
||||
WM_operator_free(first->op);
|
||||
MEM_freeN(first);
|
||||
}
|
||||
}
|
||||
@@ -697,10 +720,16 @@ void BKE_write_undo(bContext *C, const char *name)
|
||||
BLI_remlink(&undobase, first);
|
||||
/* the merge is because of compression */
|
||||
BLO_merge_memfile(&first->memfile, &first->next->memfile);
|
||||
if (first->op) {
|
||||
WM_operator_free(first->op);
|
||||
first->op = NULL;
|
||||
}
|
||||
MEM_freeN(first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WM_operator_build_stack(C, &undobase, true);
|
||||
}
|
||||
|
||||
/* 1 = an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
|
||||
@@ -735,18 +764,22 @@ void BKE_undo_step(bContext *C, int step)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_reset_undo(void)
|
||||
void BKE_reset_undo(bContext *C)
|
||||
{
|
||||
UndoElem *uel;
|
||||
|
||||
uel = undobase.first;
|
||||
while (uel) {
|
||||
BLO_free_memfile(&uel->memfile);
|
||||
if(uel->op)
|
||||
WM_operator_free(uel->op);
|
||||
uel = uel->next;
|
||||
}
|
||||
|
||||
BLI_freelistN(&undobase);
|
||||
curundo = NULL;
|
||||
|
||||
WM_operator_build_stack(C, &undobase, false);
|
||||
}
|
||||
|
||||
/* based on index nr it does a restore */
|
||||
@@ -756,17 +789,39 @@ void BKE_undo_number(bContext *C, int nr)
|
||||
BKE_undo_step(C, 0);
|
||||
}
|
||||
|
||||
/* go back to the last occurance of name in stack */
|
||||
void BKE_undo_name(bContext *C, const char *name)
|
||||
/* go back to the last occurance of the given name, or the
|
||||
* given operator */
|
||||
static void undo_op_name(bContext *C, const wmOperator *op, const char *name)
|
||||
{
|
||||
UndoElem *uel = BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
|
||||
|
||||
ListBase included_ops;
|
||||
UndoElem *uel;
|
||||
included_ops.first = undobase.first;
|
||||
included_ops.last = curundo ? curundo : undobase.last;
|
||||
|
||||
if(op)
|
||||
uel = BLI_findptr(&included_ops, op, offsetof(UndoElem, op));
|
||||
else
|
||||
uel = BLI_rfindstring(&included_ops, name, offsetof(UndoElem, name));
|
||||
|
||||
if (uel && uel->prev) {
|
||||
curundo = uel->prev;
|
||||
BKE_undo_step(C, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* go back to the last occurance of name in stack */
|
||||
void BKE_undo_name(bContext *C, const char *name)
|
||||
{
|
||||
undo_op_name(C, NULL, name);
|
||||
}
|
||||
|
||||
|
||||
/* go back to the last occurance of the given operator */
|
||||
void BKE_undo_op(bContext *C, const wmOperator *op)
|
||||
{
|
||||
undo_op_name(C, op, NULL);
|
||||
}
|
||||
|
||||
/* name optional */
|
||||
int BKE_undo_valid(const char *name)
|
||||
{
|
||||
|
@@ -75,6 +75,7 @@ static void spacetype_free(SpaceType *st)
|
||||
|
||||
BLI_freelistN(&art->paneltypes);
|
||||
BLI_freelistN(&art->headertypes);
|
||||
BLI_freelistN(&art->menubartypes);
|
||||
}
|
||||
|
||||
BLI_freelistN(&st->regiontypes);
|
||||
@@ -268,7 +269,9 @@ void BKE_spacedata_draw_locks(int set)
|
||||
/* not region itself */
|
||||
void BKE_area_region_free(SpaceType *st, ARegion *ar)
|
||||
{
|
||||
Panel *pa;
|
||||
uiList *uilst;
|
||||
OperatorListItem *oli;
|
||||
|
||||
if (st) {
|
||||
ARegionType *art = BKE_regiontype_from_id(st, ar->regiontype);
|
||||
@@ -286,6 +289,12 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
|
||||
MEM_freeN(ar->v2d.tab_offset);
|
||||
ar->v2d.tab_offset = NULL;
|
||||
}
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
for (oli = pa->operators.first; oli; oli = oli->next) {
|
||||
BKE_operator_list_item_free(oli);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_freelistN(&ar->panels);
|
||||
|
||||
@@ -306,6 +315,10 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&ar->ui_lists);
|
||||
|
||||
for (oli = ar->operators.first; oli; oli = oli->next) {
|
||||
BKE_operator_list_item_free(oli);
|
||||
}
|
||||
}
|
||||
|
||||
/* not area itself */
|
||||
@@ -364,6 +377,15 @@ unsigned int BKE_screen_visible_layers(bScreen *screen, Scene *scene)
|
||||
return layer;
|
||||
}
|
||||
|
||||
/* Including the OperatorListItem */
|
||||
void BKE_operator_list_item_free(OperatorListItem *oli) {
|
||||
if (oli->properties) {
|
||||
IDP_FreeProperty(oli->properties);
|
||||
MEM_freeN(oli->properties);
|
||||
}
|
||||
MEM_freeN(oli);
|
||||
}
|
||||
|
||||
/* ***************** Utilities ********************** */
|
||||
|
||||
/* Find a region of the specified type from the given area */
|
||||
@@ -394,6 +416,20 @@ ARegion *BKE_area_find_region_active_win(ScrArea *sa)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find a region of the specified type from the given area */
|
||||
ARegion *BKE_spacelink_find_region_type(SpaceLink *sl, int type)
|
||||
{
|
||||
if (sl) {
|
||||
ARegion *ar;
|
||||
|
||||
for (ar = sl->regionbase.first; ar; ar = ar->next) {
|
||||
if (ar->regiontype == type)
|
||||
return ar;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* note, using this function is generally a last resort, you really want to be
|
||||
* using the context when you can - campbell
|
||||
* -1 for any type */
|
||||
|
@@ -6109,6 +6109,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
||||
{
|
||||
Panel *pa;
|
||||
uiList *ui_list;
|
||||
OperatorListItem *oli;
|
||||
|
||||
link_list(fd, &ar->panels);
|
||||
|
||||
@@ -6117,6 +6118,14 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
||||
pa->runtime_flag = 0;
|
||||
pa->activedata = NULL;
|
||||
pa->type = NULL;
|
||||
|
||||
link_list(fd, &pa->operators);
|
||||
|
||||
for (oli = pa->operators.first; oli; oli = oli->next) {
|
||||
oli->properties = newdataadr(fd, oli->properties);
|
||||
if (oli->properties)
|
||||
IDP_DirectLinkProperty(oli->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
||||
}
|
||||
}
|
||||
|
||||
link_list(fd, &ar->ui_lists);
|
||||
@@ -6128,6 +6137,14 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
||||
if (ui_list->properties)
|
||||
IDP_DirectLinkProperty(ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
||||
}
|
||||
|
||||
link_list(fd, &ar->operators);
|
||||
|
||||
for (oli = ar->operators.first; oli; oli = oli->next) {
|
||||
oli->properties = newdataadr(fd, oli->properties);
|
||||
if (oli->properties)
|
||||
IDP_DirectLinkProperty(oli->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
||||
}
|
||||
|
||||
if (spacetype == SPACE_EMPTY) {
|
||||
/* unkown space type, don't leak regiondata */
|
||||
@@ -6164,6 +6181,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
||||
ar->swap = 0;
|
||||
ar->do_draw = FALSE;
|
||||
ar->regiontimer = NULL;
|
||||
ar->dragdata = NULL;
|
||||
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
|
||||
}
|
||||
|
||||
@@ -9555,7 +9573,53 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: what is the right version here?
|
||||
if (MAIN_VERSION_OLDER(main, 268, 3)) {
|
||||
bScreen *sc;
|
||||
|
||||
for (sc = main->screen.first; sc; sc = sc->id.next) {
|
||||
ScrArea *sa;
|
||||
|
||||
for (sa = sc->areabase.first; sa; sa = sa->next) {
|
||||
SpaceLink *sl;
|
||||
ARegion *ar;
|
||||
ARegion *before = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
|
||||
if (before && sa->spacetype == SPACE_VIEW3D) {
|
||||
|
||||
/* add operators menubar */
|
||||
ar = BKE_area_find_region_type(sa, RGN_TYPE_MENU_BAR);
|
||||
if (ar == NULL) {
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool operators menu bar for view3d");
|
||||
|
||||
BLI_insertlinkbefore(&sa->regionbase, before, ar);
|
||||
ar->regiontype = RGN_TYPE_MENU_BAR;
|
||||
ar->alignment = RGN_ALIGN_TOP;
|
||||
}
|
||||
}
|
||||
|
||||
for (sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
|
||||
ARegion *before = BKE_spacelink_find_region_type(sl, RGN_TYPE_TOOLS);
|
||||
|
||||
if (before && sl->spacetype == SPACE_VIEW3D) {
|
||||
|
||||
/* add operators menubar */
|
||||
ar = BKE_spacelink_find_region_type(sl, RGN_TYPE_MENU_BAR);
|
||||
if (ar == NULL) {
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool operators menu bar for view3d");
|
||||
|
||||
BLI_insertlinkbefore(&sl->regionbase, before, ar);
|
||||
ar->regiontype = RGN_TYPE_MENU_BAR;
|
||||
ar->alignment = RGN_ALIGN_TOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(main, 268, 1)) {
|
||||
Brush *brush;
|
||||
for (brush = main->brush.first; brush; brush = brush->id.next) {
|
||||
@@ -9618,6 +9682,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
|
||||
|
||||
|
@@ -236,15 +236,14 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
|
||||
BLI_addtail(lb, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOLS;
|
||||
ar->alignment = RGN_ALIGN_LEFT;
|
||||
ar->flag = RGN_FLAG_HIDDEN;
|
||||
|
||||
/* tool properties */
|
||||
//ar->flag = RGN_FLAG_HIDDEN;
|
||||
|
||||
/* tool props */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool properties for view3d");
|
||||
|
||||
|
||||
BLI_addtail(lb, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
ar->alignment = RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
|
||||
ar->flag = RGN_FLAG_HIDDEN;
|
||||
ar->alignment = RGN_SPLIT_PREV | RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* buttons/list view */
|
||||
ar = MEM_callocN(sizeof(ARegion), "buttons for view3d");
|
||||
@@ -253,6 +252,9 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
|
||||
ar->regiontype = RGN_TYPE_UI;
|
||||
ar->alignment = RGN_ALIGN_RIGHT;
|
||||
ar->flag = RGN_FLAG_HIDDEN;
|
||||
|
||||
/* The tool properties are added in readfile.c */
|
||||
|
||||
#if 0
|
||||
case SPACE_BUTS:
|
||||
/* context UI region */
|
||||
@@ -271,7 +273,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
|
||||
|
||||
BLI_addtail(lb, ar);
|
||||
ar->winrct = sa->totrct;
|
||||
|
||||
ar->regiontype = RGN_TYPE_WINDOW;
|
||||
|
||||
if (sl) {
|
||||
|
@@ -2368,8 +2368,26 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_operator_list_item(WriteData *wd, OperatorListItem *oli)
|
||||
{
|
||||
writestruct(wd, DATA, "OperatorListItem", 1, oli);
|
||||
|
||||
if (oli->properties) {
|
||||
IDP_WriteProperty(oli->properties, wd);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_panel(WriteData *wd, Panel *pa)
|
||||
{
|
||||
OperatorListItem *oli;
|
||||
writestruct(wd, DATA, "Panel", 1, pa);
|
||||
|
||||
for (oli = pa->operators.first; oli; oli = oli->next)
|
||||
write_operator_list_item(wd, oli);
|
||||
}
|
||||
|
||||
static void write_region(WriteData *wd, ARegion *ar, int spacetype)
|
||||
{
|
||||
{
|
||||
writestruct(wd, DATA, "ARegion", 1, ar);
|
||||
|
||||
if (ar->regiondata) {
|
||||
@@ -2474,17 +2492,21 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
|
||||
Panel *pa;
|
||||
uiList *ui_list;
|
||||
ARegion *ar;
|
||||
OperatorListItem *oli;
|
||||
|
||||
writestruct(wd, DATA, "ScrArea", 1, sa);
|
||||
|
||||
for (ar= sa->regionbase.first; ar; ar= ar->next) {
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
write_region(wd, ar, sa->spacetype);
|
||||
|
||||
for (pa= ar->panels.first; pa; pa= pa->next)
|
||||
writestruct(wd, DATA, "Panel", 1, pa);
|
||||
for (pa = ar->panels.first; pa; pa = pa->next)
|
||||
write_panel(wd, pa);
|
||||
|
||||
for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next)
|
||||
write_uilist(wd, ui_list);
|
||||
|
||||
for (oli = ar->operators.first; oli; oli = oli->next)
|
||||
write_operator_list_item(wd, oli);
|
||||
}
|
||||
|
||||
sl= sa->spacedata.first;
|
||||
|
@@ -684,28 +684,50 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
|
||||
static int armature_parent_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
PointerRNA ptr;
|
||||
|
||||
EditBone *actbone = CTX_data_active_bone(C);
|
||||
uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
|
||||
uiLayout *layout = uiPupMenuLayout(pup);
|
||||
int allchildbones = 0;
|
||||
PropertyRNA *prop;
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
|
||||
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
|
||||
{
|
||||
if (ebone != actbone) {
|
||||
if (ebone->parent != actbone) allchildbones = 1;
|
||||
}
|
||||
WM_operator_properties_create_ptr(&ptr, op->type);
|
||||
prop = RNA_struct_find_property(&ptr, "type");
|
||||
|
||||
if (prop == NULL) {
|
||||
printf("%s: %s has no enum property set\n", __func__, op->type->idname);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT);
|
||||
|
||||
/* ob becomes parent, make the associated menus */
|
||||
if (allchildbones)
|
||||
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET);
|
||||
else if (RNA_property_type(prop) != PROP_ENUM) {
|
||||
printf("%s: %s \"%s\" is not an enum property\n",
|
||||
__func__, op->type->idname, RNA_property_identifier(prop));
|
||||
}
|
||||
else if (RNA_property_is_set(op->ptr, prop)) {
|
||||
const int retval = op->type->exec(C, op);
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
return retval;
|
||||
} else {
|
||||
int allchildbones = 0;
|
||||
pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
|
||||
layout = uiPupMenuLayout(pup);
|
||||
|
||||
uiPupMenuEnd(C, pup);
|
||||
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
|
||||
{
|
||||
if (ebone != actbone) {
|
||||
if (ebone->parent != actbone) allchildbones = 1;
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT);
|
||||
|
||||
/* ob becomes parent, make the associated menus */
|
||||
if (allchildbones)
|
||||
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET);
|
||||
|
||||
uiPupMenuEnd(C, pup);
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -714,10 +715,10 @@ static void *get_armature_edit(bContext *C)
|
||||
}
|
||||
|
||||
/* and this is all the undo system needs to know */
|
||||
void undo_push_armature(bContext *C, const char *name)
|
||||
void undo_push_armature(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
// XXX solve getdata()
|
||||
undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
|
||||
undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL, op);
|
||||
}
|
||||
|
||||
/* *************************************************************** */
|
||||
|
@@ -7364,9 +7364,9 @@ static void *get_data(bContext *C)
|
||||
}
|
||||
|
||||
/* and this is all the undo system needs to know */
|
||||
void undo_push_curve(bContext *C, const char *name)
|
||||
void undo_push_curve(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
|
||||
undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL, op);
|
||||
}
|
||||
|
||||
void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count)
|
||||
|
@@ -1796,7 +1796,7 @@ static void *get_undoFont(bContext *C)
|
||||
}
|
||||
|
||||
/* and this is all the undo system needs to know */
|
||||
void undo_push_font(bContext *C, const char *name)
|
||||
void undo_push_font(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
|
||||
undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL, op);
|
||||
}
|
||||
|
@@ -56,6 +56,14 @@ if(WITH_BLENDER)
|
||||
#../../../../release/datafiles/blender_icons32.png
|
||||
#180 SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/blender_icons32.png SRC)
|
||||
#svg_to_png(../../../../release/datafiles/blender_operator_icons.svg
|
||||
#../../../../release/datafiles/blender_operator_icons16.png
|
||||
#90 SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/blender_operator_icons16.png SRC)
|
||||
#svg_to_png(../../../../release/datafiles/blender_operator_icons.svg
|
||||
#../../../../release/datafiles/blender_operator_icons32.png
|
||||
#180 SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/blender_operator_icons32.png SRC)
|
||||
#svg_to_png(../../../../release/datafiles/prvicons.svg
|
||||
#../../../../release/datafiles/prvicons.png
|
||||
#90 SRC)
|
||||
|
@@ -286,6 +286,35 @@ static void draw_gpencil_space_specials(const bContext *C, uiLayout *layout)
|
||||
}
|
||||
|
||||
/* Draw the contents for a grease-pencil panel*/
|
||||
static void draw_gpencil_operator_buttons(const bContext *C, uiLayout *layout)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
uiLayout *row;
|
||||
wmOperatorType *ot;
|
||||
|
||||
ot = WM_operatortype_find("GPENCIL_OT_draw", 0);
|
||||
row = uiLayoutRowWithButtonHeight(layout, TRUE, 1.5f);
|
||||
|
||||
ptr = uiItemFullO_ptr(row, ot, "", ICON_AUTOMATIC, NULL, uiLayoutGetOperatorContext(layout), UI_ITEM_O_RETURN_PROPS);
|
||||
RNA_enum_set(&ptr, "mode", GP_PAINTMODE_DRAW);
|
||||
|
||||
ptr = uiItemFullO_ptr(row, WM_operatortype_find("GPENCIL_OT_draw", 0), "", ICON_AUTOMATIC, NULL, uiLayoutGetOperatorContext(layout), UI_ITEM_O_RETURN_PROPS);
|
||||
RNA_enum_set(&ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT);
|
||||
|
||||
ptr = uiItemFullO_ptr(row, WM_operatortype_find("GPENCIL_OT_draw", 0), "", ICON_AUTOMATIC, NULL, uiLayoutGetOperatorContext(layout), UI_ITEM_O_RETURN_PROPS);
|
||||
RNA_enum_set(&ptr, "mode", GP_PAINTMODE_DRAW_POLY);
|
||||
|
||||
ptr = uiItemFullO_ptr(row, WM_operatortype_find("GPENCIL_OT_draw", 0), "", ICON_AUTOMATIC, NULL, uiLayoutGetOperatorContext(layout), UI_ITEM_O_RETURN_PROPS);
|
||||
RNA_enum_set(&ptr, "mode", GP_PAINTMODE_ERASER);
|
||||
|
||||
row = uiLayoutRow(layout, TRUE);
|
||||
RNA_pointer_create(NULL, &RNA_ToolSettings, CTX_data_tool_settings(C), &ptr);
|
||||
//prop = RNA_struct_find_property(&ptr, "use_grease_pencil_sessions");
|
||||
//uiItemFullR
|
||||
uiItemR(row, &ptr, "use_grease_pencil_sessions", 0, "Continuous drawing", ICON_NONE);
|
||||
|
||||
}
|
||||
|
||||
static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr)
|
||||
{
|
||||
PointerRNA gpd_ptr;
|
||||
@@ -305,49 +334,55 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
|
||||
/* TODO: show some info about who owns this? */
|
||||
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink");
|
||||
|
||||
if (gpd != NULL) {
|
||||
/* draw gpd drawing settings first ------------------------------------- */
|
||||
col = uiLayoutColumn(layout, TRUE);
|
||||
/* label */
|
||||
uiItemL(col, IFACE_("Pencil Settings:"), ICON_NONE);
|
||||
|
||||
/* check whether advanced 3D-View drawing space options can be used */
|
||||
if (is_v3d) {
|
||||
if (gpd->flag & (GP_DATA_DEPTH_STROKE | GP_DATA_DEPTH_VIEW))
|
||||
v3d_stroke_opts = STROKE_OPTS_V3D_ON;
|
||||
else
|
||||
v3d_stroke_opts = STROKE_OPTS_V3D_OFF;
|
||||
}
|
||||
|
||||
/* drawing space options */
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE);
|
||||
|
||||
if (sc == NULL) {
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
uiLayoutSetActive(row, v3d_stroke_opts);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE);
|
||||
|
||||
row = uiLayoutRow(col, FALSE);
|
||||
uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON);
|
||||
uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* add new layer button - can be used even when no data, since it can add a new block too */
|
||||
col = uiLayoutColumn(layout, TRUE);
|
||||
uiItemL(col, IFACE_("Pencil Layers:"), ICON_NONE);
|
||||
|
||||
uiItemO(col, IFACE_("New Layer"), ICON_NONE, "GPENCIL_OT_layer_add");
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
uiItemO(row, IFACE_("Delete Frame"), ICON_NONE, "GPENCIL_OT_active_frame_delete");
|
||||
uiItemO(row, IFACE_("Convert"), ICON_NONE, "GPENCIL_OT_convert");
|
||||
|
||||
/* sanity checks... */
|
||||
if (gpd == NULL)
|
||||
return;
|
||||
|
||||
/* draw each layer --------------------------------------------- */
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
col = uiLayoutColumn(layout, TRUE);
|
||||
gp_drawui_layer(col, gpd, gpl, is_v3d);
|
||||
}
|
||||
|
||||
/* draw gpd drawing settings first ------------------------------------- */
|
||||
col = uiLayoutColumn(layout, TRUE);
|
||||
/* label */
|
||||
uiItemL(col, IFACE_("Drawing Settings:"), ICON_NONE);
|
||||
|
||||
/* check whether advanced 3D-View drawing space options can be used */
|
||||
if (is_v3d) {
|
||||
if (gpd->flag & (GP_DATA_DEPTH_STROKE | GP_DATA_DEPTH_VIEW))
|
||||
v3d_stroke_opts = STROKE_OPTS_V3D_ON;
|
||||
else
|
||||
v3d_stroke_opts = STROKE_OPTS_V3D_OFF;
|
||||
}
|
||||
|
||||
/* drawing space options */
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE);
|
||||
|
||||
if (sc == NULL) {
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
uiLayoutSetActive(row, v3d_stroke_opts);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE);
|
||||
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE);
|
||||
|
||||
row = uiLayoutRow(col, FALSE);
|
||||
uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON);
|
||||
uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE);
|
||||
/* sanity checks... */
|
||||
if (gpd != NULL)
|
||||
{
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
col = uiLayoutColumn(layout, TRUE);
|
||||
gp_drawui_layer(col, gpd, gpl, is_v3d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +402,9 @@ void gpencil_panel_standard(const bContext *C, Panel *pa)
|
||||
|
||||
/* if (v3d->flag2 & V3D_DISPGP)... etc. */
|
||||
|
||||
/* draw tool buttons */
|
||||
draw_gpencil_operator_buttons(C, pa->layout);
|
||||
|
||||
draw_gpencil_space_specials(C, pa->layout);
|
||||
|
||||
/* get pointer to Grease Pencil Data */
|
||||
|
@@ -70,6 +70,8 @@
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "gpencil_intern.h"
|
||||
|
||||
/* ******************************************* */
|
||||
@@ -2030,6 +2032,21 @@ static EnumPropertyItem prop_gpencil_drawmodes[] = {
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
static int gpencil_draw_icon(const bContext *UNUSED(C), PointerRNA *opptr)
|
||||
{
|
||||
if (opptr) {
|
||||
switch (RNA_enum_get(opptr, "mode")) {
|
||||
case GP_PAINTMODE_DRAW: return OPICON_GREASE_DRAW;
|
||||
case GP_PAINTMODE_DRAW_STRAIGHT: return OPICON_GREASE_LINE;
|
||||
case GP_PAINTMODE_DRAW_POLY: return OPICON_GREASE_POLY;
|
||||
case GP_PAINTMODE_ERASER: return OPICON_GREASE_ERASE;
|
||||
}
|
||||
}
|
||||
|
||||
return ICON_GREASEPENCIL;
|
||||
}
|
||||
|
||||
void GPENCIL_OT_draw(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@@ -2043,6 +2060,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot)
|
||||
ot->modal = gpencil_draw_modal;
|
||||
ot->cancel = gpencil_draw_cancel;
|
||||
ot->poll = gpencil_draw_poll;
|
||||
ot->icon = gpencil_draw_icon;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
|
@@ -52,6 +52,8 @@ void sdrawXORline4(int nr, int x0, int y0, int x1, int y1);
|
||||
void fdrawXORellipse(float xofs, float yofs, float hw, float hh);
|
||||
void fdrawXORcirc(float xofs, float yofs, float rad);
|
||||
|
||||
void fdrawellipses(float xofs, float yofs, float rad);
|
||||
|
||||
void fdrawcheckerboard(float x1, float y1, float x2, float y2);
|
||||
|
||||
/* OpenGL stipple defines */
|
||||
|
@@ -155,7 +155,7 @@ void create_vgroups_from_armature(struct ReportList *reports, struct Scene *scen
|
||||
void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */
|
||||
void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep);
|
||||
|
||||
void undo_push_armature(struct bContext *C, const char *name);
|
||||
void undo_push_armature(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
|
||||
/* low level selection functions which handle */
|
||||
int ED_armature_ebone_selectflag_get(const EditBone *ebone);
|
||||
|
@@ -56,7 +56,7 @@ void CU_select_all(struct Object *obedit);
|
||||
void CU_select_swap(struct Object *obedit);
|
||||
|
||||
|
||||
void undo_push_curve(struct bContext *C, const char *name);
|
||||
void undo_push_curve(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
ListBase *object_editcurve_get(struct Object *ob);
|
||||
|
||||
void load_editNurb(struct Object *obedit);
|
||||
@@ -72,7 +72,7 @@ int isNurbsel(struct Nurb *nu);
|
||||
int join_curve_exec(struct bContext *C, struct wmOperator *op);
|
||||
|
||||
/* editfont.h */
|
||||
void undo_push_font(struct bContext *C, const char *name);
|
||||
void undo_push_font(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
void make_editText(struct Object *obedit);
|
||||
void load_editText(struct Object *obedit);
|
||||
void free_editText(struct Object *obedit);
|
||||
|
@@ -48,6 +48,12 @@ extern char datatoc_blender_icons16_png[];
|
||||
extern int datatoc_blender_icons32_png_size;
|
||||
extern char datatoc_blender_icons32_png[];
|
||||
|
||||
extern int datatoc_blender_operator_icons16_png_size;
|
||||
extern char datatoc_blender_operator_icons16_png[];
|
||||
|
||||
extern int datatoc_blender_operator_icons32_png_size;
|
||||
extern char datatoc_blender_operator_icons32_png[];
|
||||
|
||||
extern int datatoc_prvicons_png_size;
|
||||
extern char datatoc_prvicons_png[];
|
||||
|
||||
|
@@ -35,6 +35,7 @@ struct bContext;
|
||||
struct MetaBall;
|
||||
struct Object;
|
||||
struct wmKeyConfig;
|
||||
struct wmOperator;
|
||||
|
||||
void ED_operatortypes_metaball(void);
|
||||
void ED_keymap_metaball(struct wmKeyConfig *keyconf);
|
||||
@@ -47,7 +48,7 @@ void free_editMball(struct Object *obedit);
|
||||
void make_editMball(struct Object *obedit);
|
||||
void load_editMball(struct Object *obedit);
|
||||
|
||||
void undo_push_mball(struct bContext *C, const char *name);
|
||||
void undo_push_mball(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
|
||||
void ED_mball_transform(struct MetaBall *mb, float *mat);
|
||||
|
||||
|
@@ -120,7 +120,7 @@ void EDBM_selectmode_flush(struct BMEditMesh *em);
|
||||
void EDBM_deselect_flush(struct BMEditMesh *em);
|
||||
void EDBM_select_flush(struct BMEditMesh *em);
|
||||
|
||||
void undo_push_mesh(struct bContext *C, const char *name);
|
||||
void undo_push_mesh(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
|
||||
bool EDBM_vert_color_check(struct BMEditMesh *em);
|
||||
|
||||
|
@@ -170,7 +170,7 @@ void ED_object_constraint_dependency_update(struct Main *bmain, struct Object *o
|
||||
|
||||
/* object_lattice.c */
|
||||
bool mouse_lattice(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
||||
void undo_push_lattice(struct bContext *C, const char *name);
|
||||
void undo_push_lattice(struct bContext *C, const char *name, struct wmOperator *op);
|
||||
|
||||
/* object_lattice.c */
|
||||
|
||||
|
@@ -63,6 +63,8 @@ void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
|
||||
void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, const char *context, int contextnr);
|
||||
void ED_region_header_init(struct ARegion *ar);
|
||||
void ED_region_header(const struct bContext *C, struct ARegion *ar);
|
||||
void ED_region_menubar(const struct bContext *C, struct ARegion *ar);
|
||||
void ED_region_menubar_init(struct ARegion *ar);
|
||||
void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar);
|
||||
void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float fill_color[4]);
|
||||
void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
|
||||
|
@@ -72,8 +72,8 @@ void undo_editmode_push(struct bContext *C, const char *name,
|
||||
void (*freedata)(void *),
|
||||
void (*to_editmode)(void *, void *, void *),
|
||||
void *(*from_editmode)(void *, void *),
|
||||
int (*validate_undo)(void *, void *));
|
||||
|
||||
int (*validate_undo)(void *, void *),
|
||||
struct wmOperator * op);
|
||||
|
||||
void undo_editmode_clear(void);
|
||||
|
||||
|
@@ -44,6 +44,7 @@ struct Main;
|
||||
struct ListBase;
|
||||
struct ARegion;
|
||||
struct ARegionType;
|
||||
struct OperatorListItem;
|
||||
struct ScrArea;
|
||||
struct wmWindow;
|
||||
struct wmWindowManager;
|
||||
@@ -79,6 +80,7 @@ typedef struct uiBut uiBut;
|
||||
typedef struct uiBlock uiBlock;
|
||||
typedef struct uiPopupBlockHandle uiPopupBlockHandle;
|
||||
typedef struct uiLayout uiLayout;
|
||||
typedef struct uiHandleRegionDragData uiHandleRegionDragData;
|
||||
|
||||
/* Defines */
|
||||
|
||||
@@ -130,6 +132,7 @@ typedef struct uiLayout uiLayout;
|
||||
/* block->flag bits 12-15 are identical to but->flag bits */
|
||||
|
||||
#define UI_BLOCK_LIST_ITEM (1 << 19)
|
||||
#define UI_BLOCK_SHORTCUTS (1 << 20)
|
||||
|
||||
/* uiPopupBlockHandle->menuretval */
|
||||
#define UI_RETURN_CANCEL (1 << 0) /* cancel all menus cascading */
|
||||
@@ -179,6 +182,9 @@ typedef struct uiLayout uiLayout;
|
||||
#define UI_BUT_VEC_SIZE_LOCK (1 << 30) /* used to flag if color hsv-circle should keep luminance */
|
||||
#define UI_BUT_COLOR_CUBIC (1 << 31) /* cubic saturation for the color wheel */
|
||||
|
||||
#define UI_BUT2_EXTRA_TEXT (1 << 0)
|
||||
|
||||
|
||||
#define UI_PANEL_WIDTH 340
|
||||
#define UI_COMPACT_PANEL_WIDTH 160
|
||||
|
||||
@@ -270,6 +276,16 @@ typedef enum {
|
||||
|
||||
#define UI_GRAD_V_ALT 9
|
||||
|
||||
/* Panel flags */
|
||||
#define PNL_LAST_ADDED 1
|
||||
#define PNL_ACTIVE 2
|
||||
#define PNL_WAS_ACTIVE 4
|
||||
#define PNL_ANIM_ALIGN 8
|
||||
#define PNL_NEW_ADDED 16
|
||||
#define PNL_FIRST 32
|
||||
#define PNL_CUSTOM_PANEL 64
|
||||
#define PNL_PINNED 128
|
||||
|
||||
/* Drawing
|
||||
*
|
||||
* Functions to draw various shapes, taking theme settings into account.
|
||||
@@ -372,6 +388,7 @@ void uiDrawBlock(const struct bContext *C, struct uiBlock *block);
|
||||
uiBlock *uiGetBlock(const char *name, struct ARegion *ar);
|
||||
|
||||
void uiBlockSetEmboss(uiBlock *block, char dt);
|
||||
void uiBlockSetPanel(uiBlock *block, struct Panel *pa);
|
||||
|
||||
void uiFreeBlock(const struct bContext *C, uiBlock *block);
|
||||
void uiFreeBlocks(const struct bContext *C, struct ListBase *lb);
|
||||
@@ -417,6 +434,7 @@ void uiButSetDragID(uiBut *but, struct ID *id);
|
||||
void uiButSetDragRNA(uiBut *but, struct PointerRNA *ptr);
|
||||
void uiButSetDragPath(uiBut *but, const char *path);
|
||||
void uiButSetDragName(uiBut *but, const char *name);
|
||||
void uiButSetDragOp(uiBut *but, const struct wmOperatorType *ot);
|
||||
void uiButSetDragValue(uiBut *but);
|
||||
void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale);
|
||||
|
||||
@@ -647,14 +665,23 @@ bool autocomplete_end(AutoComplete *autocpl, char *autoname);
|
||||
* could use a good cleanup, though how they will function in 2.5 is
|
||||
* not clear yet so we postpone that. */
|
||||
|
||||
void uiCollapseAllPanels(struct ScrArea *sa, struct ARegion *ar, const char *context);
|
||||
|
||||
void uiBeginPanels(const struct bContext *C, struct ARegion *ar);
|
||||
void uiEndPanels(const struct bContext *C, struct ARegion *ar, int *x, int *y);
|
||||
void uiDrawPanels(const struct bContext *C, struct ARegion *ar);
|
||||
|
||||
struct Panel *uiGetExistingPanel(struct ARegion *ar, struct PanelType *pt);
|
||||
struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open);
|
||||
void uiEndPanel(uiBlock *block, int width, int height);
|
||||
void uiScalePanels(struct ARegion *ar, float new_width);
|
||||
|
||||
void uiPanelAddOperator(struct bContext *C, struct Panel *pa, struct wmOperatorType *ot, PointerRNA *opptr);
|
||||
void uiPanelFree(struct Panel *pa);
|
||||
int uiPanelClosed(struct Panel *pa);
|
||||
|
||||
struct PanelType *uiCreateCustomPanelType(struct ScrArea *sa, struct ARegion *ar, const char *context, const char *name, const char *label);
|
||||
|
||||
/* Handlers
|
||||
*
|
||||
* Handlers that can be registered in regions, areas and windows for
|
||||
@@ -712,6 +739,8 @@ void UI_exit(void);
|
||||
#define UI_ITEM_R_FULL_EVENT (1 << 6)
|
||||
#define UI_ITEM_R_NO_BG (1 << 7)
|
||||
#define UI_ITEM_R_IMMEDIATE (1 << 8)
|
||||
#define UI_ITEM_O_SINGLE_UNIT (1 << 9)
|
||||
#define UI_ITEM_O_SHORTCUT (1 << 10)
|
||||
|
||||
/* uiLayoutOperatorButs flags */
|
||||
#define UI_LAYOUT_OP_SHOW_TITLE 1
|
||||
@@ -749,6 +778,7 @@ const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing
|
||||
void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op,
|
||||
bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
|
||||
const char label_align, const short flag);
|
||||
void uiLayoutOperatorTypeDefaultsButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op);
|
||||
struct MenuType *uiButGetMenuType(uiBut *but);
|
||||
|
||||
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext);
|
||||
@@ -772,7 +802,9 @@ float uiLayoutGetScaleY(uiLayout *layout);
|
||||
|
||||
/* layout specifiers */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutRowWithButtonHeight(uiLayout *layout, int align, float button_height);
|
||||
uiLayout *uiLayoutColumn(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutColumnWithButtonHeight(uiLayout *layout, int align, float button_height);
|
||||
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align);
|
||||
uiLayout *uiLayoutBox(uiLayout *layout);
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct PointerRNA *ptr, struct PropertyRNA *prop,
|
||||
@@ -791,6 +823,8 @@ void uiTemplateIDBrowse(uiLayout *layout, struct bContext *C, struct PointerRNA
|
||||
const char *newop, const char *openop, const char *unlinkop);
|
||||
void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname,
|
||||
const char *newop, const char *openop, const char *unlinkop, int rows, int cols);
|
||||
void uiTemplateIDPreviewCompact(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname,
|
||||
const char *newop, const char *openop, const char *unlinkop, int rows, int cols);
|
||||
void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
|
||||
const char *proptypename, const char *text);
|
||||
void uiTemplatePathBuilder(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
|
||||
@@ -873,6 +907,12 @@ void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc
|
||||
void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, const char *propname, const char *name, int icon);
|
||||
void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon);
|
||||
|
||||
/* OperatorListItem utilities */
|
||||
struct OperatorListItem *uiOperatorListItemPresent(ListBase *lb, const char *idname, IDProperty *properties, const char *context);
|
||||
struct OperatorListItem *uiRegionDraggedOperatorListItem(struct ARegion *ar);
|
||||
int uiRegionDraggedNewIndex(struct ARegion *ar);
|
||||
|
||||
|
||||
/* UI Operators */
|
||||
void UI_buttons_operatortypes(void);
|
||||
|
||||
|
54
source/blender/editors/include/UI_opicons.h
Normal file
54
source/blender/editors/include/UI_opicons.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2009 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file UI_opicons.h
|
||||
* \ingroup editorui
|
||||
*/
|
||||
|
||||
/* Note: this is included twice with different #defines for DEF_ICON
|
||||
* once from UI_resources.h for the internal icon enum and
|
||||
* once for interface_api.c for the definition of the RNA enum for the icons */
|
||||
|
||||
/* OPICON_ prefix added */
|
||||
DEF_FIRST_OPICON(RENDER_FRAME)
|
||||
DEF_OPICON(RENDER_ANIM)
|
||||
DEF_OPICON(RENDER)
|
||||
DEF_OPICON(RULER)
|
||||
DEF_OPICON(ADD)
|
||||
DEF_OPICON(DELETE)
|
||||
DEF_OPICON(DUP)
|
||||
DEF_OPICON(DUP_LINKED)
|
||||
DEF_OPICON(LOOPCUT)
|
||||
DEF_OPICON(GREASE_DRAW)
|
||||
DEF_OPICON(GREASE_LINE)
|
||||
DEF_OPICON(GREASE_POLY)
|
||||
DEF_OPICON(GREASE_ERASE)
|
||||
DEF_OPICON(GREASE)
|
||||
DEF_OPICON(BRUSH)
|
||||
DEF_OPICON(KNIFE)
|
||||
|
||||
|
||||
|
@@ -32,21 +32,38 @@
|
||||
#ifndef __UI_RESOURCES_H__
|
||||
#define __UI_RESOURCES_H__
|
||||
|
||||
#define ICON_AUTOMATIC -1
|
||||
|
||||
#define ICON_GRID_COLS 26
|
||||
#define ICON_GRID_ROWS 30
|
||||
|
||||
#define OPICON_GRID_COLS 26
|
||||
#define OPICON_GRID_ROWS 30
|
||||
|
||||
#define OPICON_OFFSET 0x3FFF
|
||||
|
||||
/* elubie: TODO: move the typedef for icons to UI_interface_icons.h */
|
||||
/* and add/replace include of UI_resources.h by UI_interface_icons.h */
|
||||
#define DEF_ICON(name) ICON_##name,
|
||||
#define DEF_VICO(name) VICO_##name,
|
||||
#define DEF_OPICON(name) OPICON_##name,
|
||||
#define DEF_FIRST_OPICON(name) OPICON_##name = OPICON_OFFSET,
|
||||
|
||||
typedef enum {
|
||||
/* ui */
|
||||
#include "UI_icons.h"
|
||||
#include "UI_opicons.h"
|
||||
BIFICONID_LAST
|
||||
} BIFIconID;
|
||||
|
||||
/* operator icons are offset by 0x3FFF */
|
||||
#define BIFICONID_FIRST (ICON_NONE)
|
||||
#define BIFICONID_FIRST_OP (BIFICONID_FIRST + OPICON_OFFSET)
|
||||
|
||||
#undef DEF_ICON
|
||||
#undef DEF_VICO
|
||||
#undef DEF_OPICON
|
||||
#undef DEF_FIRST_OPICON
|
||||
|
||||
enum {
|
||||
TH_REDALERT,
|
||||
@@ -245,6 +262,7 @@ enum {
|
||||
|
||||
struct bTheme;
|
||||
struct PointerRNA;
|
||||
struct bContext;
|
||||
|
||||
// THE CODERS API FOR THEMES:
|
||||
|
||||
@@ -312,4 +330,6 @@ const unsigned char *UI_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, i
|
||||
|
||||
void UI_make_axis_color(const unsigned char *src_col, unsigned char *dst_col, const char axis);
|
||||
|
||||
int UI_data_mode_icon(const struct bContext *C);
|
||||
|
||||
#endif /* __UI_RESOURCES_H__ */
|
||||
|
@@ -1021,7 +1021,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
|
||||
for (but = block->buttons.first; but; but = but->next) {
|
||||
|
||||
if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
|
||||
ui_but_add_shortcut(but, buf, FALSE);
|
||||
ui_but_add_shortcut(but, buf, TRUE);
|
||||
}
|
||||
else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
|
||||
ui_but_add_shortcut(but, buf, FALSE);
|
||||
@@ -1080,7 +1080,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
|
||||
ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
|
||||
}
|
||||
|
||||
if (block->flag & UI_BLOCK_LOOP) {
|
||||
if (block->flag & UI_BLOCK_SHORTCUTS) {
|
||||
ui_menu_block_set_keymaps(C, block);
|
||||
}
|
||||
|
||||
@@ -1199,7 +1199,8 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
|
||||
if (block->flag & UI_BLOCK_LOOP)
|
||||
ui_draw_menu_back(&style, block, &rect);
|
||||
else if (block->panel)
|
||||
ui_draw_aligned_panel(&style, block, &rect);
|
||||
ui_draw_aligned_panel(&style, block, &rect, ar && ar->regiontype == RGN_TYPE_TOOLS);
|
||||
|
||||
|
||||
/* widgets */
|
||||
for (but = block->buttons.first; but; but = but->next) {
|
||||
@@ -2352,6 +2353,11 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor
|
||||
block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]);
|
||||
block->auto_open = TRUE;
|
||||
block->flag |= UI_BLOCK_LOOP; /* tag as menu */
|
||||
block->flag |= UI_BLOCK_SHORTCUTS;
|
||||
}
|
||||
/* Add shortcuts to toolbar */
|
||||
if (region && region->type && region->type->regionid == RGN_TYPE_TOOLS) {
|
||||
block->flag |= UI_BLOCK_SHORTCUTS;
|
||||
}
|
||||
|
||||
return block;
|
||||
@@ -2367,6 +2373,11 @@ void uiBlockSetEmboss(uiBlock *block, char dt)
|
||||
block->dt = dt;
|
||||
}
|
||||
|
||||
void uiBlockSetPanel(uiBlock *block, Panel *pa)
|
||||
{
|
||||
block->panel = pa;
|
||||
}
|
||||
|
||||
void ui_check_but(uiBut *but)
|
||||
{
|
||||
/* if something changed in the button */
|
||||
@@ -3613,6 +3624,12 @@ void uiButSetDragName(uiBut *but, const char *name)
|
||||
but->dragpoin = (void *)name;
|
||||
}
|
||||
|
||||
void uiButSetDragOp(uiBut *but, const wmOperatorType *ot)
|
||||
{
|
||||
but->dragtype = WM_DRAG_OP;
|
||||
but->dragpoin = (void *)ot;
|
||||
}
|
||||
|
||||
/* value from button itself */
|
||||
void uiButSetDragValue(uiBut *but)
|
||||
{
|
||||
|
@@ -64,6 +64,7 @@
|
||||
#include "BKE_tracking.h"
|
||||
#include "BKE_unit.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_util.h"
|
||||
@@ -905,7 +906,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
|
||||
{
|
||||
wmDrag *drag;
|
||||
|
||||
drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but));
|
||||
drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but), but->opptr, but->opcontext);
|
||||
if (but->imb)
|
||||
WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect));
|
||||
}
|
||||
@@ -2491,7 +2492,14 @@ int ui_button_open_menu_direction(uiBut *but)
|
||||
static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
|
||||
{
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
|
||||
/* first handle click on icondrag type button */
|
||||
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
|
||||
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
|
||||
data->dragstartx = event->x;
|
||||
data->dragstarty = event->y;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
|
||||
button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
@@ -2515,6 +2523,26 @@ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, cons
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
|
||||
|
||||
/* this function also ends state */
|
||||
if (ui_but_start_drag(C, but, data, event)) {
|
||||
data->escapecancel = TRUE;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
/* If the mouse has been pressed and released, getting to
|
||||
* this point without triggering a drag, then clear the
|
||||
* drag state for this button and continue to pass on the event */
|
||||
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
/* while waiting for a drag to be triggered, always block
|
||||
* other events from getting handled */
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
@@ -2573,7 +2601,6 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
|
||||
data->escapecancel = true;
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5039,6 +5066,76 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
|
||||
uiPupBlock(C, menu_add_shortcut, but);
|
||||
}
|
||||
|
||||
//static void ui_but_menu_set_last_properties(bContext *UNUSED(C), void *arg_op, int UNUSED(arg_event))
|
||||
//{
|
||||
// wmOperator *op = (wmOperator*)arg_op;
|
||||
// WM_operator_default_properties_store(op);
|
||||
//}
|
||||
|
||||
// TODO: this should make use of the new comparison method, perhaps based on sort order
|
||||
static void remove_from_custom_panel(bContext *UNUSED(C), void *arg_pa, void *arg_optype)
|
||||
{
|
||||
Panel *pa = arg_pa;
|
||||
wmOperatorType *ot = arg_optype;
|
||||
OperatorListItem *oli;
|
||||
|
||||
oli = BLI_findstring(&pa->operators, ot->idname, offsetof(OperatorListItem, optype_idname));
|
||||
BLI_remlink(&pa->operators, oli);
|
||||
BKE_operator_list_item_free(oli);
|
||||
}
|
||||
|
||||
static void remove_from_icon_shelf(bContext *C, void *arg_ot, void *arg_opptr)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
wmOperatorType *ot = arg_ot;
|
||||
PointerRNA *opptr = (PointerRNA*)arg_opptr;
|
||||
OperatorListItem *oli;
|
||||
|
||||
for (oli = ar->operators.first; oli; oli = oli->next) {
|
||||
if (strcmp(oli->optype_idname, ot->idname) == 0 && IDP_EqualsProperties(opptr->data, oli->properties)) {
|
||||
BLI_remlink(&ar->operators, oli);
|
||||
BKE_operator_list_item_free(oli);
|
||||
}
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void remove_from_icon_shelf_divider(bContext *C, void *arg_oli, void *UNUSED(arg2))
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
OperatorListItem *oli = (OperatorListItem*)arg_oli;
|
||||
|
||||
BLI_remlink(&ar->operators, oli);
|
||||
BKE_operator_list_item_free(oli);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void add_divider_to_icon_shelf(bContext *C, void *arg_ot, void *arg_opptr)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
wmOperatorType *ot = arg_ot;
|
||||
PointerRNA *opptr = (PointerRNA*)arg_opptr;
|
||||
OperatorListItem *oli = uiOperatorListItemPresent(&ar->operators, ot->idname, opptr->data, CTX_data_mode_string(C));
|
||||
OperatorListItem *div;
|
||||
|
||||
/*
|
||||
* Only add a divider if:
|
||||
* - the current button is not a divider
|
||||
* - the current button does not have a divider in front of it already
|
||||
*/
|
||||
if (oli && !(oli->flag & OLI_DIVIDER) &&
|
||||
!(oli->prev != NULL && ((OperatorListItem*)(oli->prev))->flag & OLI_DIVIDER)) {
|
||||
div = MEM_callocN(sizeof(OperatorListItem), "OperatorListItem divider");
|
||||
div->flag |= OLI_DIVIDER;
|
||||
BLI_strncpy(div->context, CTX_data_mode_string(C), MAX_NAME);
|
||||
|
||||
BLI_insertlinkbefore(&ar->operators, oli, div);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static bool ui_but_menu(bContext *C, uiBut *but)
|
||||
{
|
||||
@@ -5046,6 +5143,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
||||
uiLayout *layout;
|
||||
bool is_array, is_array_component;
|
||||
uiStringInfo label = {BUT_GET_LABEL, NULL};
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
/* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/
|
||||
/* return 0;*/
|
||||
@@ -5234,6 +5332,8 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
||||
wmKeyMapItem *kmi = NULL;
|
||||
int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
if (kmi_id)
|
||||
kmi = WM_keymap_item_find_id(km, kmi_id);
|
||||
|
||||
@@ -5259,8 +5359,66 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
{
|
||||
uiBut *opp_but;
|
||||
Panel *pa = but->block->panel;
|
||||
|
||||
/* Remove the operator from the custom enclosure */
|
||||
if (ar->regiontype == RGN_TYPE_TOOLS && pa && pa->flag & PNL_CUSTOM_PANEL) {
|
||||
opp_but = uiDefIconTextBut(block, BUT, 0, ICON_NONE,
|
||||
CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove From Panel"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
uiButSetFunc(opp_but, remove_from_custom_panel, pa, but->optype);
|
||||
uiItemS(layout);
|
||||
}
|
||||
else if (ar->regiontype == RGN_TYPE_MENU_BAR) {
|
||||
/* Only show the option to add a divider for a button, not a divider */
|
||||
if (uiOperatorListItemPresent(&ar->operators, but->optype->idname, but->opptr->data, CTX_data_mode_string(C))) {
|
||||
opp_but = uiDefIconTextBut(block, BUT, 0, ICON_NONE,
|
||||
CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Divider to the Left"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
uiButSetFunc(opp_but, add_divider_to_icon_shelf, but->optype, but->opptr);
|
||||
|
||||
opp_but = uiDefIconTextBut(block, BUT, 0, ICON_NONE,
|
||||
CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove From Icon Shelf"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
uiButSetFunc(opp_but, remove_from_icon_shelf, but->optype, but->opptr);
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
}
|
||||
|
||||
if (ar->regiontype != RGN_TYPE_MENU_BAR) {
|
||||
opp_but = uiDefIconTextBut(block, BUT, 0, ICON_NONE,
|
||||
CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Icon Shelf"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
uiButSetFunc(opp_but, add_to_icon_shelf, but->optype, but->opptr);
|
||||
}
|
||||
|
||||
uiItemMenuF(layout, IFACE_("Add to Custom Panel..."), ICON_NONE, add_to_custom_panel_menu, but->optype);
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
}
|
||||
|
||||
/* Divider butons */
|
||||
if (ar->regiontype == RGN_TYPE_MENU_BAR) {
|
||||
if (but->func_arg1) {
|
||||
uiBut *div_but;
|
||||
uiBlock *block = uiLayoutGetBlock(layout);
|
||||
int w = uiLayoutGetWidth(layout);
|
||||
|
||||
div_but = uiDefIconTextBut(block, BUT, 0, ICON_NONE,
|
||||
CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove From Icon Shelf"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
/* N.B. the but->func_arg1 is set to the divider OperatorListItem. */
|
||||
uiButSetFunc(div_but, remove_from_icon_shelf_divider, but->func_arg1, NULL);
|
||||
|
||||
uiItemS(layout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Show header tools for header buttons. */
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
@@ -5557,7 +5715,7 @@ static bool ui_but_contains_pt(uiBut *but, int mx, int my)
|
||||
return BLI_rctf_isect_pt(&but->rect, mx, my);
|
||||
}
|
||||
|
||||
static uiBut *ui_but_find_activated(ARegion *ar)
|
||||
uiBut *ui_but_find_activated(ARegion *ar)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
@@ -7540,6 +7698,152 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
|
||||
|
||||
/* *************** UI event handlers **************** */
|
||||
|
||||
static void ui_do_drag_button(const bContext *C, const wmEvent *event, ARegion *ar)
|
||||
{
|
||||
uiHandleRegionDragData *data = ar->dragdata;
|
||||
int cur_index = BLI_findindex(&ar->operators, data->oli);
|
||||
OperatorListItem *oli_iter = data->oli;
|
||||
int dx, dunits, dunits_iter, extra_units = 0, maxindex;
|
||||
|
||||
// Calculate the new index of the button based on the drag offset
|
||||
dx = event->x - data->startx;
|
||||
dunits = dx / (UI_UNIT_X * 1.5); // TODO: make sure this factor corresponds to menubar button sizes
|
||||
|
||||
// Offset the new index by the interleaved list items that aren't shown in the current contex
|
||||
dunits_iter = dunits;
|
||||
while (dunits_iter != 0) {
|
||||
oli_iter = dunits < 0 ? oli_iter->prev : oli_iter->next;
|
||||
if (oli_iter == NULL) break;
|
||||
// TODO: also take into account closed groups
|
||||
if (strcmp(oli_iter->context, CTX_data_mode_string(C)) != 0)
|
||||
extra_units += (dunits < 0 ? -1 : 1);
|
||||
dunits_iter += (dunits < 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
data->newindex = (cur_index + dunits) + extra_units;
|
||||
maxindex = (BLI_countlist(&ar->operators) - 1);
|
||||
CLAMP(data->newindex, 0, maxindex);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void ui_do_drag_button_finish(const bContext *UNUSED(C), const wmEvent *UNUSED(event), ARegion *ar)
|
||||
{
|
||||
uiHandleRegionDragData *data = ar->dragdata;
|
||||
int cur_index = BLI_findindex(&ar->operators, data->oli);
|
||||
OperatorListItem *oli_target = BLI_findlink(&ar->operators, data->newindex);
|
||||
|
||||
if (data->newindex < cur_index) {
|
||||
BLI_remlink(&ar->operators, data->oli);
|
||||
BLI_insertlinkbefore(&ar->operators, oli_target, data->oli);
|
||||
}
|
||||
else if (data->newindex > cur_index) {
|
||||
BLI_remlink(&ar->operators, data->oli);
|
||||
BLI_insertlinkafter(&ar->operators, oli_target, data->oli);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
|
||||
static void region_activate_drag_state(const bContext *C, ARegion *ar, uiHandleRegionDragState state);
|
||||
|
||||
static int ui_handler_region_drag_shelf(bContext *C, const wmEvent *event, void *userdata)
|
||||
{
|
||||
ARegion *ar = userdata;
|
||||
uiHandleRegionDragData *data;
|
||||
int retval = WM_UI_HANDLER_CONTINUE;
|
||||
|
||||
if (event->type == MOUSEMOVE) {
|
||||
if (ar->dragdata) {
|
||||
data = ar->dragdata;
|
||||
|
||||
if (data->state == REGION_STATE_DRAG_BUTTON) {
|
||||
ui_do_drag_button(C, event, ar);
|
||||
}
|
||||
else if (data->state == REGION_STATE_DRAG_BUTTON_WAITING) {
|
||||
if (ABS(data->startx - event->x) > UI_UNIT_X) {
|
||||
region_activate_drag_state(C, ar, REGION_STATE_DRAG_BUTTON);
|
||||
}
|
||||
}
|
||||
}
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
if (ar->dragdata) {
|
||||
data = ar->dragdata;
|
||||
if (data->state == REGION_STATE_DRAG_BUTTON) {
|
||||
ui_do_drag_button_finish(C, event, ar);
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
region_activate_drag_state(C, ar, REGION_STATE_DRAG_EXIT);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ui_handler_region_drag_shelf_remove(bContext *UNUSED(C), void *UNUSED(userdata))
|
||||
{
|
||||
// ARegion *ar = userdata;
|
||||
// region_activate_drag_state(C, ar, REGION_STATE_DRAG_EXIT);
|
||||
}
|
||||
|
||||
static void region_activate_drag_state(const bContext *C, ARegion *ar, uiHandleRegionDragState state)
|
||||
{
|
||||
uiHandleRegionDragData *data = ar->dragdata;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
if (data && data->state == state)
|
||||
return;
|
||||
|
||||
if (state == REGION_STATE_DRAG_EXIT) {
|
||||
|
||||
if (data) {
|
||||
/* deactivate the button when we've dragged, otherwise we'll get a
|
||||
* global drag */
|
||||
if (data->state == REGION_STATE_DRAG_BUTTON) {
|
||||
uiBut *but = ui_but_find_activated(ar);
|
||||
if (but)
|
||||
ui_button_active_free(C, but);
|
||||
}
|
||||
|
||||
MEM_freeN(data);
|
||||
ar->dragdata = NULL;
|
||||
}
|
||||
WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_region_drag_shelf, ui_handler_region_drag_shelf_remove, ar, FALSE);
|
||||
}
|
||||
else if (state == REGION_STATE_DRAG_BUTTON_WAITING) {
|
||||
if (!data) {
|
||||
OperatorListItem *oli = NULL;
|
||||
uiBut *but = ui_but_find_activated(ar);
|
||||
|
||||
if (but->optype || but->func_arg1) {
|
||||
if (but->optype)
|
||||
oli = uiOperatorListItemPresent(&ar->operators, but->optype->idname, but->opptr ? but->opptr->data : NULL, CTX_data_mode_string(C));
|
||||
else
|
||||
oli = (OperatorListItem*)but->func_arg1;
|
||||
|
||||
if (oli) {
|
||||
data = MEM_callocN(sizeof(uiHandleRegionDragData), "uiHandleRegionDragData");
|
||||
data->state = REGION_STATE_DRAG_BUTTON_WAITING;
|
||||
data->startx = win->eventstate->x;
|
||||
data->starty = win->eventstate->y;
|
||||
data->oli = oli;
|
||||
ar->dragdata = (void*)data;
|
||||
|
||||
WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_region_drag_shelf, ui_handler_region_drag_shelf_remove, ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (state == REGION_STATE_DRAG_BUTTON) {
|
||||
if (data) data->state = state;
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(userdata))
|
||||
{
|
||||
ARegion *ar;
|
||||
@@ -7555,22 +7859,33 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use
|
||||
|
||||
/* either handle events for already activated button or try to activate */
|
||||
but = ui_but_find_activated(ar);
|
||||
|
||||
|
||||
/* capture button drags in the MENU_BAR region so that we can do custom drag and drop */
|
||||
if (ar->regiontype == RGN_TYPE_MENU_BAR) {
|
||||
/* start drag */
|
||||
if (but && event->type == LEFTMOUSE && event->val == KM_PRESS) {
|
||||
region_activate_drag_state(C, ar, REGION_STATE_DRAG_BUTTON_WAITING);
|
||||
}
|
||||
}
|
||||
|
||||
retval = ui_handler_panel_region(C, event);
|
||||
|
||||
if (retval == WM_UI_HANDLER_CONTINUE)
|
||||
retval = ui_handle_list_event(C, event, ar);
|
||||
|
||||
if (retval == WM_UI_HANDLER_CONTINUE) {
|
||||
/* only if there's no drag going on inside the region */
|
||||
if (retval == WM_UI_HANDLER_CONTINUE)
|
||||
{
|
||||
if (but)
|
||||
retval = ui_handle_button_event(C, event, but);
|
||||
else
|
||||
retval = ui_handle_button_over(C, event, ar);
|
||||
}
|
||||
|
||||
/* re-enable tooltips */
|
||||
/* re-enable tooltips, only if there's no drag going on inside the region */
|
||||
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy))
|
||||
ui_blocks_set_tooltips(ar, true);
|
||||
if (ar->dragdata == NULL)
|
||||
ui_blocks_set_tooltips(ar, true);
|
||||
|
||||
/* delayed apply callbacks */
|
||||
ui_apply_but_funcs_after(C);
|
||||
|
@@ -77,9 +77,6 @@
|
||||
#include "interface_intern.h"
|
||||
|
||||
#ifndef WITH_HEADLESS
|
||||
#define ICON_GRID_COLS 26
|
||||
#define ICON_GRID_ROWS 30
|
||||
|
||||
#define ICON_GRID_MARGIN 10
|
||||
#define ICON_GRID_W 32
|
||||
#define ICON_GRID_H 32
|
||||
@@ -130,6 +127,7 @@ typedef struct IconTexture {
|
||||
* scanning the filesystem each time the menu is drawn */
|
||||
static struct ListBase iconfilelist = {NULL, NULL};
|
||||
static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
|
||||
static IconTexture opicongltex = {0, 0, 0, 0.0f, 0.0f};
|
||||
|
||||
/* **************************************************** */
|
||||
|
||||
@@ -587,11 +585,78 @@ static void init_matcap_icons(void)
|
||||
|
||||
}
|
||||
|
||||
static void generate_mipmaps(ImBuf **b32buf, ImBuf **b16buf, IconTexture *gltex, int rows, int cols, int offset)
|
||||
{
|
||||
int x, y, icontype;
|
||||
|
||||
if (*b16buf && *b32buf) {
|
||||
/* free existing texture if any */
|
||||
if (gltex->id) {
|
||||
glDeleteTextures(1, &gltex->id);
|
||||
gltex->id = 0;
|
||||
}
|
||||
|
||||
/* we only use a texture for cards with non-power of two */
|
||||
if (GPU_non_power_of_two_support()) {
|
||||
glGenTextures(1, &gltex->id);
|
||||
|
||||
|
||||
if (gltex->id) {
|
||||
int level = 2;
|
||||
|
||||
gltex->w = (*b32buf)->x;
|
||||
gltex->h = (*b32buf)->y;
|
||||
gltex->invw = 1.0f / (*b32buf)->x;
|
||||
gltex->invh = 1.0f / (*b32buf)->y;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gltex->id);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (*b32buf)->x, (*b32buf)->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (*b32buf)->rect);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, (*b16buf)->x, (*b16buf)->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (*b16buf)->rect);
|
||||
|
||||
while ((*b16buf)->x > 1) {
|
||||
ImBuf *nbuf = IMB_onehalf(*b16buf);
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect);
|
||||
level++;
|
||||
IMB_freeImBuf(*b16buf);
|
||||
*b16buf = nbuf;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (glGetError() == GL_OUT_OF_MEMORY) {
|
||||
glDeleteTextures(1, &gltex->id);
|
||||
gltex->id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gltex->id)
|
||||
icontype = ICON_TYPE_TEXTURE;
|
||||
else
|
||||
icontype = ICON_TYPE_BUFFER;
|
||||
|
||||
if (*b32buf) {
|
||||
for (y = 0; y < rows; y++) {
|
||||
for (x = 0; x < cols; x++) {
|
||||
def_internal_icon(*b32buf, offset + y * cols + x,
|
||||
x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
|
||||
y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W,
|
||||
icontype);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void init_internal_icons(void)
|
||||
{
|
||||
// bTheme *btheme = UI_GetTheme();
|
||||
ImBuf *b16buf = NULL, *b32buf = NULL;
|
||||
int x, y, icontype;
|
||||
ImBuf *b16bufOps = NULL, *b32bufOps = NULL;
|
||||
|
||||
#if 0 // temp disabled
|
||||
if ((btheme != NULL) && btheme->tui.iconfile[0]) {
|
||||
@@ -612,6 +677,8 @@ static void init_internal_icons(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* interface icons */
|
||||
if (b16buf == NULL)
|
||||
b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png,
|
||||
datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
|
||||
@@ -624,67 +691,8 @@ static void init_internal_icons(void)
|
||||
if (b32buf)
|
||||
IMB_premultiply_alpha(b32buf);
|
||||
|
||||
if (b16buf && b32buf) {
|
||||
/* free existing texture if any */
|
||||
if (icongltex.id) {
|
||||
glDeleteTextures(1, &icongltex.id);
|
||||
icongltex.id = 0;
|
||||
}
|
||||
|
||||
/* we only use a texture for cards with non-power of two */
|
||||
if (GPU_non_power_of_two_support()) {
|
||||
glGenTextures(1, &icongltex.id);
|
||||
|
||||
if (icongltex.id) {
|
||||
int level = 2;
|
||||
|
||||
icongltex.w = b32buf->x;
|
||||
icongltex.h = b32buf->y;
|
||||
icongltex.invw = 1.0f / b32buf->x;
|
||||
icongltex.invh = 1.0f / b32buf->y;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, icongltex.id);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect);
|
||||
|
||||
while (b16buf->x > 1) {
|
||||
ImBuf *nbuf = IMB_onehalf(b16buf);
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect);
|
||||
level++;
|
||||
IMB_freeImBuf(b16buf);
|
||||
b16buf = nbuf;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (glGetError() == GL_OUT_OF_MEMORY) {
|
||||
glDeleteTextures(1, &icongltex.id);
|
||||
icongltex.id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (icongltex.id)
|
||||
icontype = ICON_TYPE_TEXTURE;
|
||||
else
|
||||
icontype = ICON_TYPE_BUFFER;
|
||||
generate_mipmaps(&b32buf, &b16buf, &icongltex, ICON_GRID_ROWS, ICON_GRID_COLS, BIFICONID_FIRST);
|
||||
|
||||
if (b32buf) {
|
||||
for (y = 0; y < ICON_GRID_ROWS; y++) {
|
||||
for (x = 0; x < ICON_GRID_COLS; x++) {
|
||||
def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
|
||||
x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
|
||||
y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W,
|
||||
icontype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def_internal_vicon(VICO_VIEW3D_VEC, vicon_view3d_draw);
|
||||
def_internal_vicon(VICO_EDIT_VEC, vicon_edit_draw);
|
||||
def_internal_vicon(VICO_EDITMODE_VEC_DEHLT, vicon_editmode_dehlt_draw);
|
||||
@@ -695,10 +703,28 @@ static void init_internal_icons(void)
|
||||
def_internal_vicon(VICO_MOVE_DOWN_VEC, vicon_move_down_draw);
|
||||
def_internal_vicon(VICO_X_VEC, vicon_x_draw);
|
||||
def_internal_vicon(VICO_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);
|
||||
|
||||
|
||||
IMB_freeImBuf(b16buf);
|
||||
IMB_freeImBuf(b32buf);
|
||||
|
||||
/* operator icons */
|
||||
if (b16bufOps == NULL)
|
||||
b16bufOps = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_operator_icons16_png,
|
||||
datatoc_blender_operator_icons16_png_size, IB_rect, NULL, "<blender operator icons>");
|
||||
if (b16bufOps)
|
||||
IMB_premultiply_alpha(b16bufOps);
|
||||
|
||||
if (b32bufOps == NULL)
|
||||
b32bufOps = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_operator_icons32_png,
|
||||
datatoc_blender_operator_icons32_png_size, IB_rect, NULL, "<blender operator icons>");
|
||||
if (b32bufOps)
|
||||
IMB_premultiply_alpha(b32bufOps);
|
||||
|
||||
generate_mipmaps(&b32bufOps, &b16bufOps, &opicongltex, OPICON_GRID_ROWS, OPICON_GRID_COLS, BIFICONID_FIRST_OP);
|
||||
|
||||
IMB_freeImBuf(b16bufOps);
|
||||
IMB_freeImBuf(b32bufOps);
|
||||
|
||||
}
|
||||
#endif /* WITH_HEADLESS */
|
||||
|
||||
@@ -808,6 +834,11 @@ void UI_icons_free(void)
|
||||
glDeleteTextures(1, &icongltex.id);
|
||||
icongltex.id = 0;
|
||||
}
|
||||
|
||||
if (opicongltex.id) {
|
||||
glDeleteTextures(1, &opicongltex.id);
|
||||
opicongltex.id = 0;
|
||||
}
|
||||
|
||||
free_iconfile_list(&iconfilelist);
|
||||
BKE_icons_free();
|
||||
@@ -1035,20 +1066,21 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
|
||||
}
|
||||
|
||||
static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy,
|
||||
int UNUSED(iw), int ih, float alpha, const float rgb[3])
|
||||
int UNUSED(iw), int ih, float alpha, const float rgb[3],
|
||||
IconTexture *icontex)
|
||||
{
|
||||
float x1, x2, y1, y2;
|
||||
|
||||
if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha);
|
||||
else glColor4f(alpha, alpha, alpha, alpha);
|
||||
|
||||
x1 = ix * icongltex.invw;
|
||||
x2 = (ix + ih) * icongltex.invw;
|
||||
y1 = iy * icongltex.invh;
|
||||
y2 = (iy + ih) * icongltex.invh;
|
||||
x1 = ix * icontex->invw;
|
||||
x2 = (ix + ih) * icontex->invw;
|
||||
y1 = iy * icontex->invh;
|
||||
y2 = (iy + ih) * icontex->invh;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, icongltex.id);
|
||||
glBindTexture(GL_TEXTURE_2D, icontex->id);
|
||||
|
||||
/* sharper downscaling, has no effect when scale matches with a mip level */
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -0.5f);
|
||||
@@ -1126,7 +1158,8 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
|
||||
/* texture image use premul alpha for correct scaling */
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y,
|
||||
di->data.texture.w, di->data.texture.h, alpha, rgb);
|
||||
di->data.texture.w, di->data.texture.h, alpha, rgb,
|
||||
(icon_id >= BIFICONID_FIRST_OP ? &opicongltex : &icongltex));
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else if (di->type == ICON_TYPE_BUFFER) {
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "RNA_types.h"
|
||||
|
||||
struct ARegion;
|
||||
struct OperatorListItem;
|
||||
struct bContext;
|
||||
struct IDProperty;
|
||||
struct uiHandleButtonData;
|
||||
@@ -163,7 +164,7 @@ typedef struct {
|
||||
|
||||
struct uiBut {
|
||||
struct uiBut *next, *prev;
|
||||
int flag, drawflag;
|
||||
int flag, flag2, drawflag;
|
||||
eButType type;
|
||||
eButPointerType pointype;
|
||||
short bit, bitnr, retval, strwidth, alignnr;
|
||||
@@ -458,6 +459,24 @@ struct uiPopupBlockHandle {
|
||||
int direction;
|
||||
};
|
||||
|
||||
typedef enum uiHandleRegionDragState {
|
||||
REGION_STATE_DRAG_BUTTON_WAITING,
|
||||
REGION_STATE_DRAG_BUTTON,
|
||||
REGION_STATE_DRAG_EXIT
|
||||
} uiHandleRegionDragState;
|
||||
|
||||
struct uiHandleRegionDragData {
|
||||
/* keep track of dragging state */
|
||||
uiHandleRegionDragState state;
|
||||
|
||||
/* info for dragging */
|
||||
int startx, starty;
|
||||
|
||||
/* custom button */
|
||||
OperatorListItem *oli;
|
||||
int newindex;
|
||||
};
|
||||
|
||||
uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but);
|
||||
|
||||
struct ARegion *ui_tooltip_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
|
||||
@@ -497,7 +516,7 @@ struct AutoComplete;
|
||||
|
||||
/* interface_panel.c */
|
||||
extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event);
|
||||
extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *rect);
|
||||
extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *rect, int toolbar);
|
||||
|
||||
/* interface_draw.c */
|
||||
extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
|
||||
@@ -519,6 +538,7 @@ extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val);
|
||||
extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
|
||||
extern void ui_button_execute_do(struct bContext *C, struct ARegion *ar, uiBut *but);
|
||||
extern void ui_button_active_free(const struct bContext *C, uiBut *but);
|
||||
extern uiBut *ui_but_find_activated(ARegion *ar);
|
||||
extern bool ui_button_is_active(struct ARegion *ar);
|
||||
extern int ui_button_open_menu_direction(uiBut *but);
|
||||
extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, int restore);
|
||||
|
@@ -146,6 +146,7 @@ struct uiLayout {
|
||||
bool redalert;
|
||||
bool keepaspect;
|
||||
char alignment;
|
||||
float button_height;
|
||||
};
|
||||
|
||||
typedef struct uiLayoutItemFlow {
|
||||
@@ -237,13 +238,14 @@ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, int
|
||||
return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */
|
||||
}
|
||||
|
||||
static void ui_item_size(uiItem *item, int *r_w, int *r_h)
|
||||
static void ui_item_size(uiLayout *layout, uiItem *item, int *r_w, int *r_h)
|
||||
{
|
||||
if (item->type == ITEM_BUTTON) {
|
||||
uiButtonItem *bitem = (uiButtonItem *)item;
|
||||
|
||||
if (r_w) *r_w = BLI_rctf_size_x(&bitem->but->rect);
|
||||
if (r_h) *r_h = BLI_rctf_size_y(&bitem->but->rect);
|
||||
if (r_h) *r_h = BLI_rctf_size_y(&bitem->but->rect) *
|
||||
(layout->button_height ? layout->button_height : 1.0f);
|
||||
}
|
||||
else {
|
||||
uiLayout *litem = (uiLayout *)item;
|
||||
@@ -693,19 +695,28 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam
|
||||
name = "";
|
||||
}
|
||||
|
||||
/* Make sure that if it is indicated a button shouldn't be truncated to a
|
||||
single X unit, and a shortcut should be shown, then make sure we get
|
||||
the right width. */
|
||||
if ((!(flag & UI_ITEM_O_SINGLE_UNIT) || flag & UI_ITEM_O_SHORTCUT)
|
||||
&& block->flag & UI_BLOCK_SHORTCUTS)
|
||||
w = ui_text_icon_width(layout, "|", icon, 0);
|
||||
else if (flag & UI_ITEM_O_SINGLE_UNIT)
|
||||
w = UI_UNIT_X;
|
||||
else
|
||||
w = ui_text_icon_width(layout, name, icon, 0);
|
||||
|
||||
if (layout->root->type == UI_LAYOUT_MENU && !icon)
|
||||
icon = ICON_BLANK1;
|
||||
|
||||
/* create button */
|
||||
uiBlockSetCurLayout(block, layout);
|
||||
|
||||
w = ui_text_icon_width(layout, name, icon, 0);
|
||||
|
||||
if (flag & UI_ITEM_R_NO_BG)
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
|
||||
/* create the button */
|
||||
if (icon) {
|
||||
if (icon != 0) {
|
||||
if (name[0]) {
|
||||
but = uiDefIconTextButO_ptr(block, BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL);
|
||||
}
|
||||
@@ -716,12 +727,24 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam
|
||||
else {
|
||||
but = uiDefButO_ptr(block, BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Only show extra text when we're in a shortcut block and it was
|
||||
indicated the shortcut should be shown */
|
||||
if (flag & UI_ITEM_O_SHORTCUT && block->flag & UI_BLOCK_SHORTCUTS)
|
||||
but->flag2 |= UI_BUT2_EXTRA_TEXT;
|
||||
|
||||
/* Make operator buttons draggable */
|
||||
uiButSetDragOp(but, ot);
|
||||
|
||||
assert(but->optype != NULL);
|
||||
|
||||
/* text alignment for toolbar buttons */
|
||||
if ((layout->root->type == UI_LAYOUT_TOOLBAR) && !icon)
|
||||
if ((layout->root->type == UI_LAYOUT_TOOLBAR) && (!icon || flag & UI_ITEM_O_SHORTCUT)) {
|
||||
but->flag |= UI_TEXT_LEFT;
|
||||
}
|
||||
|
||||
if (layout->root->type == UI_LAYOUT_TOOLBAR && !(flag & UI_ITEM_O_SHORTCUT) && !name[0])
|
||||
but->flag &= ~UI_ICON_LEFT;
|
||||
|
||||
if (flag & UI_ITEM_R_NO_BG)
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
@@ -1801,6 +1824,41 @@ void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propn
|
||||
ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl, RNA_property_description(prop), false);
|
||||
}
|
||||
|
||||
/********************* OperatorListItem utilities ********************/
|
||||
|
||||
/* return 1 when an OperatorListItem with the same name and properties is already present in lb */
|
||||
OperatorListItem *uiOperatorListItemPresent(ListBase *lb, const char *idname, IDProperty *properties, const char *context)
|
||||
{
|
||||
OperatorListItem *oli;
|
||||
|
||||
for (oli = lb->first; oli; oli = oli->next) {
|
||||
|
||||
if (strcmp(oli->optype_idname, idname) == 0) {
|
||||
if (strcmp(oli->context, context) == 0) {
|
||||
/* if no idprops are present, and the name is the same */
|
||||
if (oli->properties == NULL && properties == NULL) {
|
||||
return oli;
|
||||
}
|
||||
/* if one of the properties is set, then they are not equal */
|
||||
else if (oli->properties == NULL || properties == NULL) {
|
||||
continue;
|
||||
}
|
||||
else if (IDP_EqualsProperties(oli->properties, properties)) {
|
||||
return oli;
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**************************** Layout Items ***************************/
|
||||
|
||||
/* single-row layout */
|
||||
@@ -1813,7 +1871,7 @@ static void ui_litem_estimate_row(uiLayout *litem)
|
||||
litem->h = 0;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
litem->w += itemw;
|
||||
litem->h = MAX2(itemh, litem->h);
|
||||
@@ -1841,7 +1899,7 @@ static void ui_litem_layout_row(uiLayout *litem)
|
||||
tot = 0;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
totw += itemw;
|
||||
tot++;
|
||||
}
|
||||
@@ -1863,7 +1921,7 @@ static void ui_litem_layout_row(uiLayout *litem)
|
||||
if (item->flag)
|
||||
continue;
|
||||
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
minw = ui_litem_min_width(itemw);
|
||||
|
||||
if (w - lastw > 0)
|
||||
@@ -1895,7 +1953,7 @@ static void ui_litem_layout_row(uiLayout *litem)
|
||||
x = litem->x;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
minw = ui_litem_min_width(itemw);
|
||||
|
||||
if (item->flag) {
|
||||
@@ -1944,7 +2002,7 @@ static void ui_litem_estimate_column(uiLayout *litem)
|
||||
litem->h = 0;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
litem->w = MAX2(litem->w, itemw);
|
||||
litem->h += itemh;
|
||||
@@ -1963,7 +2021,7 @@ static void ui_litem_layout_column(uiLayout *litem)
|
||||
y = litem->y;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, NULL, &itemh);
|
||||
ui_item_size(litem, item, NULL, &itemh);
|
||||
|
||||
y -= itemh;
|
||||
ui_item_position(item, x, y, litem->w, itemh);
|
||||
@@ -2045,7 +2103,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
|
||||
toth = 0;
|
||||
totitem = 0;
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
maxw = MAX2(maxw, itemw);
|
||||
toth += itemh;
|
||||
totitem++;
|
||||
@@ -2076,7 +2134,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
|
||||
/* create column per column */
|
||||
col = 0;
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
y -= itemh + style->buttonspacey;
|
||||
miny = min_ii(miny, y);
|
||||
@@ -2109,7 +2167,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
|
||||
toth = 0;
|
||||
totitem = 0;
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
toth += itemh;
|
||||
totitem++;
|
||||
}
|
||||
@@ -2126,7 +2184,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
|
||||
/* create column per column */
|
||||
col = 0;
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, NULL, &itemh);
|
||||
ui_item_size(litem, item, NULL, &itemh);
|
||||
itemw = ui_item_fit(1, x - litem->x, flow->totcol, w, col == flow->totcol - 1, litem->alignment, &offset);
|
||||
|
||||
y -= itemh;
|
||||
@@ -2162,7 +2220,7 @@ static void ui_litem_estimate_absolute(uiLayout *litem)
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_offset(item, &itemx, &itemy);
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
minx = min_ii(minx, itemx);
|
||||
miny = min_ii(miny, itemy);
|
||||
@@ -2188,7 +2246,7 @@ static void ui_litem_layout_absolute(uiLayout *litem)
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_offset(item, &itemx, &itemy);
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
minx = min_ii(minx, itemx);
|
||||
miny = min_ii(miny, itemy);
|
||||
@@ -2210,7 +2268,7 @@ static void ui_litem_layout_absolute(uiLayout *litem)
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_offset(item, &itemx, &itemy);
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
if (scalex != 1.0f) {
|
||||
newx = (itemx - minx) * scalex;
|
||||
@@ -2260,7 +2318,7 @@ static void ui_litem_layout_split(uiLayout *litem)
|
||||
colw = MAX2(colw, 0);
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, NULL, &itemh);
|
||||
ui_item_size(litem, item, NULL, &itemh);
|
||||
|
||||
ui_item_position(item, x, y - itemh, colw, itemh);
|
||||
x += colw;
|
||||
@@ -2289,7 +2347,7 @@ static void ui_litem_estimate_overlap(uiLayout *litem)
|
||||
litem->h = 0;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
|
||||
litem->w = MAX2(itemw, litem->w);
|
||||
litem->h = MAX2(itemh, litem->h);
|
||||
@@ -2305,7 +2363,7 @@ static void ui_litem_layout_overlap(uiLayout *litem)
|
||||
y = litem->y;
|
||||
|
||||
for (item = litem->items.first; item; item = item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_size(litem, item, &itemw, &itemh);
|
||||
ui_item_position(item, x, y - itemh, litem->w, itemh);
|
||||
|
||||
litem->h = MAX2(litem->h, itemh);
|
||||
@@ -2316,10 +2374,11 @@ static void ui_litem_layout_overlap(uiLayout *litem)
|
||||
}
|
||||
|
||||
/* layout create functions */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align)
|
||||
|
||||
static uiLayout *ui_layout_row(uiLayout *layout, int align, float button_height)
|
||||
{
|
||||
uiLayout *litem;
|
||||
|
||||
|
||||
litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRow");
|
||||
litem->item.type = ITEM_LAYOUT_ROW;
|
||||
litem->root = layout->root;
|
||||
@@ -2330,14 +2389,25 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align)
|
||||
litem->space = (align) ? 0 : layout->root->style->buttonspacex;
|
||||
litem->redalert = layout->redalert;
|
||||
litem->w = layout->w;
|
||||
litem->button_height = button_height;
|
||||
BLI_addtail(&layout->items, litem);
|
||||
|
||||
|
||||
uiBlockSetCurLayout(layout->root->block, litem);
|
||||
|
||||
|
||||
return litem;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutColumn(uiLayout *layout, int align)
|
||||
uiLayout *uiLayoutRowWithButtonHeight(uiLayout *layout, int align, float button_height)
|
||||
{
|
||||
return ui_layout_row(layout, align, button_height);
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align)
|
||||
{
|
||||
return ui_layout_row(layout, align, 1.0f);
|
||||
}
|
||||
|
||||
static uiLayout *ui_layout_column(uiLayout *layout, int align, float button_height)
|
||||
{
|
||||
uiLayout *litem;
|
||||
|
||||
@@ -2351,6 +2421,7 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align)
|
||||
litem->space = (litem->align) ? 0 : layout->root->style->buttonspacey;
|
||||
litem->redalert = layout->redalert;
|
||||
litem->w = layout->w;
|
||||
litem->button_height = button_height;
|
||||
BLI_addtail(&layout->items, litem);
|
||||
|
||||
uiBlockSetCurLayout(layout->root->block, litem);
|
||||
@@ -2358,6 +2429,16 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align)
|
||||
return litem;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutColumn(uiLayout *layout, int align)
|
||||
{
|
||||
return ui_layout_column(layout, align, 1.0f);
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutColumnWithButtonHeight(uiLayout *layout, int align, float button_height)
|
||||
{
|
||||
return ui_layout_column(layout, align, button_height);
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
|
||||
{
|
||||
uiLayoutItemFlow *flow;
|
||||
@@ -2601,7 +2682,7 @@ static void ui_item_scale(uiLayout *litem, const float scale[2])
|
||||
int x, y, w, h;
|
||||
|
||||
for (item = litem->items.last; item; item = item->prev) {
|
||||
ui_item_size(item, &w, &h);
|
||||
ui_item_size(litem, item, &w, &h);
|
||||
ui_item_offset(item, &x, &y);
|
||||
|
||||
if (scale[0] != 0.0f) {
|
||||
@@ -3107,6 +3188,69 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
|
||||
}
|
||||
}
|
||||
|
||||
void uiLayoutOperatorTypeDefaultsButs(const bContext *C, uiLayout *layout, wmOperator *op)
|
||||
{
|
||||
char *h = BLI_sprintfN("Default parameters: %s", RNA_struct_ui_name(op->type->srna));
|
||||
|
||||
uiItemL(layout, h, ICON_NONE);
|
||||
MEM_freeN(h);
|
||||
|
||||
// use operator's custom panel
|
||||
if (op->type->ui) {
|
||||
op->layout = layout;
|
||||
op->type->ui((bContext *)C, op);
|
||||
op->layout = NULL;
|
||||
}
|
||||
// autogenerate panel
|
||||
else {
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
PointerRNA ptr;
|
||||
int empty;
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
|
||||
empty = uiDefAutoButsRNA(layout, &ptr, NULL, 'V') == 0;
|
||||
|
||||
if (empty) {
|
||||
uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OP_RESET_BUT
|
||||
/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
|
||||
* but this is not so important if this button is drawn in those cases
|
||||
* (which isn't all that likely anyway) - campbell */
|
||||
if (op->properties->len) {
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
uiLayout *col; /* needed to avoid alignment errors with previous buttons */
|
||||
|
||||
col = uiLayoutColumn(layout, FALSE);
|
||||
block = uiLayoutGetBlock(col);
|
||||
but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
|
||||
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
|
||||
uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set various special settings for buttons */
|
||||
{
|
||||
uiBut *but;
|
||||
|
||||
for (but = uiLayoutGetBlock(layout)->buttons.first; but; but = but->next) {
|
||||
/* no undo for buttons for operator redo panels */
|
||||
uiButClearFlag(but, UI_BUT_UNDO);
|
||||
|
||||
/* if button is operator's default property, and a text-field, enable focus for it
|
||||
* - this is used for allowing operators with popups to rename stuff with fewer clicks
|
||||
*/
|
||||
if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
|
||||
uiButSetFocusOnEnter(CTX_wm_window(C), but);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this is a bit of a hack but best keep it in one place at least */
|
||||
MenuType *uiButGetMenuType(uiBut *but)
|
||||
{
|
||||
|
@@ -49,6 +49,8 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
@@ -61,6 +63,8 @@
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "interface_intern.h"
|
||||
|
||||
/*********************** defines and structs ************************/
|
||||
@@ -68,19 +72,14 @@
|
||||
#define ANIMATION_TIME 0.30
|
||||
#define ANIMATION_INTERVAL 0.02
|
||||
|
||||
#define PNL_LAST_ADDED 1
|
||||
#define PNL_ACTIVE 2
|
||||
#define PNL_WAS_ACTIVE 4
|
||||
#define PNL_ANIM_ALIGN 8
|
||||
#define PNL_NEW_ADDED 16
|
||||
#define PNL_FIRST 32
|
||||
|
||||
typedef enum uiHandlePanelState {
|
||||
PANEL_STATE_DRAG,
|
||||
PANEL_STATE_DRAG_SCALE,
|
||||
PANEL_STATE_WAIT_UNTAB,
|
||||
PANEL_STATE_ANIMATION,
|
||||
PANEL_STATE_EXIT
|
||||
PANEL_STATE_EXIT,
|
||||
PANEL_STATE_DRAG_BUTTON_WAITING,
|
||||
PANEL_STATE_DRAG_BUTTON
|
||||
} uiHandlePanelState;
|
||||
|
||||
typedef struct uiHandlePanelData {
|
||||
@@ -94,6 +93,11 @@ typedef struct uiHandlePanelData {
|
||||
int startx, starty;
|
||||
int startofsx, startofsy;
|
||||
int startsizex, startsizey;
|
||||
|
||||
/* dragging custom button */
|
||||
OperatorListItem *oli;
|
||||
int newindex;
|
||||
|
||||
} uiHandlePanelData;
|
||||
|
||||
static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state);
|
||||
@@ -162,21 +166,29 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
|
||||
|
||||
/****************************** panels ******************************/
|
||||
|
||||
static void panels_collapse_all(ScrArea *sa, ARegion *ar, Panel *from_pa)
|
||||
void uiCollapseAllPanels(ScrArea *sa, ARegion *ar, const char *context)
|
||||
{
|
||||
Panel *pa;
|
||||
PanelType *pt, *from_pt;
|
||||
PanelType *pt;
|
||||
int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
pt = pa->type;
|
||||
from_pt = from_pa->type;
|
||||
|
||||
/* close panels with headers in the same context */
|
||||
if (pt && from_pt && !(pt->flag & PNL_NO_HEADER))
|
||||
if (!pt->context[0] || strcmp(pt->context, from_pt->context) == 0)
|
||||
pa->flag = flag;
|
||||
if (pt && context && !(pt->flag & PNL_NO_HEADER))
|
||||
if (!pt->context[0] || strcmp(pt->context, context) == 0) {
|
||||
pa->flag |= flag;
|
||||
pa->ofsx = 0;
|
||||
pa->ofsy = 0;
|
||||
pa->sizex = 0;
|
||||
pa->sizey = 0;
|
||||
pa->runtime_flag |= PNL_NEW_ADDED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
|
||||
@@ -188,6 +200,20 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
|
||||
pa->ofsy = papar->ofsy + papar->sizey - pa->sizey;
|
||||
}
|
||||
|
||||
Panel *uiGetExistingPanel(ARegion *ar, PanelType *pt)
|
||||
{
|
||||
Panel *pa = NULL;
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next)
|
||||
if (strncmp(pa->panelname, pt->idname, UI_MAX_NAME_STR) == 0)
|
||||
if (strncmp(pa->tabname, pt->idname, UI_MAX_NAME_STR) == 0) {
|
||||
pa->type = pt;
|
||||
break;
|
||||
}
|
||||
|
||||
return pa;
|
||||
}
|
||||
|
||||
Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int *open)
|
||||
{
|
||||
Panel *pa, *patab, *palast, *panext;
|
||||
@@ -199,17 +225,11 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int
|
||||
int align = panel_aligned(sa, ar);
|
||||
|
||||
/* check if Panel exists, then use that one */
|
||||
for (pa = ar->panels.first; pa; pa = pa->next)
|
||||
if (strncmp(pa->panelname, idname, UI_MAX_NAME_STR) == 0)
|
||||
if (strncmp(pa->tabname, tabname, UI_MAX_NAME_STR) == 0)
|
||||
break;
|
||||
pa = uiGetExistingPanel(ar, pt);
|
||||
|
||||
newpanel = (pa == NULL);
|
||||
|
||||
if (!newpanel) {
|
||||
pa->type = pt;
|
||||
}
|
||||
else {
|
||||
if (newpanel) {
|
||||
/* new panel */
|
||||
pa = MEM_callocN(sizeof(Panel), "new panel");
|
||||
pa->type = pt;
|
||||
@@ -228,6 +248,12 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int
|
||||
pa->sizex = 0;
|
||||
pa->sizey = 0;
|
||||
pa->runtime_flag |= PNL_NEW_ADDED;
|
||||
|
||||
// Mark the new panel as custom so we know we have to generate the PanelTypes upon loading
|
||||
if (pt->flag & PNL_CUSTOM_PANELTYPE) {
|
||||
pa->flag |= PNL_CUSTOM_PANEL;
|
||||
BLI_strncpy(pa->context, pt->context, MAX_NAME);
|
||||
}
|
||||
|
||||
BLI_addtail(&ar->panels, pa);
|
||||
|
||||
@@ -437,6 +463,28 @@ static void ui_draw_panel_scalewidget(rcti *rect)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
static void ui_draw_panel_openwidget(const rctf *rect)
|
||||
{
|
||||
float xmin, xmax, dx;
|
||||
float ymin, ymax, dy;
|
||||
|
||||
xmin = rect->xmin;
|
||||
xmax = rect->xmax;
|
||||
ymin = rect->ymin;
|
||||
ymax = rect->ymax;
|
||||
|
||||
dx = (xmax - xmin);
|
||||
dy = (ymax - ymin);
|
||||
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glColor4ub(0, 0, 0, 150);
|
||||
fdrawellipses(xmin, ymin + dy / 2.f, dx / 10.f);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
static void ui_draw_panel_dragwidget(const rctf *rect)
|
||||
{
|
||||
float xmin, xmax, dx;
|
||||
@@ -484,6 +532,7 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, rcti *r
|
||||
hrect = *rect;
|
||||
if (dir == 'h') {
|
||||
hrect.xmin = rect->xmin + pnl_icons;
|
||||
hrect.xmax = hrect.xmin + BLI_rcti_size_x(&hrect) - (2*PNL_ICON) / block->aspect;
|
||||
hrect.ymin += 2.0f / block->aspect;
|
||||
uiStyleFontDraw(&style->paneltitle, &hrect, activename);
|
||||
}
|
||||
@@ -510,7 +559,7 @@ static void rectf_scale(rctf *rect, const float scale)
|
||||
}
|
||||
|
||||
/* panel integrated in buttonswindow, tool/property lists etc */
|
||||
void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
|
||||
void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect, int UNUSED(toolbar))
|
||||
{
|
||||
Panel *panel = block->panel;
|
||||
rcti headrect;
|
||||
@@ -573,6 +622,16 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
|
||||
* (------)
|
||||
*/
|
||||
if (panel->flag & PNL_CLOSEDY) {
|
||||
// Uncomment to only show popup ellipses in the toolbar.
|
||||
//if (toolbar) {
|
||||
/* draw popup widget */
|
||||
itemrect.xmax = headrect.xmax - (1.0f + PNL_ICON) / block->aspect;
|
||||
itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
|
||||
itemrect.ymin = headrect.ymin;
|
||||
itemrect.ymax = headrect.ymax;
|
||||
rectf_scale(&itemrect, 0.7f);
|
||||
ui_draw_panel_openwidget(&itemrect);
|
||||
//}
|
||||
}
|
||||
else if (panel->flag & PNL_CLOSEDX) {
|
||||
/* draw vertical title */
|
||||
@@ -631,6 +690,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
|
||||
(void)ofsx;
|
||||
}
|
||||
|
||||
|
||||
/************************** panel alignment *************************/
|
||||
|
||||
static int get_panel_header(Panel *pa)
|
||||
@@ -871,9 +931,12 @@ static void ui_do_animate(const bContext *C, Panel *panel)
|
||||
}
|
||||
}
|
||||
|
||||
void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar)
|
||||
void uiBeginPanels(const bContext *C, ARegion *ar)
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
Panel *pa;
|
||||
PanelType *pt;
|
||||
|
||||
/* set all panels as inactive, so that at the end we know
|
||||
* which ones were used */
|
||||
@@ -882,6 +945,14 @@ void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar)
|
||||
pa->runtime_flag = PNL_WAS_ACTIVE;
|
||||
else
|
||||
pa->runtime_flag = 0;
|
||||
|
||||
/* Only create a custom paneltype when the panel is a custom panel
|
||||
* and it's the correct context. */
|
||||
if (pa->type == NULL && pa->flag & PNL_CUSTOM_PANEL && strcmp(context, pa->context) == 0) {
|
||||
/* recreate custom paneltypes for typeless panels */
|
||||
pt = uiCreateCustomPanelType(sa, ar, context, pa->panelname, pa->drawname);
|
||||
pa->type = pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1055,17 +1126,182 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void ui_do_drag_button(const bContext *C, const wmEvent *event, Panel *pa)
|
||||
{
|
||||
uiHandlePanelData *data = pa->activedata;
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
int cur_index = BLI_findindex(&pa->operators, data->oli);
|
||||
int dy, dunits, maxindex;
|
||||
|
||||
// Calculate the new index of the button based on the drag offset
|
||||
dy = event->y - data->starty;
|
||||
dunits = dy / UI_UNIT_Y;
|
||||
data->newindex = (cur_index - dunits);
|
||||
maxindex = (BLI_countlist(&pa->operators) - 1);
|
||||
CLAMP(data->newindex, 0, maxindex);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void ui_do_drag_button_finish(const bContext *C, const wmEvent *UNUSED(event), Panel *pa)
|
||||
{
|
||||
uiHandlePanelData *data = pa->activedata;
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
int cur_index = BLI_findindex(&pa->operators, data->oli);
|
||||
OperatorListItem *oli_target = BLI_findlink(&pa->operators, data->newindex);
|
||||
|
||||
if (data->newindex < cur_index) {
|
||||
BLI_remlink(&pa->operators, data->oli);
|
||||
BLI_insertlinkbefore(&pa->operators, oli_target, data->oli);
|
||||
}
|
||||
else if (data->newindex > cur_index) {
|
||||
BLI_remlink(&pa->operators, data->oli);
|
||||
BLI_insertlinkafter(&pa->operators, oli_target, data->oli);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
/******************* region level panel interaction *****************/
|
||||
|
||||
static void panel_popup_draw(bContext *C, uiBlock *block, Panel *pa)
|
||||
{
|
||||
uiStyle *style = UI_GetStyleDraw();
|
||||
Panel *pa_copy;
|
||||
int xco, yco;
|
||||
int w = UI_PANEL_WIDTH / 2;
|
||||
int em = UI_UNIT_Y;
|
||||
|
||||
if (pa) {
|
||||
|
||||
/* Create a copy of the panel so that we can reset the ofset */
|
||||
pa_copy = MEM_callocN(sizeof(Panel), "new panel");
|
||||
memcpy(pa_copy, pa, sizeof(Panel));
|
||||
|
||||
pa_copy->ofsx = 0;
|
||||
pa_copy->ofsy = 0;
|
||||
pa_copy->sizex = 0;
|
||||
pa_copy->sizey = 0;
|
||||
|
||||
uiBlockSetPanel(block, pa_copy);
|
||||
|
||||
pa_copy->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_TOOLBAR,
|
||||
style->panelspace, 0, w - 2 * style->panelspace, em, style);
|
||||
pa_copy->type->draw(C, pa_copy);
|
||||
pa_copy->labelofs = 0;
|
||||
uiBlockLayoutResolve(block, &xco, &yco);
|
||||
|
||||
yco -= 2 * style->panelspace;
|
||||
uiEndPanel(block, w, 0);
|
||||
|
||||
uiBlockSetPanel(block, NULL);
|
||||
/* N.B. don't use uiPanelFree because the operator list is shared with the original. */
|
||||
MEM_freeN(pa_copy);
|
||||
}
|
||||
}
|
||||
|
||||
static uiBlock *panel_popup_create_block(bContext *C, ARegion *ar, void *pa_arg)
|
||||
{
|
||||
uiBlock *block;
|
||||
Panel *pa = (Panel*)pa_arg;
|
||||
|
||||
block = uiBeginBlock(C, ar, "popup", UI_EMBOSS);
|
||||
|
||||
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
||||
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
|
||||
panel_popup_draw(C, block, pa);
|
||||
|
||||
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
||||
uiEndBlock(C, block);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static void rename_custom_panel(bContext *C, void *but_arg, void *pa_arg)
|
||||
{
|
||||
uiBut *but = but_arg;
|
||||
Panel *pa = pa_arg;
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
if (pa->type) {
|
||||
BLI_strncpy(pa->type->label, but->drawstr, MAX_NAME);
|
||||
BLI_strncpy(pa->drawname, but->drawstr, MAX_NAME);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void delete_custom_panel(bContext *C, void *pa_arg, void *UNUSED(arg2))
|
||||
{
|
||||
Panel *pa = pa_arg;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
|
||||
if (pa->type && ar->type)
|
||||
BLI_freelinkN(&ar->type->paneltypes, pa->type);
|
||||
|
||||
BLI_remlink(&ar->panels, pa);
|
||||
uiPanelFree(pa);
|
||||
|
||||
/* make sure we don't leave gaps in the layout */
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
|
||||
}
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static uiBlock *custom_panel_options_create_block(bContext *C, ARegion *ar, void *pa_arg)
|
||||
{
|
||||
uiBlock *block;
|
||||
Panel *pa = (Panel*)pa_arg; // the custom panel
|
||||
uiLayout *layout;
|
||||
uiBut *but;
|
||||
PointerRNA ptr;
|
||||
uiStyle *style = UI_GetStyleDraw();
|
||||
|
||||
int xco, yco;
|
||||
int w = UI_PANEL_WIDTH / 2;
|
||||
int em = UI_UNIT_Y;
|
||||
|
||||
block = uiBeginBlock(C, ar, "panel options", UI_EMBOSS);
|
||||
|
||||
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
||||
uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
|
||||
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_TOOLBAR,
|
||||
style->panelspace, 0, w - 2 * style->panelspace, em, style);
|
||||
|
||||
/* Rename panel */
|
||||
RNA_pointer_create(NULL, &RNA_Panel, pa, &ptr);
|
||||
|
||||
but = uiDefButR(block, TEX, 1, "", 0, 0, w, UI_UNIT_Y,
|
||||
&ptr, "text", -1, 0, 0, -1, -1, NULL);
|
||||
uiButSetFunc(but, rename_custom_panel, but, pa);
|
||||
|
||||
|
||||
/* Delete panel button */
|
||||
but = uiDefIconTextBut(block, BUTM, 0, ICON_NONE, IFACE_("Delete Panel"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
uiButSetFunc(but, delete_custom_panel, pa, NULL);
|
||||
|
||||
uiBlockLayoutResolve(block, &xco, &yco);
|
||||
|
||||
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
||||
uiEndBlock(C, block);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/* this function is supposed to call general window drawing too */
|
||||
/* also it supposes a block has panel, and isn't a menu */
|
||||
static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event, int ctrl)
|
||||
static void ui_handle_panel_header(bContext *C, uiBlock *block, int mx, int my, int event, int ctrl)
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Panel *pa;
|
||||
int align = panel_aligned(sa, ar), button = 0;
|
||||
int x_popup = block->rect.xmax - ((2 * PNL_ICON) + 5) / block->aspect;
|
||||
int x_drag = block->rect.xmax - (PNL_ICON + 5) / block->aspect;
|
||||
|
||||
/* mouse coordinates in panel space! */
|
||||
|
||||
@@ -1081,20 +1317,30 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
|
||||
}
|
||||
else if (block->panel->control & UI_PNL_CLOSE) {
|
||||
/* whole of header can be used to collapse panel (except top-right corner) */
|
||||
if (mx <= block->rect.xmax - 8 - PNL_ICON) button = 2;
|
||||
//else if (mx <= block->rect.xmin + 10 + 2 * PNL_ICON + 2) button = 1;
|
||||
if (mx <= x_drag) button = 2;
|
||||
}
|
||||
else if (mx <= block->rect.xmax - PNL_ICON - 12) {
|
||||
button = 1;
|
||||
}
|
||||
|
||||
if (button) {
|
||||
if (button == 2) { /* close */
|
||||
ED_region_tag_redraw(ar);
|
||||
// only shows popups in toolbars
|
||||
else if (block->panel->flag & PNL_CLOSEDY /*&& ar->regiontype == RGN_TYPE_TOOLS*/) {
|
||||
if (mx <= x_popup) {
|
||||
button = 1;
|
||||
} else if (mx > x_popup && mx <= x_drag) {
|
||||
button = 3; // popup!
|
||||
} else if (mx > x_drag) {
|
||||
button = 4; // drag
|
||||
}
|
||||
else { /* collapse */
|
||||
} else {
|
||||
if (mx > x_drag) {
|
||||
button = 4; // drag
|
||||
} else {
|
||||
button = 1; // open
|
||||
}
|
||||
}
|
||||
|
||||
switch (button) {
|
||||
case 1:
|
||||
/* collapse */
|
||||
if (ctrl)
|
||||
panels_collapse_all(sa, ar, block->panel);
|
||||
uiCollapseAllPanels(sa, ar, CTX_data_mode_string(C));
|
||||
|
||||
if (block->panel->flag & PNL_CLOSED) {
|
||||
block->panel->flag &= ~PNL_CLOSED;
|
||||
@@ -1118,15 +1364,23 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
|
||||
else pa->flag &= ~PNL_CLOSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (align)
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_ANIMATION);
|
||||
else
|
||||
case 2:
|
||||
/* close */
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
else if (mx <= (block->rect.xmax - PNL_ICON - 12) + PNL_ICON + 2) {
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
|
||||
if (align)
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_ANIMATION);
|
||||
if (ar->regiontype == RGN_TYPE_TOOL_PROPS) {
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
/* The size of the redo panel region needs to be calculated again */
|
||||
CTX_wm_screen(C)->do_refresh = TRUE;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
uiPupBlock(C, panel_popup_create_block, block->panel);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,24 +1434,49 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event)
|
||||
}
|
||||
|
||||
/* XXX hardcoded key warning */
|
||||
if ((inside || inside_header) && event->val == KM_PRESS) {
|
||||
if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) {
|
||||
|
||||
if (pa->flag & PNL_CLOSEDY) {
|
||||
if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my))
|
||||
if (inside || inside_header) {
|
||||
if (event->val == KM_PRESS) {
|
||||
if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) {
|
||||
|
||||
if (pa->flag & PNL_CLOSEDY) {
|
||||
if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my))
|
||||
ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
|
||||
}
|
||||
else
|
||||
ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
|
||||
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
|
||||
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* on active button, do not handle panels */
|
||||
if (ui_button_is_active(ar))
|
||||
/* This catches the drag events here so that we can do our own custom drag instead
|
||||
* of having the drag & drop system handle the button/op drag. */
|
||||
|
||||
|
||||
/* on active button, do a possible button drag for reordering, but panels should
|
||||
* not be handled. */
|
||||
|
||||
if (ui_button_is_active(ar)) {
|
||||
uiBut *but = ui_but_find_activated(ar);
|
||||
uiHandlePanelData *data;
|
||||
|
||||
if (inside && but && pa->flag & PNL_CUSTOM_PANEL) {
|
||||
// Are we starting a potential drag?
|
||||
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
|
||||
panel_activate_state(C, pa, PANEL_STATE_DRAG_BUTTON_WAITING);
|
||||
// pass the oli that is being dragged
|
||||
data = pa->activedata;
|
||||
// TODO: also check for oli->properties equality
|
||||
data->oli = BLI_findstring(&pa->operators, but->optype->idname, offsetof(OperatorListItem, optype_idname));
|
||||
}
|
||||
}
|
||||
|
||||
// Don't handle events for the panels if a button was activated
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (inside || inside_header) {
|
||||
|
||||
@@ -1266,6 +1545,9 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (event->type == RIGHTMOUSE && pa->flag & PNL_CUSTOM_PANEL) {
|
||||
uiPupBlock(C, custom_panel_options_create_block, block->panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1280,13 +1562,18 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
|
||||
{
|
||||
Panel *panel = userdata;
|
||||
uiHandlePanelData *data = panel->activedata;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
uiBut *but;
|
||||
|
||||
/* verify if we can stop */
|
||||
|
||||
if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
int align = panel_aligned(sa, ar);
|
||||
|
||||
if (data->state == PANEL_STATE_DRAG_BUTTON)
|
||||
ui_do_drag_button_finish(C, event, panel);
|
||||
|
||||
if (align)
|
||||
panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
|
||||
else
|
||||
@@ -1295,6 +1582,14 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
|
||||
else if (event->type == MOUSEMOVE) {
|
||||
if (data->state == PANEL_STATE_DRAG)
|
||||
ui_do_drag(C, event, panel);
|
||||
if (data->state == PANEL_STATE_DRAG_BUTTON_WAITING && ABS(data->starty - event->y) > (UI_UNIT_Y / 2)) {
|
||||
panel_activate_state(C, panel, PANEL_STATE_DRAG_BUTTON);
|
||||
but = ui_but_find_activated(ar);
|
||||
ui_button_active_free(C, but);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
if (data->state == PANEL_STATE_DRAG_BUTTON)
|
||||
ui_do_drag_button(C, event, panel);
|
||||
}
|
||||
else if (event->type == TIMER && event->customdata == data->animtimer) {
|
||||
if (data->state == PANEL_STATE_ANIMATION)
|
||||
@@ -1379,3 +1674,129 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
|
||||
void uiPanelAddOperator(bContext *C, Panel *pa, wmOperatorType *ot, PointerRNA *opptr)
|
||||
{
|
||||
OperatorListItem *oli;
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
|
||||
if (uiOperatorListItemPresent(&pa->operators, ot->idname, opptr->data, CTX_data_mode_string(C))) {
|
||||
BKE_reportf(&wm->reports, RPT_INFO, "This operator (%s) is already present in this panel.", ot->idname);
|
||||
return;
|
||||
}
|
||||
|
||||
oli = MEM_callocN(sizeof(OperatorListItem), "panel type operator");
|
||||
BLI_strncpy(oli->optype_idname, ot->idname, OP_MAX_TYPENAME);
|
||||
BLI_strncpy(oli->context, CTX_data_mode_string(C), MAX_NAME);
|
||||
|
||||
if (opptr) {
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_struct_find_property(opptr, "COPY_opcontext");
|
||||
if(prop)
|
||||
oli->opcontext = RNA_property_int_get(opptr, prop);
|
||||
|
||||
/* clear the properties that were only necessary for this operator execution */
|
||||
/* TODO: see if this can all be done a little bit nicer by including a pointer as a property */
|
||||
RNA_struct_idprops_unset(opptr, "COPY_opcontext");
|
||||
RNA_struct_idprops_unset(opptr, "COPY_idname");
|
||||
RNA_struct_idprops_unset(opptr, "COPY_paneltypeid");
|
||||
|
||||
oli->properties = IDP_CopyProperty(opptr->data);
|
||||
}
|
||||
|
||||
BLI_addtail(&pa->operators, oli);
|
||||
}
|
||||
|
||||
void uiPanelFree(Panel *pa)
|
||||
{
|
||||
if (pa == NULL) return;
|
||||
OperatorListItem *oli;
|
||||
|
||||
while ((oli = (OperatorListItem*)BLI_pophead(&pa->operators))) {
|
||||
BKE_operator_list_item_free(oli);
|
||||
}
|
||||
MEM_freeN(pa);
|
||||
}
|
||||
|
||||
int uiPanelClosed(Panel *pa)
|
||||
{
|
||||
if (pa == NULL) return 0;
|
||||
|
||||
return (pa->flag & PNL_CLOSED || pa->flag & PNL_CLOSEDX || pa->flag & PNL_CLOSEDY);
|
||||
}
|
||||
|
||||
static void custom_panel_draw_oli(const bContext *C, uiLayout *column, OperatorListItem *oli)
|
||||
{
|
||||
if (oli && column) {
|
||||
wmOperatorType *ot = WM_operatortype_find(oli->optype_idname, TRUE);
|
||||
int icon = ICON_NONE;
|
||||
PointerRNA ptr;
|
||||
|
||||
WM_operator_properties_create_ptr(&ptr, ot);
|
||||
ptr.data = oli->properties;
|
||||
|
||||
icon = ot->icon ? ot->icon(C, &ptr) : ot->default_icon;
|
||||
|
||||
if (icon != ICON_NONE)
|
||||
uiItemFullO_ptr(column, ot, ot->name, ICON_AUTOMATIC, IDP_CopyProperty(oli->properties), oli->opcontext, 0);
|
||||
else
|
||||
uiItemFullO_ptr(column, ot, ot->name, ICON_NONE, IDP_CopyProperty(oli->properties), oli->opcontext, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void custom_panel_draw(const bContext *C, Panel *pa)
|
||||
{
|
||||
uiHandlePanelData *data = pa->activedata;
|
||||
uiLayout *layout = pa->layout;
|
||||
uiLayout *column = uiLayoutColumn(layout, TRUE);
|
||||
OperatorListItem *oli;
|
||||
int drag_state = data ? (data->state == PANEL_STATE_DRAG_BUTTON) : 0;
|
||||
int i = 0;
|
||||
|
||||
for (oli = pa->operators.first; oli; oli = oli->next) {
|
||||
if (drag_state) {
|
||||
// draw the new order of buttons
|
||||
if (i == data->newindex) {
|
||||
// Don't draw a separator for its current position
|
||||
int cur_index = BLI_findindex(&pa->operators, data->oli);
|
||||
// draw it before or after the button that currently has the new index
|
||||
if (data->newindex == cur_index) {
|
||||
custom_panel_draw_oli(C, column, oli);
|
||||
}
|
||||
else if (data->newindex < cur_index) {
|
||||
custom_panel_draw_oli(C, column, data->oli);
|
||||
custom_panel_draw_oli(C, column, oli);
|
||||
}
|
||||
else if (data->newindex > cur_index) {
|
||||
custom_panel_draw_oli(C, column, oli);
|
||||
custom_panel_draw_oli(C, column, data->oli);
|
||||
}
|
||||
}
|
||||
// otherwise just draw normally
|
||||
else if (oli != data->oli)
|
||||
custom_panel_draw_oli(C, column, oli);
|
||||
}
|
||||
else
|
||||
custom_panel_draw_oli(C, column, oli);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
PanelType *uiCreateCustomPanelType(ScrArea *sa, ARegion *ar, const char *context, const char *name, const char *label)
|
||||
{
|
||||
PanelType *pt = MEM_callocN(sizeof(PanelType), "custom panel type");
|
||||
// Create new panel type and add to the current editor's toolbar
|
||||
BLI_strncpy(pt->idname, name, BKE_ST_MAXNAME);
|
||||
strcpy(pt->label, label);
|
||||
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
// pt_new->draw_header = custom_panel_draw_header;
|
||||
pt->draw = custom_panel_draw;
|
||||
// pt_new->poll = custom_panel_poll;
|
||||
pt->flag = PNL_CUSTOM_PANELTYPE;
|
||||
pt->space_type = sa->type->spaceid;
|
||||
pt->region_type = ar->regiontype;
|
||||
BLI_strncpy(pt->context, context, BKE_ST_MAXNAME);
|
||||
BLI_addtail(&ar->type->paneltypes, pt);
|
||||
return pt;
|
||||
}
|
||||
|
@@ -2829,3 +2829,36 @@ float *ui_block_hsv_get(uiBlock *block)
|
||||
{
|
||||
return block->_hsv;
|
||||
}
|
||||
|
||||
/* OperatorListItem utility functions for dragging in the Menubar */
|
||||
|
||||
/* Retrieve the OperatorListItem that is being dragged */
|
||||
OperatorListItem *uiRegionDraggedOperatorListItem(ARegion *ar)
|
||||
{
|
||||
OperatorListItem *oli = NULL;
|
||||
uiHandleRegionDragData *data;
|
||||
|
||||
if (ar->dragdata) {
|
||||
data = ar->dragdata;
|
||||
if (data->state == REGION_STATE_DRAG_BUTTON) {
|
||||
return data->oli;
|
||||
}
|
||||
}
|
||||
|
||||
return oli;
|
||||
}
|
||||
|
||||
/* Retrieve the new index for the dropped OperatorListItem */
|
||||
int uiRegionDraggedNewIndex(ARegion *ar)
|
||||
{
|
||||
uiHandleRegionDragData *data;
|
||||
|
||||
if (ar->dragdata) {
|
||||
data = ar->dragdata;
|
||||
if (data->state == REGION_STATE_DRAG_BUTTON) {
|
||||
return data->newindex;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -406,21 +406,21 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
// ListBase *lb; // UNUSED
|
||||
ID *id, *idfrom;
|
||||
int editable = RNA_property_editable(&template->ptr, template->prop);
|
||||
|
||||
|
||||
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
|
||||
id = idptr.data;
|
||||
idfrom = template->ptr.id.data;
|
||||
// lb = template->idlb;
|
||||
|
||||
|
||||
block = uiLayoutGetBlock(layout);
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
|
||||
if (idptr.type)
|
||||
type = idptr.type;
|
||||
|
||||
|
||||
if (flag & UI_ID_PREVIEWS) {
|
||||
template->preview = true;
|
||||
|
||||
|
||||
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
|
||||
TIP_(template_id_browse_tip(type)));
|
||||
if (type) {
|
||||
@@ -436,32 +436,32 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
else if (flag & UI_ID_BROWSE) {
|
||||
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
|
||||
TIP_(template_id_browse_tip(type)));
|
||||
|
||||
|
||||
uiButSetDrawFlag(but, UI_BUT_DRAW_ENUM_ARROWS);
|
||||
|
||||
|
||||
if (type) {
|
||||
but->icon = RNA_struct_ui_icon(type);
|
||||
/* default dragging of icon for id browse buttons */
|
||||
uiButSetDragID(but, id);
|
||||
uiButSetFlag(but, UI_HAS_ICON | UI_ICON_LEFT);
|
||||
}
|
||||
|
||||
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
|
||||
/* text button with name */
|
||||
if (id) {
|
||||
char name[UI_MAX_NAME_STR];
|
||||
const short user_alert = (id->us <= 0);
|
||||
|
||||
|
||||
//text_idbutton(id, name);
|
||||
name[0] = '\0';
|
||||
but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
|
||||
&idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
|
||||
if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
|
||||
|
||||
|
||||
if (id->lib) {
|
||||
if (id->flag & LIB_INDIRECT) {
|
||||
but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
|
||||
@@ -474,19 +474,19 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
if (!id_make_local(id, true /* test */) || (idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
|
||||
}
|
||||
|
||||
|
||||
if (id->us > 1) {
|
||||
char numstr[32];
|
||||
|
||||
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", id->us);
|
||||
|
||||
|
||||
but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0,
|
||||
TIP_("Display number of users of this data (click to make a single-user copy)"));
|
||||
|
||||
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
|
||||
if (/* test only */
|
||||
(id_copy(id, NULL, true) == false) ||
|
||||
@@ -498,7 +498,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
|
||||
|
||||
if (id->lib == NULL && !(ELEM5(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) {
|
||||
@@ -506,6 +506,195 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
}
|
||||
}
|
||||
|
||||
if (flag & UI_ID_ADD_NEW) {
|
||||
int w = id ? UI_UNIT_X : (flag & UI_ID_OPEN) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
|
||||
|
||||
/* i18n markup, does nothing! */
|
||||
BLF_I18N_MSGID_MULTI_CTXT("New", BLF_I18NCONTEXT_DEFAULT,
|
||||
BLF_I18NCONTEXT_ID_SCENE,
|
||||
BLF_I18NCONTEXT_ID_OBJECT,
|
||||
BLF_I18NCONTEXT_ID_MESH,
|
||||
BLF_I18NCONTEXT_ID_CURVE,
|
||||
BLF_I18NCONTEXT_ID_METABALL,
|
||||
BLF_I18NCONTEXT_ID_MATERIAL,
|
||||
BLF_I18NCONTEXT_ID_TEXTURE,
|
||||
BLF_I18NCONTEXT_ID_IMAGE,
|
||||
BLF_I18NCONTEXT_ID_LATTICE,
|
||||
BLF_I18NCONTEXT_ID_LAMP,
|
||||
BLF_I18NCONTEXT_ID_CAMERA,
|
||||
BLF_I18NCONTEXT_ID_WORLD,
|
||||
BLF_I18NCONTEXT_ID_SCREEN,
|
||||
BLF_I18NCONTEXT_ID_TEXT,
|
||||
);
|
||||
BLF_I18N_MSGID_MULTI_CTXT("New", BLF_I18NCONTEXT_ID_SPEAKER,
|
||||
BLF_I18NCONTEXT_ID_SOUND,
|
||||
BLF_I18NCONTEXT_ID_ARMATURE,
|
||||
BLF_I18NCONTEXT_ID_ACTION,
|
||||
BLF_I18NCONTEXT_ID_NODETREE,
|
||||
BLF_I18NCONTEXT_ID_BRUSH,
|
||||
BLF_I18NCONTEXT_ID_PARTICLESETTINGS,
|
||||
BLF_I18NCONTEXT_ID_GPENCIL,
|
||||
BLF_I18NCONTEXT_ID_FREESTYLELINESTYLE,
|
||||
);
|
||||
|
||||
if (newop) {
|
||||
but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
|
||||
(id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
|
||||
}
|
||||
else {
|
||||
but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
|
||||
}
|
||||
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
/* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
|
||||
* Only for images, sound and fonts */
|
||||
if (id && BKE_pack_check(id)) {
|
||||
but = uiDefIconButO(block, BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0,
|
||||
UI_UNIT_X, UI_UNIT_Y, TIP_("Packed File, click to unpack"));
|
||||
uiButGetOperatorPtrRNA(but);
|
||||
|
||||
RNA_string_set(but->opptr, "id_name", id->name + 2);
|
||||
RNA_int_set(but->opptr, "id_type", GS(id->name));
|
||||
|
||||
}
|
||||
else if (flag & UI_ID_OPEN) {
|
||||
int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
|
||||
|
||||
if (openop) {
|
||||
but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"),
|
||||
0, 0, w, UI_UNIT_Y, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
|
||||
}
|
||||
else {
|
||||
but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
|
||||
}
|
||||
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
/* delete button */
|
||||
/* don't use RNA_property_is_unlink here */
|
||||
if (id && (flag & UI_ID_DELETE) && (RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) {
|
||||
if (unlinkop) {
|
||||
but = uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
|
||||
/* so we can access the template from operators, font unlinking needs this */
|
||||
uiButSetNFunc(but, NULL, MEM_dupallocN(template), NULL);
|
||||
}
|
||||
else {
|
||||
but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
|
||||
TIP_("Unlink datablock "
|
||||
"(Shift + Click to set users to zero, data will then not be saved)"));
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
|
||||
|
||||
if (RNA_property_flag(template->prop) & PROP_NEVER_NULL)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
if (idcode == ID_TE)
|
||||
uiTemplateTextureShow(layout, C, &template->ptr, template->prop);
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
|
||||
static void template_ID_compact(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
|
||||
const char *newop, const char *UNUSED(openop), const char *unlinkop)
|
||||
{
|
||||
uiBut *but;
|
||||
uiBlock *block;
|
||||
uiLayout *row, *col;
|
||||
PointerRNA idptr;
|
||||
ID *id, *idfrom;
|
||||
int editable = RNA_property_editable(&template->ptr, template->prop);
|
||||
|
||||
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
|
||||
id = idptr.data;
|
||||
idfrom = template->ptr.id.data;
|
||||
|
||||
block = uiLayoutGetBlock(layout);
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
if (idptr.type)
|
||||
type = idptr.type;
|
||||
|
||||
template->preview = true;
|
||||
row = uiLayoutRow(layout, TRUE);
|
||||
|
||||
/* left part of the brush */
|
||||
col = uiLayoutColumn(row, TRUE);
|
||||
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 2, UI_UNIT_Y * 2,
|
||||
TIP_(template_id_browse_tip(type)));
|
||||
if (type) {
|
||||
but->icon = RNA_struct_ui_icon(type);
|
||||
if (id) but->icon = ui_id_icon_get(C, id, true);
|
||||
uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
|
||||
}
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
|
||||
uiItemS(row);
|
||||
|
||||
/* right part */
|
||||
col = uiLayoutColumn(row, TRUE);
|
||||
|
||||
/* first row: text button with name */
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
|
||||
if (id) {
|
||||
char name[UI_MAX_NAME_STR];
|
||||
const short user_alert = id->us <= 0;
|
||||
|
||||
//text_idbutton(id, name);
|
||||
name[0] = '\0';
|
||||
but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
|
||||
&idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
|
||||
if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
|
||||
|
||||
/* second row */
|
||||
row = uiLayoutRow(col, TRUE);
|
||||
|
||||
if (id->us > 1) {
|
||||
char numstr[32];
|
||||
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", id->us);
|
||||
|
||||
but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0,
|
||||
TIP_("Display number of users of this data (click to make a single-user copy)"));
|
||||
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
|
||||
if (/* test only */
|
||||
(id_copy(id, NULL, true) == false) ||
|
||||
(idfrom && idfrom->lib) ||
|
||||
(editable == FALSE) ||
|
||||
/* object in editmode - don't change data */
|
||||
(idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT)))
|
||||
{
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
|
||||
|
||||
if (id->lib == NULL && !(ELEM5(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) {
|
||||
uiDefButR(block, TOG, 0, "F", 0, 0, 6 * UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag & UI_ID_ADD_NEW) {
|
||||
int w = id ? UI_UNIT_X : (flag & UI_ID_OPEN) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
|
||||
|
||||
@@ -551,35 +740,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
/* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
|
||||
* Only for images, sound and fonts */
|
||||
if (id && BKE_pack_check(id)) {
|
||||
but = uiDefIconButO(block, BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0,
|
||||
UI_UNIT_X, UI_UNIT_Y, TIP_("Packed File, click to unpack"));
|
||||
uiButGetOperatorPtrRNA(but);
|
||||
|
||||
RNA_string_set(but->opptr, "id_name", id->name + 2);
|
||||
RNA_int_set(but->opptr, "id_type", GS(id->name));
|
||||
|
||||
}
|
||||
else if (flag & UI_ID_OPEN) {
|
||||
int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
|
||||
|
||||
if (openop) {
|
||||
but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"),
|
||||
0, 0, w, UI_UNIT_Y, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
|
||||
}
|
||||
else {
|
||||
but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
|
||||
}
|
||||
|
||||
if ((idfrom && idfrom->lib) || !editable)
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
/* delete button */
|
||||
/* don't use RNA_property_is_unlink here */
|
||||
@@ -610,7 +770,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
}
|
||||
|
||||
static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
|
||||
const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
|
||||
const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols, int compact)
|
||||
{
|
||||
TemplateID *template;
|
||||
PropertyRNA *prop;
|
||||
@@ -644,7 +804,13 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const
|
||||
*/
|
||||
if (template->idlb) {
|
||||
uiLayoutRow(layout, TRUE);
|
||||
template_ID(C, layout, template, type, idcode, flag, newop, openop, unlinkop);
|
||||
if (compact) {
|
||||
template_ID_compact(C, layout, template, type, idcode, flag, newop, openop, unlinkop);
|
||||
}
|
||||
else {
|
||||
template_ID(C, layout, template, type, idcode, flag, newop, openop, unlinkop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MEM_freeN(template);
|
||||
@@ -654,22 +820,30 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *pr
|
||||
const char *openop, const char *unlinkop)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
|
||||
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, 0, 0);
|
||||
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, 0, 0, FALSE);
|
||||
}
|
||||
|
||||
void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
|
||||
const char *openop, const char *unlinkop)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME, 0, 0);
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME, 0, 0, FALSE);
|
||||
}
|
||||
|
||||
void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
|
||||
const char *openop, const char *unlinkop, int rows, int cols)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
|
||||
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols);
|
||||
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols, FALSE);
|
||||
}
|
||||
|
||||
void uiTemplateIDPreviewCompact(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
|
||||
const char *openop, const char *unlinkop, int rows, int cols)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
|
||||
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/************************ ID Chooser Template ***************************/
|
||||
|
||||
/* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
@@ -54,6 +53,8 @@
|
||||
|
||||
#include "BLF_api.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_interface_icons.h"
|
||||
|
||||
@@ -1134,6 +1135,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
|
||||
{
|
||||
//int transopts; // UNUSED
|
||||
char *cpoin = NULL;
|
||||
unsigned char button_shortcut_color[4];
|
||||
|
||||
/* for underline drawing */
|
||||
float font_xofs, font_yofs;
|
||||
@@ -1213,7 +1215,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
|
||||
#endif
|
||||
|
||||
/* cut string in 2 parts - only for menu entries */
|
||||
if ((but->block->flag & UI_BLOCK_LOOP)) {
|
||||
if ((but->block->flag & UI_BLOCK_SHORTCUTS)) {
|
||||
if (ELEM3(but->type, NUM, TEX, NUMSLI) == 0) {
|
||||
cpoin = strchr(but->drawstr, '|');
|
||||
if (cpoin) *cpoin = 0;
|
||||
@@ -1256,10 +1258,19 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
|
||||
}
|
||||
}
|
||||
|
||||
/* part text right aligned */
|
||||
if (cpoin) {
|
||||
/* part text right aligned
|
||||
* only draw if there's enough space */
|
||||
if (but->flag2 & UI_BUT2_EXTRA_TEXT && cpoin &&
|
||||
(BLI_rcti_size_x(rect) - BLF_width(fstyle->uifont_id, but->str)) >= 5) {
|
||||
|
||||
fstyle->align = UI_STYLE_TEXT_RIGHT;
|
||||
rect->xmax -= ui_but_draw_menu_icon(but) ? UI_DPI_ICON_SIZE : 0.25f * U.widget_unit;
|
||||
/* If this is not a menu, and therefore a normal button, then change the alpha of the shortcut */
|
||||
if (!(but->block->flag & UI_BLOCK_LOOP)) {
|
||||
memcpy(button_shortcut_color, wcol->text, 4);
|
||||
button_shortcut_color[3] /= 2;
|
||||
glColor4ubv(button_shortcut_color);
|
||||
}
|
||||
uiStyleFontDraw(fstyle, rect, cpoin + 1);
|
||||
*cpoin = '|';
|
||||
}
|
||||
@@ -3202,6 +3213,21 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
|
||||
ThemeUI *tui = &btheme->tui;
|
||||
uiFontStyle *fstyle = &style->widget;
|
||||
uiWidgetType *wt = NULL;
|
||||
|
||||
/* in case we have an automatic icon, let's set it here */
|
||||
if (but->icon && but->icon == ICON_AUTOMATIC) {
|
||||
int icon = ICON_NONE;
|
||||
|
||||
if (but->optype) {
|
||||
if (but->optype->icon && but->opptr) {
|
||||
icon = but->optype->icon(C, but->opptr);
|
||||
}
|
||||
else if (but->optype->default_icon) {
|
||||
icon = but->optype->default_icon;
|
||||
}
|
||||
}
|
||||
but->icon = icon;
|
||||
}
|
||||
|
||||
/* handle menus separately */
|
||||
if (but->dt == UI_EMBOSSP) {
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
@@ -49,6 +50,7 @@
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_context.h"
|
||||
|
||||
|
||||
#include "BIF_gl.h"
|
||||
@@ -1358,6 +1360,29 @@ void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3]
|
||||
}
|
||||
}
|
||||
|
||||
int UI_data_mode_icon(const bContext *C)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
|
||||
if (obedit) {
|
||||
return ICON_EDITMODE_HLT;
|
||||
}
|
||||
else {
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
if (ob) {
|
||||
if (ob->mode & OB_MODE_POSE) return ICON_POSE_HLT;
|
||||
else if (ob->mode & OB_MODE_SCULPT) return ICON_SCULPTMODE_HLT;
|
||||
else if (ob->mode & OB_MODE_WEIGHT_PAINT) return ICON_WPAINT_HLT;
|
||||
else if (ob->mode & OB_MODE_VERTEX_PAINT) return ICON_VPAINT_HLT;
|
||||
else if (ob->mode & OB_MODE_TEXTURE_PAINT) return ICON_TPAINT_HLT;
|
||||
else if (ob->mode & OB_MODE_PARTICLE_EDIT) return ICON_PARTICLEMODE;
|
||||
}
|
||||
}
|
||||
|
||||
return ICON_OBJECT_DATAMODE;
|
||||
}
|
||||
|
||||
/* ************************************************************* */
|
||||
|
||||
/* patching UserDef struct and Themes */
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_alloca.h"
|
||||
@@ -698,7 +699,7 @@ static void free_undo(void *me_v)
|
||||
}
|
||||
|
||||
/* and this is all the undo system needs to know */
|
||||
void undo_push_mesh(bContext *C, const char *name)
|
||||
void undo_push_mesh(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
/* em->ob gets out of date and crashes on mesh undo,
|
||||
* this is an easy way to ensure its OK
|
||||
@@ -707,7 +708,7 @@ void undo_push_mesh(bContext *C, const char *name)
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
em->ob = obedit;
|
||||
|
||||
undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL);
|
||||
undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL, op);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -576,9 +576,9 @@ static void *get_data(bContext *C)
|
||||
}
|
||||
|
||||
/* this is undo system for MetaBalls */
|
||||
void undo_push_mball(bContext *C, const char *name)
|
||||
void undo_push_mball(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL);
|
||||
undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL, op);
|
||||
}
|
||||
|
||||
/* matrix is 4x4 */
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
@@ -886,8 +887,8 @@ static void *get_editlatt(bContext *C)
|
||||
}
|
||||
|
||||
/* and this is all the undo system needs to know */
|
||||
void undo_push_lattice(bContext *C, const char *name)
|
||||
void undo_push_lattice(bContext *C, const char *name, wmOperator *op)
|
||||
{
|
||||
undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt);
|
||||
undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt, op);
|
||||
}
|
||||
|
||||
|
@@ -71,6 +71,8 @@
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
#include "RE_engine.h"
|
||||
|
||||
@@ -719,6 +721,8 @@ void RENDER_OT_render(wmOperatorType *ot)
|
||||
ot->invoke = screen_render_invoke;
|
||||
ot->modal = screen_render_modal;
|
||||
ot->exec = screen_render_exec;
|
||||
|
||||
ot->default_icon = OPICON_RENDER;
|
||||
|
||||
/*ot->poll = ED_operator_screenactive;*/ /* this isn't needed, causes failer in background mode */
|
||||
|
||||
|
@@ -45,6 +45,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_types.h"
|
||||
@@ -950,7 +951,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
|
||||
/* clear state flags first */
|
||||
ar->flag &= ~RGN_FLAG_TOO_SMALL;
|
||||
/* user errors */
|
||||
if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT)
|
||||
if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT && alignment != RGN_ALIGN_FLOAT)
|
||||
alignment = RGN_ALIGN_NONE;
|
||||
|
||||
/* prefsize, for header we stick to exception (prevent dpi rounding error) */
|
||||
@@ -959,24 +960,19 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
|
||||
if (ar->regiontype == RGN_TYPE_HEADER) {
|
||||
prefsizey = ED_area_headersize();
|
||||
}
|
||||
else if (ar->regiontype == RGN_TYPE_MENU_BAR) {
|
||||
prefsizey = ED_area_headersize() * 1.5f;
|
||||
}
|
||||
else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) {
|
||||
prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2);
|
||||
}
|
||||
else {
|
||||
prefsizey = UI_DPI_FAC * (ar->sizey > 1 ? ar->sizey + 0.5f : ar->type->prefsizey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ar->flag & RGN_FLAG_HIDDEN) {
|
||||
/* hidden is user flag */
|
||||
}
|
||||
else if (alignment == RGN_ALIGN_FLOAT) {
|
||||
/* XXX floating area region, not handled yet here */
|
||||
}
|
||||
else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) {
|
||||
/* remainder is too small for any usage */
|
||||
ar->flag |= RGN_FLAG_TOO_SMALL;
|
||||
}
|
||||
else if (alignment == RGN_ALIGN_NONE) {
|
||||
/* typically last region */
|
||||
ar->winrct = *remainder;
|
||||
@@ -984,6 +980,18 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
|
||||
}
|
||||
else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) {
|
||||
|
||||
if (ar->regiontype == RGN_TYPE_TOOL_PROPS) {
|
||||
|
||||
Panel *pa = NULL;
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
// TODO: is there a better way to test for the identity of a panel type?
|
||||
if (pa->type && strcmp(pa->type->idname, "VIEW3D_PT_last_operator") == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
prefsizey = ((pa && !uiPanelClosed(pa)) ? pa->sizey : 0) + 26;
|
||||
}
|
||||
|
||||
if (rct_fits(remainder, 'v', prefsizey) < 0) {
|
||||
ar->flag |= RGN_FLAG_TOO_SMALL;
|
||||
}
|
||||
@@ -1003,6 +1011,18 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
|
||||
ar->winrct.ymax = ar->winrct.ymin + prefsizey - 1;
|
||||
remainder->ymin = ar->winrct.ymax + 1;
|
||||
}
|
||||
|
||||
/* Make sure we don't hide the tool props region when the toolbar is hidden.
|
||||
* This only works nicely with overlapping regions. */
|
||||
if (ar->overlap && ar->regiontype == RGN_TYPE_TOOL_PROPS && ar->prev && (ar->prev->flag & RGN_FLAG_HIDDEN || ar->prev->flag & RGN_FLAG_TOO_SMALL)) {
|
||||
Panel *pa = NULL;
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
if (pa->type && strcmp(pa->type->idname, "VIEW3D_PT_last_operator") == 0)
|
||||
break;
|
||||
}
|
||||
if (pa && pa->flag & PNL_PINNED)
|
||||
ar->winrct.xmax = prefsizex - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
|
||||
@@ -1177,7 +1197,7 @@ static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
|
||||
|
||||
/* used for area initialize below */
|
||||
static void region_subwindow(wmWindow *win, ARegion *ar)
|
||||
{
|
||||
{
|
||||
if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) {
|
||||
if (ar->swinid)
|
||||
wm_subwindow_close(win, ar->swinid);
|
||||
@@ -1241,6 +1261,30 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_custom_paneltypes(ARegion *ar)
|
||||
{
|
||||
ARegionType *art = ar->type;
|
||||
PanelType *pt, *pt_rem;
|
||||
Panel *pa;
|
||||
|
||||
/* PanelTypes should only be created at runtime or from Panels loaded from a blend */
|
||||
for (pt = art->paneltypes.first; pt;) {
|
||||
pt_rem = pt;
|
||||
pt = pt_rem->next;
|
||||
if (pt_rem->flag & PNL_CUSTOM_PANELTYPE) {
|
||||
BLI_remlink(&art->paneltypes, pt_rem);
|
||||
MEM_freeN(pt_rem);
|
||||
}
|
||||
}
|
||||
|
||||
/* The ar->type needs to be set to NULL in case we're not loading another file. */
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
if (pa->flag & PNL_CUSTOM_PANEL) {
|
||||
pa->type = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* called in screen_refresh, or screens_init, also area size changes */
|
||||
void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
|
||||
@@ -1256,8 +1300,11 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
|
||||
sa->type = BKE_spacetype_from_id(sa->spacetype);
|
||||
}
|
||||
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next)
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype);
|
||||
reset_custom_paneltypes(ar);
|
||||
}
|
||||
|
||||
|
||||
/* area sizes */
|
||||
area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win));
|
||||
@@ -1552,7 +1599,7 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
|
||||
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
||||
|
||||
return xco + U.widget_unit;
|
||||
}
|
||||
|
||||
@@ -1621,6 +1668,11 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
|
||||
|
||||
/* draw panel */
|
||||
if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
|
||||
/* If there's a panel for this paneltype, and that panel is hidden, then do not draw it. */
|
||||
panel = uiGetExistingPanel(ar, pt);
|
||||
if (panel && panel->hidden)
|
||||
continue;
|
||||
|
||||
block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
|
||||
panel = uiBeginPanel(sa, ar, block, pt, &open);
|
||||
|
||||
@@ -1803,6 +1855,132 @@ void ED_region_header_init(ARegion *ar)
|
||||
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
|
||||
}
|
||||
|
||||
void static menubar_fold_divider(bContext *UNUSED(C), void *arg1, void *UNUSED(arg2))
|
||||
{
|
||||
OperatorListItem *oli = arg1;
|
||||
oli->flag ^= OLI_DIVIDER_CLOSED;
|
||||
}
|
||||
|
||||
void static menubar_draw_oli(const bContext *C, uiLayout *row, OperatorListItem *oli, int *draw_buttons)
|
||||
{
|
||||
uiBlock *block = uiLayoutGetBlock(row);
|
||||
uiBut *but;
|
||||
|
||||
if (oli && row) {
|
||||
if (oli->flag & OLI_DIVIDER) {
|
||||
uiItemS(row);
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
but = uiDefIconBut(block, BUT, -1, (oli->flag & OLI_DIVIDER_CLOSED ? ICON_DISCLOSURE_TRI_RIGHT : ICON_DISCLOSURE_TRI_DOWN), 0, 0, UI_UNIT_X/3, UI_UNIT_Y, NULL, 0, 0, 0, 0, "When checked shows the buttons to the right");
|
||||
|
||||
/* N.B. func_arg1 is also used for the drag system */
|
||||
uiButSetFunc(but, menubar_fold_divider, oli, NULL);
|
||||
/* Hack to make the button system not catch drag events for non-operator buttons */
|
||||
uiButSetDragOp(but, (wmOperatorType*)oli);
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
uiItemS(row);
|
||||
|
||||
*draw_buttons = !(oli->flag & OLI_DIVIDER_CLOSED);
|
||||
}
|
||||
else {
|
||||
if (*draw_buttons) {
|
||||
wmOperatorType *ot = WM_operatortype_find(oli->optype_idname, TRUE);
|
||||
int icon = ICON_NONE;
|
||||
PointerRNA ptr;
|
||||
|
||||
WM_operator_properties_create_ptr(&ptr, ot);
|
||||
ptr.data = oli->properties;
|
||||
|
||||
icon = ot->icon ? ot->icon(C, &ptr) : ot->default_icon;
|
||||
|
||||
if (icon != ICON_NONE)
|
||||
uiItemFullO_ptr(row, ot, "", ICON_AUTOMATIC, IDP_CopyProperty(oli->properties), oli->opcontext, 0);
|
||||
else
|
||||
uiItemFullO_ptr(row, ot, ot->name, ICON_NONE, IDP_CopyProperty(oli->properties), oli->opcontext, UI_ITEM_O_SINGLE_UNIT);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ED_region_menubar(const bContext *C, ARegion *ar)
|
||||
{
|
||||
uiStyle *style = UI_GetStyleDraw();
|
||||
uiBlock *block;
|
||||
uiLayout *layout, *row;
|
||||
int maxco, xco, yco;
|
||||
int headery = ED_area_headersize() * 1.5f;
|
||||
OperatorListItem *oli_iter;
|
||||
OperatorListItem *oli_dragged = uiRegionDraggedOperatorListItem(ar);
|
||||
int newindex = uiRegionDraggedNewIndex(ar);
|
||||
int i = 0;
|
||||
int draw_buttons = 1;
|
||||
|
||||
/* clear */
|
||||
UI_ThemeClearColor(TH_BACK);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
/* set view2d view matrix for scrolling (without scrollers) */
|
||||
UI_view2d_view_ortho(&ar->v2d);
|
||||
|
||||
/* add all custom buttons to lower bar */
|
||||
xco = maxco = 0.4f * UI_UNIT_X;
|
||||
yco = headery - floor(0.2f * UI_UNIT_Y);
|
||||
|
||||
block = uiBeginBlock(C, ar, "menubar icons", UI_EMBOSS);
|
||||
layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, style);
|
||||
row = uiLayoutRow(layout, TRUE);
|
||||
uiLayoutSetScaleX(row, 1.5f);
|
||||
uiLayoutSetScaleY(row, 1.5f);
|
||||
|
||||
for (oli_iter = ar->operators.first; oli_iter; oli_iter = oli_iter->next) {
|
||||
if (oli_dragged) {
|
||||
// draw the new order of buttons
|
||||
if (i == newindex) {
|
||||
int cur_index = BLI_findindex(&ar->operators, oli_dragged);
|
||||
// draw it before or after the button that currently has the new index
|
||||
if (newindex == cur_index) {
|
||||
menubar_draw_oli(C, row, oli_iter, &draw_buttons);
|
||||
}
|
||||
else if (newindex < cur_index) {
|
||||
menubar_draw_oli(C, row, oli_dragged, &draw_buttons);
|
||||
if (strcmp(oli_iter->context, CTX_data_mode_string(C)) == 0)
|
||||
menubar_draw_oli(C, row, oli_iter, &draw_buttons);
|
||||
}
|
||||
else if (newindex > cur_index) {
|
||||
if (strcmp(oli_iter->context, CTX_data_mode_string(C)) == 0)
|
||||
menubar_draw_oli(C, row, oli_iter, &draw_buttons);
|
||||
menubar_draw_oli(C, row, oli_dragged, &draw_buttons);
|
||||
}
|
||||
}
|
||||
// otherwise just draw normally
|
||||
else if (oli_iter != oli_dragged)
|
||||
if (strcmp(oli_iter->context, CTX_data_mode_string(C)) == 0)
|
||||
menubar_draw_oli(C, row, oli_iter, &draw_buttons);
|
||||
}
|
||||
else
|
||||
if (strcmp(oli_iter->context, CTX_data_mode_string(C)) == 0)
|
||||
menubar_draw_oli(C, row, oli_iter, &draw_buttons);
|
||||
i++;
|
||||
}
|
||||
|
||||
xco = uiLayoutGetWidth(row);
|
||||
if (xco > maxco) maxco = xco;
|
||||
uiBlockLayoutResolve(block, &xco, &yco);
|
||||
uiEndBlock(C, block);
|
||||
uiDrawBlock(C, block);
|
||||
|
||||
/* always as last */
|
||||
UI_view2d_totRect_set(&ar->v2d, maxco + UI_UNIT_X + 80, headery);
|
||||
|
||||
/* restore view matrix? */
|
||||
UI_view2d_view_restore(C);
|
||||
}
|
||||
|
||||
void ED_region_menubar_init(ARegion *ar)
|
||||
{
|
||||
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
|
||||
}
|
||||
|
||||
/* UI_UNIT_Y is defined as U variable now, depending dpi */
|
||||
int ED_area_headersize(void)
|
||||
{
|
||||
|
@@ -394,12 +394,26 @@ void fdrawXORcirc(float xofs, float yofs, float rad)
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(xofs, yofs, 0.0);
|
||||
glutil_draw_lined_arc(0.0, M_PI * 2.0, rad, 20);
|
||||
glutil_draw_filled_arc(0.0, M_PI * 2.0, rad, 20);
|
||||
glPopMatrix();
|
||||
|
||||
set_inverted_drawing(0);
|
||||
}
|
||||
|
||||
void fdrawellipses(float xofs, float yofs, float rad)
|
||||
{
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glPointSize(rad);
|
||||
glPushMatrix();
|
||||
glTranslatef(xofs + rad * 4.f, yofs, 0.0);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2f(0.f, 0.f);
|
||||
glVertex2f(rad * 2.f, 0.f);
|
||||
glVertex2f(rad * 4.f, 0.f);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void glutil_draw_filled_arc(float start, float angle, float radius, int nsegments)
|
||||
{
|
||||
int i;
|
||||
|
@@ -2607,9 +2607,13 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot)
|
||||
static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
wmOperator *lastop = CTX_wm_manager(C)->operators.last;
|
||||
|
||||
if (lastop)
|
||||
WM_operator_repeat(C, lastop);
|
||||
wmOperator *newop;
|
||||
|
||||
if (lastop)
|
||||
{
|
||||
newop = WM_operator_copy(C, lastop, false);
|
||||
WM_operator_call(C, newop);
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
@@ -2654,14 +2658,17 @@ static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
|
||||
static int repeat_history_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmOperator *newop;
|
||||
|
||||
op = BLI_findlink(&wm->operators, RNA_int_get(op->ptr, "index"));
|
||||
if (op) {
|
||||
/* let's put it as last operator in list */
|
||||
BLI_remlink(&wm->operators, op);
|
||||
BLI_addtail(&wm->operators, op);
|
||||
|
||||
WM_operator_repeat(C, op);
|
||||
/* Let's copy the operator and add it to the end of the list.
|
||||
* Conceptually we haven't changed the order of the operators, but
|
||||
* we have applied the operator twice. The two applications should have
|
||||
* two different wmOperator instances. This also makes it consistent with
|
||||
* the link between the undobase lists. */
|
||||
newop = WM_operator_copy(C, op, false);
|
||||
WM_operator_call(C, newop);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -2688,7 +2695,7 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
|
||||
static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
|
||||
{
|
||||
wmOperator *lastop = WM_operator_last_redo(C);
|
||||
|
||||
|
||||
if (lastop)
|
||||
WM_operator_redo_popup(C, lastop);
|
||||
|
||||
@@ -3848,7 +3855,7 @@ static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void open_file_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void open_file_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
/* copy drag path to properties */
|
||||
RNA_string_set(drop->ptr, "filepath", drag->path);
|
||||
|
@@ -118,18 +118,15 @@ void CLIP_OT_properties(wmOperatorType *ot)
|
||||
|
||||
static ARegion *clip_has_tools_region(ScrArea *sa)
|
||||
{
|
||||
ARegion *ar, *artool = NULL, *arprops = NULL, *arhead;
|
||||
ARegion *ar, *artool = NULL, *arhead;
|
||||
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
if (ar->regiontype == RGN_TYPE_TOOLS)
|
||||
artool = ar;
|
||||
|
||||
if (ar->regiontype == RGN_TYPE_TOOL_PROPS)
|
||||
arprops = ar;
|
||||
}
|
||||
|
||||
/* tool region hide/unhide also hides props */
|
||||
if (arprops && artool)
|
||||
if (artool)
|
||||
return artool;
|
||||
|
||||
if (artool == NULL) {
|
||||
@@ -149,15 +146,6 @@ static ARegion *clip_has_tools_region(ScrArea *sa)
|
||||
artool->flag = RGN_FLAG_HIDDEN;
|
||||
}
|
||||
|
||||
if (arprops == NULL) {
|
||||
/* add extra subdivided region for tool properties */
|
||||
arprops = MEM_callocN(sizeof(ARegion), "tool props for clip");
|
||||
|
||||
BLI_insertlinkafter(&sa->regionbase, artool, arprops);
|
||||
arprops->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
arprops->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
|
||||
}
|
||||
|
||||
return artool;
|
||||
}
|
||||
|
||||
@@ -193,7 +181,7 @@ void CLIP_OT_tools(wmOperatorType *ot)
|
||||
|
||||
static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
|
||||
{
|
||||
uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0);
|
||||
uiLayoutOperatorButs(C, pa->layout, op, NULL, 'H', 0);
|
||||
}
|
||||
|
||||
static void clip_panel_operator_redo_header(const bContext *C, Panel *pa)
|
||||
|
@@ -267,13 +267,15 @@ static SpaceLink *clip_new(const bContext *C)
|
||||
ar->regiontype = RGN_TYPE_TOOLS;
|
||||
ar->alignment = RGN_ALIGN_LEFT;
|
||||
|
||||
#if 0
|
||||
/* tool properties */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool properties for clip");
|
||||
|
||||
BLI_addtail(&sc->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
|
||||
|
||||
#endif
|
||||
|
||||
/* properties view */
|
||||
ar = MEM_callocN(sizeof(ARegion), "properties for clip");
|
||||
|
||||
@@ -825,7 +827,7 @@ static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void clip_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void clip_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
PointerRNA itemptr;
|
||||
char dir[FILE_MAX], file[FILE_MAX];
|
||||
@@ -855,7 +857,9 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
|
||||
SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
|
||||
ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
|
||||
ARegion *ar_tools = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
#if 0
|
||||
ARegion *ar_tool_props = BKE_area_find_region_type(sa, RGN_TYPE_TOOL_PROPS);
|
||||
#endif
|
||||
ARegion *ar_preview = ED_clip_has_preview_region(C, sa);
|
||||
ARegion *ar_properties = ED_clip_has_properties_region(sa);
|
||||
ARegion *ar_channels = ED_clip_has_channels_region(sa);
|
||||
@@ -967,6 +971,7 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (tool_props_visible) {
|
||||
if (ar_tool_props && (ar_tool_props->flag & RGN_FLAG_HIDDEN)) {
|
||||
ar_tool_props->flag &= ~RGN_FLAG_HIDDEN;
|
||||
@@ -990,6 +995,7 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
|
||||
view_changed = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (preview_visible) {
|
||||
if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
|
||||
@@ -1529,6 +1535,7 @@ void ED_spacetype_clip(void)
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
#if 0
|
||||
/* tool properties */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype clip tool properties region");
|
||||
art->regionid = RGN_TYPE_TOOL_PROPS;
|
||||
@@ -1541,6 +1548,7 @@ void ED_spacetype_clip(void)
|
||||
ED_clip_tool_props_register(art);
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
#endif
|
||||
|
||||
/* regions: header */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");
|
||||
|
@@ -171,7 +171,7 @@ static int id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void id_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
char *text;
|
||||
ID *id = drag->poin;
|
||||
@@ -190,7 +190,7 @@ static int path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void path_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void path_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
char pathname[FILE_MAX + 2];
|
||||
BLI_snprintf(pathname, sizeof(pathname), "\"%s\"", drag->path);
|
||||
|
@@ -349,7 +349,7 @@ static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNU
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void image_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
/* copy drag path to properties */
|
||||
RNA_string_set(drop->ptr, "filepath", drag->path);
|
||||
|
@@ -666,7 +666,7 @@ static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
RNA_string_set(drop->ptr, "name", id->name + 2);
|
||||
}
|
||||
|
||||
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void node_id_path_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
|
@@ -129,7 +129,7 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void outliner_parent_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
@@ -171,7 +171,7 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void outliner_parent_clear_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
RNA_string_set(drop->ptr, "dragged_obj", id->name + 2);
|
||||
@@ -200,7 +200,7 @@ static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *ev
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void outliner_scene_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
@@ -225,7 +225,7 @@ static int outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void outliner_material_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
|
@@ -414,7 +414,7 @@ static int sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sequencer_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void sequencer_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
/* copy drag path to properties */
|
||||
if (RNA_struct_find_property(drop->ptr, "filepath"))
|
||||
|
@@ -468,7 +468,7 @@ static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void text_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
/* copy drag path to properties */
|
||||
RNA_string_set(drop->ptr, "filepath", drag->path);
|
||||
|
@@ -42,10 +42,13 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLF_translation.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
#include "ED_render.h"
|
||||
#include "ED_space_api.h"
|
||||
@@ -56,6 +59,7 @@
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -65,6 +69,7 @@
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
#include "UI_interface.h"
|
||||
|
||||
#include "view3d_intern.h" /* own include */
|
||||
|
||||
@@ -94,48 +99,37 @@ ARegion *view3d_has_buttons_region(ScrArea *sa)
|
||||
return arnew;
|
||||
}
|
||||
|
||||
ARegion *view3d_has_tools_region(ScrArea *sa)
|
||||
{
|
||||
ARegion *ar, *artool = NULL, *arprops = NULL, *arhead;
|
||||
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
if (ar->regiontype == RGN_TYPE_TOOLS)
|
||||
artool = ar;
|
||||
if (ar->regiontype == RGN_TYPE_TOOL_PROPS)
|
||||
arprops = ar;
|
||||
}
|
||||
|
||||
/* tool region hide/unhide also hides props */
|
||||
if (arprops && artool) return artool;
|
||||
|
||||
if (artool == NULL) {
|
||||
/* add subdiv level; after header */
|
||||
for (arhead = sa->regionbase.first; arhead; arhead = arhead->next)
|
||||
if (arhead->regiontype == RGN_TYPE_HEADER)
|
||||
break;
|
||||
|
||||
/* is error! */
|
||||
if (arhead == NULL) return NULL;
|
||||
|
||||
artool = MEM_callocN(sizeof(ARegion), "tools for view3d");
|
||||
|
||||
BLI_insertlinkafter(&sa->regionbase, arhead, artool);
|
||||
artool->regiontype = RGN_TYPE_TOOLS;
|
||||
artool->alignment = RGN_ALIGN_LEFT;
|
||||
artool->flag = RGN_FLAG_HIDDEN;
|
||||
}
|
||||
|
||||
if (arprops == NULL) {
|
||||
/* add extra subdivided region for tool properties */
|
||||
arprops = MEM_callocN(sizeof(ARegion), "tool props for view3d");
|
||||
|
||||
BLI_insertlinkafter(&sa->regionbase, artool, arprops);
|
||||
arprops->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
arprops->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
|
||||
}
|
||||
|
||||
return artool;
|
||||
}
|
||||
//ARegion *view3d_has_tools_region(ScrArea *sa)
|
||||
//{
|
||||
// ARegion *ar, *artool = NULL, *arhead;
|
||||
//
|
||||
// for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
// if (ar->regiontype == RGN_TYPE_TOOLS)
|
||||
// artool = ar;
|
||||
// }
|
||||
//
|
||||
// /* tool region hide/unhide also hides props */
|
||||
// if (artool) return artool;
|
||||
//
|
||||
// if (artool == NULL) {
|
||||
// /* add subdiv level; after header */
|
||||
// for (arhead = sa->regionbase.first; arhead; arhead = arhead->next)
|
||||
// if (arhead->regiontype == RGN_TYPE_HEADER)
|
||||
// break;
|
||||
//
|
||||
// /* is error! */
|
||||
// if (arhead == NULL) return NULL;
|
||||
//
|
||||
// artool = MEM_callocN(sizeof(ARegion), "tools for view3d");
|
||||
//
|
||||
// BLI_insertlinkafter(&sa->regionbase, arhead, artool);
|
||||
// artool->regiontype = RGN_TYPE_TOOLS;
|
||||
// artool->alignment = RGN_ALIGN_LEFT;
|
||||
// artool->flag = RGN_FLAG_HIDDEN;
|
||||
// }
|
||||
//
|
||||
// return artool;
|
||||
//}
|
||||
|
||||
/* ****************************************************** */
|
||||
|
||||
@@ -304,30 +298,35 @@ static SpaceLink *view3d_new(const bContext *C)
|
||||
ar->regiontype = RGN_TYPE_HEADER;
|
||||
ar->alignment = RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* operators menubar */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool operators menu bar for view3d");
|
||||
|
||||
BLI_addtail(&v3d->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_MENU_BAR;
|
||||
ar->alignment = RGN_ALIGN_TOP;
|
||||
|
||||
/* tool shelf */
|
||||
ar = MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
|
||||
|
||||
BLI_addtail(&v3d->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOLS;
|
||||
ar->alignment = RGN_ALIGN_LEFT;
|
||||
ar->flag = RGN_FLAG_HIDDEN;
|
||||
|
||||
/* tool properties */
|
||||
/* tool props, floating and therefore last! */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool properties for view3d");
|
||||
|
||||
BLI_addtail(&v3d->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
|
||||
ar->flag = RGN_FLAG_HIDDEN;
|
||||
ar->alignment = RGN_SPLIT_PREV | RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* buttons/list view */
|
||||
/* object properties sidebar right */
|
||||
ar = MEM_callocN(sizeof(ARegion), "buttons for view3d");
|
||||
|
||||
BLI_addtail(&v3d->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_UI;
|
||||
ar->alignment = RGN_ALIGN_RIGHT;
|
||||
ar->flag = RGN_FLAG_HIDDEN;
|
||||
|
||||
|
||||
/* main area */
|
||||
ar = MEM_callocN(sizeof(ARegion), "main area for view3d");
|
||||
|
||||
@@ -574,14 +573,14 @@ static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void view3d_ob_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
RNA_string_set(drop->ptr, "name", id->name + 2);
|
||||
}
|
||||
|
||||
static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void view3d_group_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
@@ -589,14 +588,14 @@ static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
RNA_string_set(drop->ptr, "name", id->name + 2);
|
||||
}
|
||||
|
||||
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void view3d_id_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
RNA_string_set(drop->ptr, "name", id->name + 2);
|
||||
}
|
||||
|
||||
static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
static void view3d_id_path_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
@@ -606,6 +605,87 @@ static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
RNA_string_set(drop->ptr, "filepath", drag->path);
|
||||
}
|
||||
|
||||
static void view3d_menubar_drop_copy(const bContext *UNUSED(C), const wmEvent *UNUSED(event), wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
wmOperatorType *ot = (wmOperatorType*)drag->poin;
|
||||
/* replace the drop ptr with the passed ptr so it can be copied by the drag operator */
|
||||
if (drag->ptr && drag->ptr->data) {
|
||||
WM_operator_properties_free(drop->ptr);
|
||||
drop->ptr->data = IDP_CopyProperty(drag->ptr->data);
|
||||
}
|
||||
/* temporarily set the properties for the drag operator in the copied ptr
|
||||
* this is effectively piggy backing on the properties for the OperatorListItem */
|
||||
RNA_string_set(drop->ptr, "COPY_idname", ot->idname);
|
||||
RNA_int_set(drop->ptr, "COPY_opcontext", drag->opcontext);
|
||||
}
|
||||
|
||||
static int view3d_menubar_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
|
||||
{
|
||||
wmOperatorType *ot = (wmOperatorType*)drag->poin;
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
if (drag->type == WM_DRAG_OP && ot && ar && ar->regiontype == RGN_TYPE_MENU_BAR) {
|
||||
/* check to see if an oli with the same properties is already present */
|
||||
if (drag->ptr)
|
||||
return !uiOperatorListItemPresent(&ar->operators, ot->idname, drag->ptr->data, CTX_data_mode_string(C));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Panel *over_panel(const bContext *C, const wmEvent *event)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C); // This handler is only registered in the TOOLBAR region
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
Panel *pa = NULL;
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
if (pa->flag & PNL_CUSTOM_PANEL && !uiPanelClosed(pa) && strcmp(context, pa->context) == 0) {
|
||||
// adjust ys for region
|
||||
int adjy = event->y - (ar->winrct.ymax - ar->sizey);
|
||||
int paminy = ar->sizey + pa->ofsy;
|
||||
int pamaxy = paminy + pa->sizey;
|
||||
int overp = adjy < pamaxy && adjy > paminy;
|
||||
|
||||
if (overp)
|
||||
return pa;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void view3d_toolbar_drop_copy(const bContext *C, const wmEvent *event, wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
wmOperatorType *ot = (wmOperatorType*)drag->poin;
|
||||
Panel *pa = over_panel(C, event);
|
||||
|
||||
/* replace the drop ptr with the passed ptr so it can be copied by the drag operator */
|
||||
if (drag->ptr && drag->ptr->data) {
|
||||
WM_operator_properties_free(drop->ptr);
|
||||
drop->ptr->data = IDP_CopyProperty(drag->ptr->data);
|
||||
}
|
||||
/* temporarily set the properties for the drag operator in the copied ptr
|
||||
* this is effectively piggy backing on the properties for the OperatorListItem */
|
||||
RNA_string_set(drop->ptr, "COPY_idname", ot->idname);
|
||||
RNA_int_set(drop->ptr, "COPY_opcontext", drag->opcontext);
|
||||
RNA_string_set(drop->ptr, "COPY_paneltypeid", pa->type ? pa->type->idname : "");
|
||||
}
|
||||
|
||||
static int view3d_toolbar_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
{
|
||||
wmOperatorType *ot = (wmOperatorType*)drag->poin;
|
||||
Panel *pa = NULL;
|
||||
OperatorListItem *present_p = NULL;
|
||||
|
||||
if (drag->type == WM_DRAG_OP && ot) {
|
||||
pa = over_panel(C, event);
|
||||
if (pa != NULL && drag->ptr && drag->ptr->data)
|
||||
/* check to see if an oli with the same properties is already present */
|
||||
present_p = uiOperatorListItemPresent(&pa->operators, ot->idname, drag->ptr->data, CTX_data_mode_string(C));
|
||||
}
|
||||
|
||||
return pa != NULL && present_p == NULL;
|
||||
}
|
||||
|
||||
/* region dropbox definition */
|
||||
static void view3d_dropboxes(void)
|
||||
@@ -618,6 +698,16 @@ static void view3d_dropboxes(void)
|
||||
WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
|
||||
WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
|
||||
WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
|
||||
|
||||
lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_MENU_BAR);
|
||||
|
||||
WM_dropbox_add(lb, "WM_OT_menubar_add_dragged_operator", view3d_menubar_drop_poll, view3d_menubar_drop_copy);
|
||||
|
||||
lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_TOOLS);
|
||||
|
||||
WM_dropbox_add(lb, "WM_OT_add_to_custom_panel", view3d_toolbar_drop_poll, view3d_toolbar_drop_copy);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -713,7 +803,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
|
||||
{
|
||||
Scene *scene = sc->scene;
|
||||
View3D *v3d = sa->spacedata.first;
|
||||
|
||||
|
||||
/* context changes */
|
||||
switch (wmn->category) {
|
||||
case NC_ANIMATION:
|
||||
@@ -1053,12 +1143,16 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
ListBase *lb;
|
||||
wmKeyMap *keymap;
|
||||
|
||||
ED_region_panels_init(wm, ar);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_TOOLS);
|
||||
WM_event_add_dropbox_handler(&ar->handlers, lb);
|
||||
}
|
||||
|
||||
static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
|
||||
@@ -1066,6 +1160,79 @@ static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
|
||||
ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1);
|
||||
}
|
||||
|
||||
static void view3d_menubar_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
ListBase *lb;
|
||||
wmKeyMap *keymap;
|
||||
|
||||
ED_region_menubar_init(ar);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_MENU_BAR);
|
||||
WM_event_add_dropbox_handler(&ar->handlers, lb);
|
||||
}
|
||||
|
||||
static void view3d_menubar_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
ED_region_menubar(C, ar);
|
||||
}
|
||||
|
||||
static void view3d_menubar_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
|
||||
{
|
||||
/* context changes */
|
||||
switch (wmn->category) {
|
||||
case NC_SCENE:
|
||||
if (wmn->data == ND_MODE)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int view3d_props_sum_panel_heights(ARegion *ar)
|
||||
{
|
||||
Panel *pa;
|
||||
int sum = 0;
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
sum += pa->sizey;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void view3d_props_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
/* If in laying out and redrawing the panels this area contains we find that the
|
||||
* panels have changed in height we'll need to redraw the area so that its height
|
||||
* is automatically adapted. If */
|
||||
int total_panel_height = view3d_props_sum_panel_heights(ar);
|
||||
|
||||
/* firstly, draw a clear divider */
|
||||
ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColor4ub(0, 0, 0, 200);
|
||||
fdrawline(0, BLI_rcti_size_y(&ar->winrct)+1, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)+1);
|
||||
glColor4ub(255, 255, 255, 30);
|
||||
fdrawline(0, BLI_rcti_size_y(&ar->winrct), BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
|
||||
|
||||
if (total_panel_height != view3d_props_sum_panel_heights(ar)) {
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
CTX_wm_screen(C)->do_refresh = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_props_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
wmKeyMap *keymap;
|
||||
|
||||
ED_region_panels_init(wm, ar);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
}
|
||||
|
||||
static void view3d_props_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
|
||||
{
|
||||
/* context changes */
|
||||
@@ -1077,6 +1244,8 @@ static void view3d_props_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
|
||||
case NC_SCENE:
|
||||
if (wmn->data == ND_MODE)
|
||||
ED_region_tag_redraw(ar);
|
||||
if (wmn->action == NA_EDITED)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_SPACE:
|
||||
if (wmn->data == ND_SPACE_VIEW3D)
|
||||
@@ -1318,24 +1487,31 @@ void ED_spacetype_view3d(void)
|
||||
art->draw = view3d_tools_area_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
#if 0
|
||||
/* unfinished still */
|
||||
view3d_toolshelf_register(art);
|
||||
#endif
|
||||
|
||||
view3d_toolbar_header_register(art);
|
||||
view3d_grease_register(art);
|
||||
|
||||
/* regions: tool properties */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tool properties region");
|
||||
art->regionid = RGN_TYPE_TOOL_PROPS;
|
||||
art->prefsizex = 0;
|
||||
art->prefsizey = 120;
|
||||
art->prefsizex = 160; /* XXX */
|
||||
art->prefsizey = 50; /* XXX */
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
|
||||
art->listener = view3d_props_area_listener;
|
||||
art->init = view3d_tools_area_init;
|
||||
art->draw = view3d_tools_area_draw;
|
||||
art->init = view3d_props_area_init;
|
||||
art->draw = view3d_props_area_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
view3d_tool_props_register(art);
|
||||
|
||||
/* regions: operators menu bar */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d operators menu bar region");
|
||||
art->regionid = RGN_TYPE_MENU_BAR;
|
||||
art->prefsizey = ED_area_headersize();
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
|
||||
art->listener = view3d_menubar_area_listener;
|
||||
art->init = view3d_menubar_area_init;
|
||||
art->draw = view3d_menubar_area_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: header */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
|
||||
|
@@ -1154,13 +1154,13 @@ void view3d_buttons_register(ARegionType *art)
|
||||
pt->poll = view3d_panel_transform_poll;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
|
||||
strcpy(pt->idname, "VIEW3D_PT_gpencil");
|
||||
strcpy(pt->label, N_("Grease Pencil")); /* XXX C panels are not available through RNA (bpy.types)! */
|
||||
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw_header = gpencil_panel_standard_header;
|
||||
pt->draw = gpencil_panel_standard;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
// pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
|
||||
// strcpy(pt->idname, "VIEW3D_PT_gpencil");
|
||||
// strcpy(pt->label, N_("Grease Pencil")); /* XXX C panels are not available through RNA (bpy.types)! */
|
||||
// strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
// pt->draw_header = gpencil_panel_standard_header;
|
||||
// pt->draw = gpencil_panel_standard;
|
||||
// BLI_addtail(&art->paneltypes, pt);
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
|
||||
strcpy(pt->idname, "VIEW3D_PT_vgroup");
|
||||
|
@@ -207,6 +207,8 @@ void view3d_buttons_register(struct ARegionType *art);
|
||||
void VIEW3D_OT_toolshelf(struct wmOperatorType *ot);
|
||||
void view3d_toolshelf_register(struct ARegionType *art);
|
||||
void view3d_tool_props_register(struct ARegionType *art);
|
||||
void view3d_grease_register(struct ARegionType *art);
|
||||
void view3d_toolbar_header_register(struct ARegionType *art);
|
||||
|
||||
/* view3d_snap.c */
|
||||
bool ED_view3d_minmax_verts(struct Object *obedit, float min[3], float max[3]);
|
||||
|
@@ -56,9 +56,11 @@
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_util.h"
|
||||
#include "ED_gpencil.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
@@ -73,30 +75,30 @@ static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOper
|
||||
uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0);
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)
|
||||
{
|
||||
wmOperator *op = WM_operator_last_redo(C);
|
||||
|
||||
if (op)
|
||||
BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
|
||||
else
|
||||
BLI_strncpy(pa->drawname, IFACE_("Operator"), sizeof(pa->drawname));
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op)
|
||||
{
|
||||
if (op->type->flag & OPTYPE_MACRO) {
|
||||
for (op = op->macro.first; op; op = op->next) {
|
||||
uiItemL(pa->layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
|
||||
// uiItemL(pa->layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
|
||||
view3d_panel_operator_redo_operator(C, pa, op);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uiItemL(pa->layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
|
||||
view3d_panel_operator_redo_buts(C, pa, op);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO de-duplicate redo panel functions - campbell */
|
||||
static void view3d_panel_operator_redo_header(const bContext *UNUSED(C), Panel *pa)
|
||||
{
|
||||
uiLayout *layout = pa->layout;
|
||||
|
||||
uiBlockSetEmboss(uiLayoutGetBlock(layout), UI_EMBOSSN);
|
||||
uiDefIconButBitS(uiLayoutGetBlock(layout), TOG, PNL_PINNED, 0, pa->flag & PNL_PINNED ? ICON_PINNED : ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &pa->flag, 0.f, 0.f, 0.f, 0.f, "When this panel is pinned it is not hidden when the toolbar is hidden");
|
||||
uiBlockSetEmboss(uiLayoutGetBlock(layout), UI_EMBOSS);
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
{
|
||||
wmOperator *op = WM_operator_last_redo(C);
|
||||
@@ -129,6 +131,150 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
CTX_wm_region_set((bContext *)C, ar);
|
||||
}
|
||||
|
||||
static uiBlock *active_panel_menu_popup_create_block(bContext *C, ARegion *cur_ar, void *arg_ar);
|
||||
|
||||
static void active_panel_menu_popup_cb(bContext *C, void *UNUSED(arg_block), int UNUSED(event))
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
// uiBlock *block = (uiBlock*)arg_block;
|
||||
|
||||
/* This results in a crash that has something to do with recursion
|
||||
in the event handling system. I'm not quite sure it is possible
|
||||
to refresh popup blocks.
|
||||
*/
|
||||
// uiPupBlockClose(C, block);
|
||||
// uiPupBlock(C, active_panel_menu_popup_create_block, ar);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static int sort_panels_by_sortorder(void *o1, void *o2)
|
||||
{
|
||||
Panel *pa1 = (Panel*)o1;
|
||||
Panel *pa2 = (Panel*)o2;
|
||||
|
||||
return pa1->sortorder > pa2->sortorder;
|
||||
}
|
||||
|
||||
static uiBlock *active_panel_menu_popup_create_block(bContext *C, ARegion *cur_ar, void *arg_ar)
|
||||
{
|
||||
uiBlock *block;
|
||||
Panel *pa;
|
||||
ARegion *ar = (ARegion*)arg_ar;
|
||||
uiLayout *layout, *col;
|
||||
uiStyle *style = UI_GetStyle();
|
||||
uiBut *but;
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
int width = 10 * UI_UNIT_X;
|
||||
int height = 12 * UI_UNIT_Y;
|
||||
// bool all_showing = true;
|
||||
|
||||
block = uiBeginBlock(C, cur_ar, __func__, UI_EMBOSS);
|
||||
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
uiBlockSetHandleFunc(block, active_panel_menu_popup_cb, block);
|
||||
|
||||
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, style->panelspace, 0, width - 2 * style->panelspace, height, style);
|
||||
col = uiLayoutColumn(layout, TRUE);
|
||||
|
||||
CTX_wm_region_set(C, ar);
|
||||
|
||||
BLI_sortlist(&ar->panels, sort_panels_by_sortorder);
|
||||
|
||||
/*
|
||||
The following code is meant to show 2 buttons:
|
||||
1. - Show all => a button that is shown if 1 or more panels are hidden and unhides all panels when pressed.
|
||||
- Hide all => a button that is shown if all panels are visible and hides all panels when pressed
|
||||
2. Invert => a button that hides the visible panels and unhides the hidden ones when pressed.
|
||||
|
||||
However, it is not so easy to redraw a popup block and this
|
||||
severly limits the usefulness of these buttons. The rest of the
|
||||
buttons don't update accordingly and the panel would have to be
|
||||
reopened again by the user. Without these extra buttons the panel
|
||||
is conceptually clear, and I doubt that the extra buttons would
|
||||
be very helpful.
|
||||
*/
|
||||
|
||||
// for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
// /* check to see if this panel should be considered */
|
||||
// if (pa->type && !(pa->type->flag & PNL_NO_HEADER) &&
|
||||
// (pa->type->context[0] ? strcmp(context, pa->type->context) == 0 : true) &&
|
||||
// (pa->type->poll ? pa->type->poll(C, pa->type) : true)) {
|
||||
// /* if any panel is not hidden, break */
|
||||
// if (pa->hidden) {
|
||||
// all_showing = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// but = uiDefBut(block, BUT, 1, !all_showing ? "Show all" : "Hide all", 0, 0, width, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Show all panels");
|
||||
// // TODO: set callback that shows or hides all panels.
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
/* Create a button with a callback for each panel that belongs fits the mode */
|
||||
if (!pa->type || pa->type->flag & PNL_NO_HEADER
|
||||
|| (context && pa->type->context[0] && strcmp(context, pa->type->context) != 0)
|
||||
|| (pa->type->poll && !pa->type->poll(C, pa->type)))
|
||||
continue;
|
||||
|
||||
uiLayoutRow(col, TRUE);
|
||||
but = uiDefButBitI(block, OPTIONN, 1, 0, pa->drawname, 0, 0, width, UI_UNIT_Y, (int*)&pa->hidden, 0, 0, 0, 0, "Uncheck to hide panel");
|
||||
}
|
||||
CTX_wm_region_set(C, cur_ar);
|
||||
|
||||
uiBlockLayoutResolve(block, NULL, NULL);
|
||||
uiPopupBoundsBlock(block, 4, 0, 0);
|
||||
uiEndBlock(C, block);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static void active_panel_menu_popup(bContext *C, void *arg_ar, void *UNUSED(arg2))
|
||||
{
|
||||
uiPupBlock(C, active_panel_menu_popup_create_block, arg_ar);
|
||||
}
|
||||
|
||||
|
||||
static void collapse_all_panels(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
uiCollapseAllPanels(sa, ar, CTX_data_mode_string(C));
|
||||
}
|
||||
|
||||
static void view3d_toolbar_header_draw(const bContext *C, Panel *pa)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
uiLayout *layout = pa->layout;
|
||||
uiLayout *row = uiLayoutRow(layout, TRUE);
|
||||
const char *name = "";
|
||||
int modeicon = UI_data_mode_icon(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
int modeselect = ob ? ob->mode : OB_MODE_OBJECT;
|
||||
EnumPropertyItem *item = object_mode_items;
|
||||
uiBut *but;
|
||||
|
||||
while (item->identifier) {
|
||||
if (item->value == modeselect && item->identifier[0]) {
|
||||
name = IFACE_(item->name);
|
||||
break;
|
||||
}
|
||||
item++;
|
||||
}
|
||||
|
||||
uiItemL(row, name, modeicon);
|
||||
|
||||
but = uiDefIconBut(uiLayoutGetBlock(row), BUT, 0, ICON_CHECKBOX_HLT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Show and hide panels");
|
||||
uiButSetFunc(but, active_panel_menu_popup, ar, NULL);
|
||||
|
||||
but = uiDefIconBut(uiLayoutGetBlock(row), BUT, 0, ICON_TRIA_RIGHT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Collapse all panels in this toolbar");
|
||||
uiButSetFunc(but, collapse_all_panels, pa, NULL);
|
||||
|
||||
uiDefIconButO(uiLayoutGetBlock(row), BUT, "WM_OT_create_custom_panel", WM_OP_INVOKE_DEFAULT, ICON_PLUS, 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add a custom panel to this toolbar");
|
||||
|
||||
}
|
||||
|
||||
/* ******************* */
|
||||
|
||||
typedef struct CustomTool {
|
||||
@@ -249,19 +395,60 @@ void view3d_tool_props_register(ARegionType *art)
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel last operator");
|
||||
strcpy(pt->idname, "VIEW3D_PT_last_operator");
|
||||
strcpy(pt->label, N_("Operator"));
|
||||
strcpy(pt->label, N_("Last Operator"));
|
||||
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw_header = view3d_panel_operator_redo_header;
|
||||
pt->draw = view3d_panel_operator_redo;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
|
||||
static int view3d_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt))
|
||||
{
|
||||
return ELEM9(CTX_data_mode_enum(C),
|
||||
CTX_MODE_EDIT_MESH,
|
||||
CTX_MODE_EDIT_CURVE,
|
||||
CTX_MODE_EDIT_SURFACE,
|
||||
CTX_MODE_EDIT_TEXT,
|
||||
CTX_MODE_EDIT_ARMATURE,
|
||||
CTX_MODE_EDIT_METABALL,
|
||||
CTX_MODE_EDIT_LATTICE,
|
||||
CTX_MODE_POSE,
|
||||
CTX_MODE_OBJECT);
|
||||
}
|
||||
|
||||
void view3d_grease_register(ARegionType *art)
|
||||
{
|
||||
PanelType *pt;
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
|
||||
strcpy(pt->idname, "VIEW3D_PT_gpencil");
|
||||
strcpy(pt->label, N_("Grease Pencil")); /* XXX C panels are not available through RNA (bpy.types)! */
|
||||
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw_header = gpencil_panel_standard_header;
|
||||
pt->draw = gpencil_panel_standard;
|
||||
pt->poll = view3d_grease_pencil_panel_poll;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
|
||||
void view3d_toolbar_header_register(ARegionType *art)
|
||||
{
|
||||
PanelType *pt;
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d toolbar header");
|
||||
strcpy(pt->idname, "VIEW3D_PT_toolbar_header");
|
||||
strcpy(pt->label, N_("No Label!"));
|
||||
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->flag = PNL_NO_HEADER;
|
||||
pt->draw = view3d_toolbar_header_draw;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
|
||||
/* ********** operator to open/close toolshelf region */
|
||||
|
||||
static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = view3d_has_tools_region(sa);
|
||||
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS); //view3d_has_tools_region(sa);
|
||||
|
||||
if (ar)
|
||||
ED_region_toggle_hidden(C, ar);
|
||||
|
@@ -557,6 +557,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
|
||||
ot->description = "Translate (move) selected items";
|
||||
ot->idname = OP_TRANSLATION;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
ot->default_icon = ICON_MAN_TRANS;
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = transform_invoke;
|
||||
@@ -577,6 +578,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
|
||||
ot->description = "Scale (resize) selected items";
|
||||
ot->idname = OP_RESIZE;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
ot->default_icon = ICON_MAN_SCALE;
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = transform_invoke;
|
||||
@@ -653,6 +655,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
|
||||
ot->description = "Rotate selected items";
|
||||
ot->idname = OP_ROTATION;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
ot->default_icon = ICON_MAN_ROT;
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = transform_invoke;
|
||||
|
@@ -84,6 +84,7 @@ set(SRC
|
||||
../include/ED_uvedit.h
|
||||
../include/ED_view3d.h
|
||||
../include/UI_icons.h
|
||||
../include/UI_opicons.h
|
||||
../include/UI_interface.h
|
||||
../include/UI_interface_icons.h
|
||||
../include/UI_resources.h
|
||||
|
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dynstr.h"
|
||||
@@ -46,10 +47,14 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "ED_util.h"
|
||||
#include "ED_mesh.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
@@ -80,8 +85,11 @@
|
||||
static void error(const char *UNUSED(arg)) {}
|
||||
/* ****** XXX ***** */
|
||||
|
||||
/* op should be in the third position so it
|
||||
correctly maps to UndoElem in wm.c */
|
||||
typedef struct UndoElem {
|
||||
struct UndoElem *next, *prev;
|
||||
wmOperator *op;
|
||||
ID id; // copy of editmode object ID
|
||||
Object *ob; // pointer to edited object
|
||||
int type; // type of edited object
|
||||
@@ -101,20 +109,25 @@ static UndoElem *curundo = NULL;
|
||||
|
||||
/* ********************* xtern api calls ************* */
|
||||
|
||||
static void undo_restore(UndoElem *undo, void *editdata, void *obdata)
|
||||
static void undo_restore(bContext *C, UndoElem *undo, void *editdata, void *obdata)
|
||||
{
|
||||
if (undo) {
|
||||
ListBase included_ops;
|
||||
undo->to_editmode(undo->undodata, editdata, obdata);
|
||||
included_ops.first = undobase.first;
|
||||
included_ops.last = undo;
|
||||
WM_operator_build_stack(C, &included_ops, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* name can be a dynamic string */
|
||||
void undo_editmode_push(bContext *C, const char *name,
|
||||
void * (*getdata)(bContext * C),
|
||||
void (*freedata)(void *),
|
||||
void (*to_editmode)(void *, void *, void *),
|
||||
void *(*from_editmode)(void *, void *),
|
||||
int (*validate_undo)(void *, void *))
|
||||
void * (*getdata)(bContext * C),
|
||||
void (*freedata)(void *),
|
||||
void (*to_editmode)(void *, void *, void *),
|
||||
void *(*from_editmode)(void *, void *),
|
||||
int (*validate_undo)(void *, void *),
|
||||
wmOperator *op)
|
||||
{
|
||||
UndoElem *uel;
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -128,6 +141,9 @@ void undo_editmode_push(bContext *C, const char *name,
|
||||
/* remove all undos after (also when curundo == NULL) */
|
||||
while (undobase.last != curundo) {
|
||||
uel = undobase.last;
|
||||
// Don't free the op if it is repeated!
|
||||
if(uel->op && uel->op != op)
|
||||
WM_operator_free(uel->op);
|
||||
uel->freedata(uel->undodata);
|
||||
BLI_freelinkN(&undobase, uel);
|
||||
}
|
||||
@@ -142,6 +158,9 @@ void undo_editmode_push(bContext *C, const char *name,
|
||||
uel->to_editmode = to_editmode;
|
||||
uel->from_editmode = from_editmode;
|
||||
uel->validate_undo = validate_undo;
|
||||
if (op && op->type && op->type->flag & OPTYPE_REGISTER && op->type->flag & OPTYPE_UNDO) {
|
||||
uel->op = op;
|
||||
}
|
||||
|
||||
/* limit amount to the maximum amount*/
|
||||
nr = 0;
|
||||
@@ -154,6 +173,8 @@ void undo_editmode_push(bContext *C, const char *name,
|
||||
if (uel) {
|
||||
while (undobase.first != uel) {
|
||||
UndoElem *first = undobase.first;
|
||||
if(first->op)
|
||||
WM_operator_free(first->op);
|
||||
first->freedata(first->undodata);
|
||||
BLI_freelinkN(&undobase, first);
|
||||
}
|
||||
@@ -186,11 +207,15 @@ void undo_editmode_push(bContext *C, const char *name,
|
||||
|
||||
while (undobase.first != uel) {
|
||||
UndoElem *first = undobase.first;
|
||||
if(first->op)
|
||||
WM_operator_free(first->op);
|
||||
first->freedata(first->undodata);
|
||||
BLI_freelinkN(&undobase, first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WM_operator_build_stack(C, &undobase, true);
|
||||
}
|
||||
|
||||
/* helper to remove clean other objects from undo stack */
|
||||
@@ -222,7 +247,8 @@ static void undo_clean_stack(bContext *C)
|
||||
else {
|
||||
if (uel == curundo)
|
||||
curundo = NULL;
|
||||
|
||||
if(uel->op)
|
||||
WM_operator_free(uel->op);
|
||||
uel->freedata(uel->undodata);
|
||||
BLI_freelinkN(&undobase, uel);
|
||||
}
|
||||
@@ -242,7 +268,7 @@ void undo_editmode_step(bContext *C, int step)
|
||||
undo_clean_stack(C);
|
||||
|
||||
if (step == 0) {
|
||||
undo_restore(curundo, curundo->getdata(C), obedit->data);
|
||||
undo_restore(C, curundo, curundo->getdata(C), obedit->data);
|
||||
}
|
||||
else if (step == 1) {
|
||||
|
||||
@@ -252,7 +278,7 @@ void undo_editmode_step(bContext *C, int step)
|
||||
else {
|
||||
if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name);
|
||||
curundo = curundo->prev;
|
||||
undo_restore(curundo, curundo->getdata(C), obedit->data);
|
||||
undo_restore(C, curundo, curundo->getdata(C), obedit->data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -262,7 +288,7 @@ void undo_editmode_step(bContext *C, int step)
|
||||
error("No more steps to redo");
|
||||
}
|
||||
else {
|
||||
undo_restore(curundo->next, curundo->getdata(C), obedit->data);
|
||||
undo_restore(C, curundo->next, curundo->getdata(C), obedit->data);
|
||||
curundo = curundo->next;
|
||||
if (G.debug & G_DEBUG) printf("redo %s\n", curundo->name);
|
||||
}
|
||||
@@ -284,6 +310,8 @@ void undo_editmode_clear(void)
|
||||
|
||||
uel = undobase.first;
|
||||
while (uel) {
|
||||
if(uel->op)
|
||||
WM_operator_free(uel->op);
|
||||
uel->freedata(uel->undodata);
|
||||
uel = uel->next;
|
||||
}
|
||||
@@ -304,12 +332,12 @@ void undo_editmode_number(bContext *C, int nr)
|
||||
undo_editmode_step(C, 0);
|
||||
}
|
||||
|
||||
void undo_editmode_name(bContext *C, const char *undoname)
|
||||
void undo_editmode_op(bContext *C, const wmOperator* op)
|
||||
{
|
||||
UndoElem *uel;
|
||||
|
||||
for (uel = undobase.last; uel; uel = uel->prev) {
|
||||
if (strcmp(undoname, uel->name) == 0)
|
||||
if (uel->op == op)
|
||||
break;
|
||||
}
|
||||
if (uel && uel->prev) {
|
||||
|
@@ -78,7 +78,7 @@
|
||||
|
||||
/* ***************** generic undo system ********************* */
|
||||
|
||||
void ED_undo_push(bContext *C, const char *str)
|
||||
static void ed_undo_push_internal(bContext *C, const char *str, wmOperator *op)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -91,25 +91,26 @@ void ED_undo_push(bContext *C, const char *str)
|
||||
if (U.undosteps == 0) return;
|
||||
|
||||
if (obedit->type == OB_MESH)
|
||||
undo_push_mesh(C, str);
|
||||
undo_push_mesh(C, str, op);
|
||||
else if (ELEM(obedit->type, OB_CURVE, OB_SURF))
|
||||
undo_push_curve(C, str);
|
||||
undo_push_curve(C, str, op);
|
||||
else if (obedit->type == OB_FONT)
|
||||
undo_push_font(C, str);
|
||||
undo_push_font(C, str, op);
|
||||
else if (obedit->type == OB_MBALL)
|
||||
undo_push_mball(C, str);
|
||||
undo_push_mball(C, str, op);
|
||||
else if (obedit->type == OB_LATTICE)
|
||||
undo_push_lattice(C, str);
|
||||
undo_push_lattice(C, str, op);
|
||||
else if (obedit->type == OB_ARMATURE)
|
||||
undo_push_armature(C, str);
|
||||
undo_push_armature(C, str, op);
|
||||
}
|
||||
// not sure what to do with the partice edit undo stack ~ ack-err
|
||||
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
|
||||
if (U.undosteps == 0) return;
|
||||
|
||||
PE_undo_push(CTX_data_scene(C), str);
|
||||
}
|
||||
else {
|
||||
BKE_write_undo(C, str);
|
||||
BKE_write_undo_op(C, str, op);
|
||||
}
|
||||
|
||||
if (wm->file_saved) {
|
||||
@@ -119,8 +120,13 @@ void ED_undo_push(bContext *C, const char *str)
|
||||
}
|
||||
}
|
||||
|
||||
void ED_undo_push(bContext *C, const char *str)
|
||||
{
|
||||
ed_undo_push_internal(C, str, NULL);
|
||||
}
|
||||
|
||||
/* note: also check undo_history_exec() in bottom if you change notifiers */
|
||||
static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
static int ed_undo_step(bContext *C, int step, const char *undoname, const wmOperator *op)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Object *obact = CTX_data_active_object(C);
|
||||
@@ -141,10 +147,10 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
|
||||
|
||||
if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
|
||||
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) {
|
||||
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname ? undoname : op->type->name)) {
|
||||
if (U.uiflag & USER_GLOBALUNDO) {
|
||||
ED_viewport_render_kill_jobs(C, true);
|
||||
BKE_undo_name(C, undoname);
|
||||
BKE_undo_name(C, undoname ? undoname : op->type->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,8 +164,8 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
}
|
||||
else if (obedit) {
|
||||
if (OB_TYPE_SUPPORT_EDITMODE(obedit->type)) {
|
||||
if (undoname)
|
||||
undo_editmode_name(C, undoname);
|
||||
if (op)
|
||||
undo_editmode_op(C, op);
|
||||
else
|
||||
undo_editmode_step(C, step);
|
||||
|
||||
@@ -197,9 +203,9 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
undo_editmode_clear();
|
||||
|
||||
ED_viewport_render_kill_jobs(C, true);
|
||||
|
||||
if (undoname)
|
||||
BKE_undo_name(C, undoname);
|
||||
|
||||
if (op)
|
||||
BKE_undo_op(C, op);
|
||||
else
|
||||
BKE_undo_step(C, step);
|
||||
|
||||
@@ -214,23 +220,23 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
|
||||
void ED_undo_pop(bContext *C)
|
||||
{
|
||||
ed_undo_step(C, 1, NULL);
|
||||
ed_undo_step(C, 1, NULL, NULL);
|
||||
}
|
||||
void ED_undo_redo(bContext *C)
|
||||
{
|
||||
ed_undo_step(C, -1, NULL);
|
||||
ed_undo_step(C, -1, NULL, NULL);
|
||||
}
|
||||
|
||||
void ED_undo_push_op(bContext *C, wmOperator *op)
|
||||
{
|
||||
/* in future, get undo string info? */
|
||||
ED_undo_push(C, op->type->name);
|
||||
ed_undo_push_internal(C, op->type->name, op);
|
||||
}
|
||||
|
||||
void ED_undo_pop_op(bContext *C, wmOperator *op)
|
||||
{
|
||||
/* search back a couple of undo's, in case something else added pushes */
|
||||
ed_undo_step(C, 0, op->type->name);
|
||||
/* go back to the given op exactly */
|
||||
ed_undo_step(C, 0, NULL, op);
|
||||
}
|
||||
|
||||
/* name optionally, function used to check for operator redo panel */
|
||||
@@ -281,9 +287,7 @@ int ED_undo_valid(const bContext *C, const char *undoname)
|
||||
|
||||
static int ed_undo_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
/* "last operator" should disappear, later we can tie this with undo stack nicer */
|
||||
WM_operator_stack_clear(CTX_wm_manager(C));
|
||||
return ed_undo_step(C, 1, NULL);
|
||||
return ed_undo_step(C, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
static int ed_undo_push_exec(bContext *C, wmOperator *op)
|
||||
@@ -296,7 +300,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op)
|
||||
|
||||
static int ed_redo_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
return ed_undo_step(C, -1, NULL);
|
||||
return ed_undo_step(C, -1, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -375,9 +379,11 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
|
||||
printf("redo_cb: operator redo %s\n", op->type->name);
|
||||
ED_undo_pop_op(C, op);
|
||||
|
||||
#if 0
|
||||
if (op->type->check) {
|
||||
op->type->check(C, op); /* ignore return value since its running again anyway */
|
||||
}
|
||||
#endif
|
||||
|
||||
retval = WM_operator_repeat(C, op);
|
||||
if ((retval & OPERATOR_FINISHED) == 0) {
|
||||
|
@@ -35,7 +35,7 @@
|
||||
/* internal exports only */
|
||||
|
||||
/* editmode_undo.c */
|
||||
void undo_editmode_name (struct bContext *C, const char *undoname);
|
||||
void undo_editmode_op (struct bContext *C, const struct wmOperator* op);
|
||||
int undo_editmode_valid (const char *undoname);
|
||||
const char *undo_editmode_get_name (struct bContext *C, int nr, int *active);
|
||||
void *undo_editmode_get_prev (struct Object *ob);
|
||||
|
@@ -103,13 +103,18 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
|
||||
char panelname[64], tabname[64]; /* defined as UI_MAX_NAME_STR */
|
||||
char drawname[64]; /* panelname is identifier for restoring location */
|
||||
int ofsx, ofsy, sizex, sizey;
|
||||
short labelofs, pad;
|
||||
short labelofs;
|
||||
short hidden;
|
||||
short flag, runtime_flag;
|
||||
short control;
|
||||
short snap;
|
||||
int sortorder; /* panels are aligned according to increasing sortorder */
|
||||
struct Panel *paneltab; /* this panel is tabbed in *paneltab */
|
||||
void *activedata; /* runtime for panel manipulation */
|
||||
|
||||
char context[64]; /* save context for custom panels */
|
||||
|
||||
ListBase operators; /* custom operators for custom panel buttons */
|
||||
} Panel;
|
||||
|
||||
/* uiList dynamic data... */
|
||||
@@ -183,6 +188,17 @@ typedef struct ScrArea {
|
||||
ListBase actionzones; /* AZone */
|
||||
} ScrArea;
|
||||
|
||||
|
||||
typedef struct OperatorListItem {
|
||||
struct OperatorListItem *next, *prev;
|
||||
char optype_idname[64];
|
||||
char context[64];
|
||||
struct IDProperty *properties;
|
||||
int opcontext;
|
||||
int flag;
|
||||
} OperatorListItem;
|
||||
|
||||
|
||||
typedef struct ARegion {
|
||||
struct ARegion *next, *prev;
|
||||
|
||||
@@ -211,11 +227,13 @@ typedef struct ARegion {
|
||||
ListBase panels; /* Panel */
|
||||
ListBase ui_lists; /* uiList */
|
||||
ListBase handlers; /* wmEventHandler */
|
||||
ListBase operators; /* OperatorListItem for custom tool shelf */
|
||||
|
||||
struct wmTimer *regiontimer; /* blend in/out */
|
||||
|
||||
char *headerstr; /* use this string to draw info */
|
||||
void *regiondata; /* XXX 2.50, need spacedata equivalent? */
|
||||
void *dragdata;
|
||||
} ARegion;
|
||||
|
||||
/* swap */
|
||||
@@ -257,6 +275,7 @@ typedef struct ARegion {
|
||||
/* paneltype flag */
|
||||
#define PNL_DEFAULT_CLOSED 1
|
||||
#define PNL_NO_HEADER 2
|
||||
#define PNL_CUSTOM_PANELTYPE 4
|
||||
|
||||
/* uiList layout_type */
|
||||
enum {
|
||||
@@ -290,6 +309,13 @@ enum {
|
||||
|
||||
#define UILST_FLT_SORT_MASK (((unsigned int)UILST_FLT_SORT_REVERSE) - 1)
|
||||
|
||||
|
||||
/* OperatorListItem flags */
|
||||
enum {
|
||||
OLI_DIVIDER = 1 << 0, /* 1 for marking the OperatorListItem a divider, 0 for a normal button */
|
||||
OLI_DIVIDER_CLOSED = 1 << 1 /* 1 for marking a divider as being closed, 0 for open */
|
||||
};
|
||||
|
||||
/* regiontype, first two are the default set */
|
||||
/* Do NOT change order, append on end. Types are hardcoded needed */
|
||||
enum {
|
||||
@@ -300,7 +326,8 @@ enum {
|
||||
RGN_TYPE_UI = 4,
|
||||
RGN_TYPE_TOOLS = 5,
|
||||
RGN_TYPE_TOOL_PROPS = 6,
|
||||
RGN_TYPE_PREVIEW = 7
|
||||
RGN_TYPE_PREVIEW = 7,
|
||||
RGN_TYPE_MENU_BAR = 8,
|
||||
};
|
||||
|
||||
/* region alignment */
|
||||
|
@@ -355,6 +355,7 @@ extern StructRNA RNA_MaterialVolume;
|
||||
extern StructRNA RNA_Mask;
|
||||
extern StructRNA RNA_MaskLayer;
|
||||
extern StructRNA RNA_Menu;
|
||||
extern StructRNA RNA_MenuBar;
|
||||
extern StructRNA RNA_Mesh;
|
||||
extern StructRNA RNA_MeshColor;
|
||||
extern StructRNA RNA_MeshColorLayer;
|
||||
|
@@ -102,12 +102,17 @@ EnumPropertyItem node_chunksize_items[] = {
|
||||
#define DEF_ICON_BLANK_SKIP
|
||||
#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""},
|
||||
#define DEF_VICO(name)
|
||||
#define DEF_OPICON(name) {OPICON_##name, (#name), 0, (#name), ""},
|
||||
#define DEF_FIRST_OPICON(name) {OPICON_##name, (#name), 0, (#name), ""},
|
||||
EnumPropertyItem node_icon_items[] = {
|
||||
#include "UI_icons.h"
|
||||
#include "UI_opicons.h"
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
#undef DEF_ICON_BLANK_SKIP
|
||||
#undef DEF_ICON
|
||||
#undef DEF_VICO
|
||||
#undef DEF_OPICON
|
||||
#undef DEF_FIRST_OPICON
|
||||
|
||||
EnumPropertyItem node_math_items[] = {
|
||||
{ 0, "ADD", 0, "Add", ""},
|
||||
|
@@ -45,6 +45,7 @@ EnumPropertyItem region_type_items[] = {
|
||||
{RGN_TYPE_TOOLS, "TOOLS", 0, "Tools", ""},
|
||||
{RGN_TYPE_TOOL_PROPS, "TOOL_PROPS", 0, "Tool Properties", ""},
|
||||
{RGN_TYPE_PREVIEW, "PREVIEW", 0, "Preview", ""},
|
||||
{RGN_TYPE_MENU_BAR, "MENU_BAR", 0, "Editor Menu Bar", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@@ -38,6 +38,8 @@
|
||||
#include "rna_internal.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
@@ -757,6 +759,106 @@ static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
|
||||
else assert(!"setting the bl_description on a non-builtin menu");
|
||||
}
|
||||
|
||||
/* MenuBar */
|
||||
|
||||
static void menubar_draw(const bContext *C, MenuBar *mb)
|
||||
{
|
||||
extern FunctionRNA rna_MenuBar_draw_func;
|
||||
|
||||
PointerRNA ptr;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
|
||||
RNA_pointer_create(&CTX_wm_screen(C)->id, mb->type->ext.srna, mb, &ptr);
|
||||
func = &rna_MenuBar_draw_func;
|
||||
|
||||
RNA_parameter_list_create(&list, &ptr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
mb->type->ext.call((bContext *)C, &ptr, func, &list);
|
||||
|
||||
RNA_parameter_list_free(&list);
|
||||
}
|
||||
|
||||
static void rna_MenuBar_unregister(Main *UNUSED(bmain), StructRNA *type)
|
||||
{
|
||||
ARegionType *art;
|
||||
MenuBarType *mbt = RNA_struct_blender_type_get(type);
|
||||
|
||||
if (!mbt)
|
||||
return;
|
||||
if (!(art = region_type_find(NULL, mbt->space_type, RGN_TYPE_MENU_BAR)))
|
||||
return;
|
||||
|
||||
RNA_struct_free_extension(type, &mbt->ext);
|
||||
|
||||
BLI_freelinkN(&art->menubartypes, mbt);
|
||||
RNA_struct_free(&BLENDER_RNA, type);
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_WINDOW, NULL);
|
||||
}
|
||||
|
||||
static StructRNA *rna_MenuBar_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
|
||||
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
|
||||
{
|
||||
ARegionType *art;
|
||||
MenuBarType *mbt, dummymbt = {NULL};
|
||||
MenuBar dummymb = {NULL};
|
||||
PointerRNA dummyptr;
|
||||
int have_function[1];
|
||||
|
||||
/* setup dummy header & header type to store static properties in */
|
||||
dummymb.type = &dummymbt;
|
||||
RNA_pointer_create(NULL, &RNA_MenuBar, &dummymb, &dummyptr);
|
||||
|
||||
/* validate the python class */
|
||||
if (validate(&dummyptr, data, have_function) != 0)
|
||||
return NULL;
|
||||
|
||||
if (strlen(identifier) >= sizeof(dummymbt.idname)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Registering menu bar class: '%s' is too long, maximum length is %d",
|
||||
identifier, (int)sizeof(dummymbt.idname));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(art = region_type_find(reports, dummymbt.space_type, RGN_TYPE_MENU_BAR)))
|
||||
return NULL;
|
||||
|
||||
/* check if we have registered this header type before, and remove it */
|
||||
for (mbt = art->menubartypes.first; mbt; mbt = mbt->next) {
|
||||
if (strcmp(mbt->idname, dummymbt.idname) == 0) {
|
||||
if (mbt->ext.srna)
|
||||
rna_MenuBar_unregister(bmain, mbt->ext.srna);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* create a new header type */
|
||||
mbt = MEM_callocN(sizeof(MenuBarType), "register menu bar type");
|
||||
memcpy(mbt, &dummymbt, sizeof(dummymbt));
|
||||
|
||||
mbt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mbt->idname, &RNA_MenuBar);
|
||||
mbt->ext.data = data;
|
||||
mbt->ext.call = call;
|
||||
mbt->ext.free = free;
|
||||
RNA_struct_blender_type_set(mbt->ext.srna, mbt);
|
||||
|
||||
mbt->draw = (have_function[0]) ? menubar_draw : NULL;
|
||||
BLI_addtail(&art->menubartypes, mbt);
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_WINDOW, NULL);
|
||||
|
||||
return mbt->ext.srna;
|
||||
}
|
||||
|
||||
static StructRNA *rna_MenuBar_refine(PointerRNA *ptr)
|
||||
{
|
||||
MenuBar *mb = (MenuBar *)ptr->data;
|
||||
|
||||
return (mb->type && mb->type->ext.srna) ? mb->type->ext.srna : &RNA_MenuBar;
|
||||
}
|
||||
|
||||
/* UILayout */
|
||||
|
||||
static int rna_UILayout_active_get(PointerRNA *ptr)
|
||||
@@ -1240,6 +1342,64 @@ static void rna_def_menu(BlenderRNA *brna)
|
||||
RNA_define_verify_sdna(1);
|
||||
}
|
||||
|
||||
static void rna_def_menubar(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
PropertyRNA *parm;
|
||||
FunctionRNA *func;
|
||||
|
||||
srna = RNA_def_struct(brna, "MenuBar", NULL);
|
||||
RNA_def_struct_ui_text(srna, "MenuBar", "Menu Bar for the editor");
|
||||
RNA_def_struct_sdna(srna, "MenuBar");
|
||||
RNA_def_struct_refine_func(srna, "rna_MenuBar_refine");
|
||||
RNA_def_struct_register_funcs(srna, "rna_MenuBar_register", "rna_MenuBar_unregister", NULL);
|
||||
|
||||
/* draw */
|
||||
func = RNA_def_function(srna, "draw", NULL);
|
||||
RNA_def_function_ui_description(func, "Draw UI elements into the menu bar UI layout");
|
||||
RNA_def_function_flag(func, FUNC_REGISTER);
|
||||
parm = RNA_def_pointer(func, "context", "Context", "", "");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
|
||||
RNA_define_verify_sdna(0); /* not in sdna */
|
||||
|
||||
prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "layout");
|
||||
RNA_def_property_struct_type(prop, "UILayout");
|
||||
RNA_def_property_ui_text(prop, "Layout", "Structure of the menu bar in the UI");
|
||||
|
||||
/* registration */
|
||||
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "type->idname");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
|
||||
RNA_def_property_ui_text(prop, "ID Name",
|
||||
"If this is set, the menu bar gets a custom ID, otherwise it takes "
|
||||
"the name of the class used to define the menu bar; for example, if the "
|
||||
"class name is \"OBJECT_MBT_hello\", and bl_idname is not set by the "
|
||||
"script, then bl_idname = \"OBJECT_MBT_hello\"");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
|
||||
RNA_def_property_enum_items(prop, space_type_items);
|
||||
RNA_def_property_flag(prop, PROP_REGISTER);
|
||||
RNA_def_property_ui_text(prop, "Space type", "The space where the menu bar is going to be used in");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
|
||||
RNA_def_property_enum_items(prop, region_type_items);
|
||||
RNA_def_property_flag(prop, PROP_REGISTER);
|
||||
RNA_def_property_ui_text(prop, "Region Type", "The region where the menu bar is going to be used in");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "type->context");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
|
||||
RNA_def_property_ui_text(prop, "Context",
|
||||
"The context in which the panel appears");
|
||||
|
||||
RNA_define_verify_sdna(1);
|
||||
}
|
||||
|
||||
void RNA_def_ui(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_ui_layout(brna);
|
||||
@@ -1247,6 +1407,7 @@ void RNA_def_ui(BlenderRNA *brna)
|
||||
rna_def_uilist(brna);
|
||||
rna_def_header(brna);
|
||||
rna_def_menu(brna);
|
||||
rna_def_menubar(brna);
|
||||
}
|
||||
|
||||
#endif /* RNA_RUNTIME */
|
||||
|
@@ -50,13 +50,18 @@
|
||||
#define DEF_ICON_BLANK_SKIP
|
||||
#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""},
|
||||
#define DEF_VICO(name) {VICO_##name, (#name), 0, (#name), ""},
|
||||
#define DEF_OPICON(name) {OPICON_##name, (#name), 0, (#name), ""},
|
||||
#define DEF_FIRST_OPICON(name) {OPICON_##name, (#name), 0, (#name), ""},
|
||||
EnumPropertyItem icon_items[] = {
|
||||
#include "UI_icons.h"
|
||||
#include "UI_opicons.h"
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
#undef DEF_ICON_BLANK_SKIP
|
||||
#undef DEF_ICON
|
||||
#undef DEF_VICO
|
||||
#undef DEF_OPICON
|
||||
#undef DEF_FIRST_OPICON
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
@@ -174,7 +179,7 @@ static void rna_uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const c
|
||||
}
|
||||
|
||||
static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, const char *text_ctxt,
|
||||
int translate, int icon, int emboss)
|
||||
int translate, int icon, int emboss, int single_unit, int shortcut)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
int flag;
|
||||
@@ -190,6 +195,9 @@ static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *
|
||||
|
||||
flag = UI_ITEM_O_RETURN_PROPS;
|
||||
flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG;
|
||||
|
||||
if (single_unit) flag |= UI_ITEM_O_SINGLE_UNIT;
|
||||
if (shortcut) flag |= UI_ITEM_O_SHORTCUT;
|
||||
|
||||
return uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag);
|
||||
}
|
||||
@@ -422,21 +430,26 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
static float node_socket_color_default[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
/* simple layout specifiers */
|
||||
func = RNA_def_function(srna, "row", "uiLayoutRow");
|
||||
func = RNA_def_function(srna, "row", "uiLayoutRowWithButtonHeight");
|
||||
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
|
||||
RNA_def_function_return(func, parm);
|
||||
RNA_def_function_ui_description(func,
|
||||
"Sub-layout. Items placed in this sublayout are placed next to each other "
|
||||
"in a row");
|
||||
RNA_def_boolean(func, "align", false, "", "Align buttons to each other");
|
||||
// TODO: button_height should be replaced by the already present scale_y property. ~ ack-err
|
||||
parm = RNA_def_float(func, "button_height", 1.0f, 1.0f, 5.0f, "",
|
||||
"The multiplier for the height of buttons in this new layout.", 1.0f, 5.0f);
|
||||
|
||||
func = RNA_def_function(srna, "column", "uiLayoutColumn");
|
||||
func = RNA_def_function(srna, "column", "uiLayoutColumnWithButtonHeight");
|
||||
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
|
||||
RNA_def_function_return(func, parm);
|
||||
RNA_def_function_ui_description(func,
|
||||
"Sub-layout. Items placed in this sublayout are placed under each other "
|
||||
"in a column");
|
||||
RNA_def_boolean(func, "align", false, "", "Align buttons to each other");
|
||||
parm = RNA_def_float(func, "button_height", 1.0f, 1.0f, 5.0f, "",
|
||||
"The multiplier for the height of buttons in this new layout.", 1.0f, 5.0f);
|
||||
|
||||
func = RNA_def_function(srna, "column_flow", "uiLayoutColumnFlow");
|
||||
RNA_def_int(func, "columns", 0, 0, INT_MAX, "", "Number of columns, 0 is automatic", 0, INT_MAX);
|
||||
@@ -536,6 +549,8 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
func = RNA_def_function(srna, "operator", "rna_uiItemO");
|
||||
api_ui_item_op_common(func);
|
||||
RNA_def_boolean(func, "emboss", true, "", "Draw the button itself, just the icon/text");
|
||||
RNA_def_boolean(func, "single_unit", 0, "", "Truncate the button width to a single unit if there is no text");
|
||||
RNA_def_boolean(func, "shortcut", 1, "", "Show the shortcut on the button if there is one");
|
||||
parm = RNA_def_pointer(func, "properties", "OperatorProperties", "",
|
||||
"Operator properties to fill in, return when 'properties' is set to true");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
|
||||
@@ -641,6 +656,15 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
|
||||
RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX);
|
||||
|
||||
func = RNA_def_function(srna, "template_ID_preview_compact", "uiTemplateIDPreviewCompact");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
api_ui_item_rna_common(func);
|
||||
RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block");
|
||||
RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block");
|
||||
RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block");
|
||||
RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
|
||||
RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX);
|
||||
|
||||
func = RNA_def_function(srna, "template_any_ID", "rna_uiTemplateAnyID");
|
||||
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
|
||||
|
@@ -464,7 +464,7 @@ static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
|
||||
|
||||
if (wm)
|
||||
for (op = wm->operators.first; op; op = op->next)
|
||||
if (op->properties == properties)
|
||||
if (op->properties && op->properties == properties)
|
||||
return op;
|
||||
|
||||
return NULL;
|
||||
@@ -1424,6 +1424,12 @@ static void rna_def_operator(BlenderRNA *brna)
|
||||
RNA_def_property_enum_items(prop, operator_flag_items);
|
||||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
|
||||
RNA_def_property_ui_text(prop, "Options", "Options for this operator type");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_icon", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "type->default_icon");
|
||||
RNA_def_property_enum_items(prop, icon_items); /* TODO: operator_icon_items */
|
||||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
|
||||
RNA_def_property_ui_text(prop, "Icon", "Default icon for this operator type");
|
||||
|
||||
RNA_api_operator(srna);
|
||||
|
||||
|
@@ -209,6 +209,7 @@ int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, con
|
||||
void WM_operator_free (struct wmOperator *op);
|
||||
void WM_operator_type_set(struct wmOperator *op, struct wmOperatorType *ot);
|
||||
void WM_operator_stack_clear(struct wmWindowManager *wm);
|
||||
void WM_operator_build_stack(struct bContext *C, const ListBase *uels, bool notify);
|
||||
void WM_operator_handlers_clear(wmWindowManager *wm, struct wmOperatorType *ot);
|
||||
|
||||
struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet);
|
||||
@@ -250,9 +251,16 @@ void WM_operator_properties_select_action(struct wmOperatorType *ot, int defaul
|
||||
bool WM_operator_check_ui_enabled(const struct bContext *C, const char *idname);
|
||||
wmOperator *WM_operator_last_redo(const struct bContext *C);
|
||||
|
||||
bool WM_operator_last_properties_init(struct wmOperator *op);
|
||||
wmOperator *WM_operator_create(const struct bContext *C, struct wmOperatorType *ot,
|
||||
struct PointerRNA *properties, struct ReportList *reports);
|
||||
wmOperator *WM_operator_copy(struct bContext *C, wmOperator *op, bool copylink);
|
||||
bool WM_operator_properties_init(struct wmOperator *op);
|
||||
bool WM_operator_last_properties_store(struct wmOperator *op);
|
||||
bool WM_operator_default_properties_store(struct wmOperator *op);
|
||||
|
||||
void add_to_icon_shelf(struct bContext *C, void *arg1, void *arg2);
|
||||
void add_to_custom_panel_menu(struct bContext *C, struct uiLayout *layout, void *arg);
|
||||
|
||||
/* MOVE THIS SOMEWHERE ELSE */
|
||||
#define SEL_TOGGLE 0
|
||||
#define SEL_SELECT 1
|
||||
@@ -322,11 +330,12 @@ void WM_event_print(const struct wmEvent *event);
|
||||
void WM_operator_region_active_win_set(struct bContext *C);
|
||||
|
||||
/* drag and drop */
|
||||
struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value);
|
||||
struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value, struct PointerRNA *ptr, short opcontext);
|
||||
void wm_drag_free(struct wmDrag *drag);
|
||||
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);
|
||||
|
||||
struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event),
|
||||
void (*copy)(struct wmDrag *, struct wmDropBox *));
|
||||
void (*copy)(const struct bContext *, const struct wmEvent *, struct wmDrag *, struct wmDropBox *));
|
||||
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
|
||||
|
||||
/* Set a subwindow active in pixelspace view, with optional scissor subset */
|
||||
|
@@ -545,10 +545,17 @@ typedef struct wmOperatorType {
|
||||
|
||||
/* optional panel for redo and repeat, autogenerated if not set */
|
||||
void (*ui)(struct bContext *, struct wmOperator *);
|
||||
|
||||
/* optional function to decide which icon to use based on operator properties */
|
||||
int (*icon)(const struct bContext *, PointerRNA *);
|
||||
|
||||
/* rna for properties */
|
||||
struct StructRNA *srna;
|
||||
|
||||
/* default settings - for initializing */
|
||||
struct IDProperty *default_properties;
|
||||
struct wmOperator *default_properties_op;
|
||||
|
||||
/* previous settings - for initializing on re-use */
|
||||
struct IDProperty *last_properties;
|
||||
|
||||
@@ -572,6 +579,7 @@ typedef struct wmOperatorType {
|
||||
|
||||
/* Flag last for padding */
|
||||
short flag;
|
||||
int default_icon;
|
||||
|
||||
} wmOperatorType;
|
||||
|
||||
@@ -606,6 +614,7 @@ typedef struct wmReport {
|
||||
#define WM_DRAG_PATH 2
|
||||
#define WM_DRAG_NAME 3
|
||||
#define WM_DRAG_VALUE 4
|
||||
#define WM_DRAG_OP 5
|
||||
|
||||
/* note: structs need not exported? */
|
||||
|
||||
@@ -622,6 +631,8 @@ typedef struct wmDrag {
|
||||
int sx, sy;
|
||||
|
||||
char opname[200]; /* if set, draws operator name*/
|
||||
PointerRNA *ptr;
|
||||
int opcontext;
|
||||
} wmDrag;
|
||||
|
||||
/* dropboxes are like keymaps, part of the screen/area/region definition */
|
||||
@@ -633,7 +644,7 @@ typedef struct wmDropBox {
|
||||
int (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
|
||||
|
||||
/* before exec, this copies drag info to wmDrop properties */
|
||||
void (*copy)(struct wmDrag *, struct wmDropBox *);
|
||||
void (*copy)(const struct bContext *, const struct wmEvent *, struct wmDrag *, struct wmDropBox *);
|
||||
|
||||
/* if poll survives, operator is called */
|
||||
wmOperatorType *ot; /* not saved in file, so can be pointer */
|
||||
|
@@ -134,9 +134,13 @@ static void wm_reports_free(wmWindowManager *wm)
|
||||
void wm_operator_register(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
int tot;
|
||||
|
||||
BLI_addtail(&wm->operators, op);
|
||||
|
||||
/* The operator stack is limited by the undo stacks, and therefore we do not
|
||||
* have to check for MAX_OP_REGISTERED. */
|
||||
#if 0
|
||||
int tot;
|
||||
tot = BLI_countlist(&wm->operators);
|
||||
|
||||
while (tot > MAX_OP_REGISTERED) {
|
||||
@@ -145,6 +149,7 @@ void wm_operator_register(bContext *C, wmOperator *op)
|
||||
WM_operator_free(opt);
|
||||
tot--;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* so the console is redrawn */
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
|
||||
@@ -163,6 +168,34 @@ void WM_operator_stack_clear(wmWindowManager *wm)
|
||||
WM_main_add_notifier(NC_WM | ND_HISTORY, NULL);
|
||||
}
|
||||
|
||||
/* This ugly little duckling is used to be able to access both the
|
||||
edit mode and object mode UndoElems. */
|
||||
typedef struct UndoElem {
|
||||
struct UndoElem *next, *prev;
|
||||
wmOperator * op;
|
||||
} UndoElem;
|
||||
|
||||
void WM_operator_build_stack(bContext *C, const ListBase *uels, bool notify)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
UndoElem *uel;
|
||||
|
||||
wm->operators.first = NULL;
|
||||
wm->operators.last = NULL;
|
||||
|
||||
for (uel = uels->first; uel && uel->prev != uels->last; uel = uel->next) {
|
||||
if (uel->op && uel->op->type && uel->op->type->flag & OPTYPE_UNDO && uel->op->type->flag & OPTYPE_REGISTER) {
|
||||
BLI_addtail(&wm->operators, uel->op);
|
||||
}
|
||||
}
|
||||
|
||||
if (notify)
|
||||
{
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_HISTORY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is needed in the case when an addon id disabled
|
||||
* while a modal operator it defined is running.
|
||||
@@ -407,8 +440,8 @@ void wm_add_default(bContext *C)
|
||||
void wm_close_and_free(bContext *C, wmWindowManager *wm)
|
||||
{
|
||||
wmWindow *win;
|
||||
wmOperator *op;
|
||||
wmKeyConfig *keyconf;
|
||||
wmDrag *drag;
|
||||
|
||||
if (wm->autosavetimer)
|
||||
wm_autosave_timer_ended(wm);
|
||||
@@ -419,9 +452,12 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
|
||||
wm_window_free(C, wm, win);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// we're freeing the operators from the undo system
|
||||
while ((op = BLI_pophead(&wm->operators))) {
|
||||
WM_operator_free(op);
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((keyconf = BLI_pophead(&wm->keyconfigs))) {
|
||||
WM_keyconfig_free(keyconf);
|
||||
@@ -430,6 +466,10 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
|
||||
BLI_freelistN(&wm->queue);
|
||||
|
||||
BLI_freelistN(&wm->paintcursors);
|
||||
|
||||
while ((drag = BLI_pophead(&wm->drags))) {
|
||||
wm_drag_free(drag);
|
||||
}
|
||||
BLI_freelistN(&wm->drags);
|
||||
|
||||
wm_reports_free(wm);
|
||||
|
@@ -104,7 +104,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
|
||||
|
||||
|
||||
wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext *, wmDrag *, const wmEvent *),
|
||||
void (*copy)(wmDrag *, wmDropBox *))
|
||||
void (*copy)(const bContext *, const wmEvent *, wmDrag *, wmDropBox *))
|
||||
{
|
||||
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
|
||||
|
||||
@@ -147,7 +147,7 @@ void wm_dropbox_free(void)
|
||||
/* *********************************** */
|
||||
|
||||
/* note that the pointer should be valid allocated and not on stack */
|
||||
wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value)
|
||||
wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value, PointerRNA *ptr, short opcontext)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmDrag *drag = MEM_callocN(sizeof(struct wmDrag), "new drag");
|
||||
@@ -160,6 +160,15 @@ wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin,
|
||||
drag->type = type;
|
||||
if (type == WM_DRAG_PATH)
|
||||
BLI_strncpy(drag->path, poin, FILE_MAX);
|
||||
else if (type == WM_DRAG_OP) {
|
||||
/* the PointerRNA should be copied */
|
||||
if (ptr && ptr->data) {
|
||||
drag->ptr = MEM_callocN(sizeof(PointerRNA), "PointerRNA for dragging");
|
||||
drag->ptr->data = IDP_CopyProperty(ptr->data);
|
||||
}
|
||||
drag->opcontext = (int)opcontext;
|
||||
drag->poin = poin;
|
||||
}
|
||||
else
|
||||
drag->poin = poin;
|
||||
drag->value = value;
|
||||
@@ -167,6 +176,16 @@ wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin,
|
||||
return drag;
|
||||
}
|
||||
|
||||
/* N.B. this doesn't free drag itself */
|
||||
void wm_drag_free(wmDrag *drag)
|
||||
{
|
||||
if (drag->ptr) {
|
||||
if (drag->type == WM_DRAG_OP)
|
||||
WM_operator_properties_free(drag->ptr);
|
||||
MEM_freeN(drag->ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy)
|
||||
{
|
||||
drag->imb = imb;
|
||||
@@ -199,7 +218,9 @@ static const char *wm_dropbox_active(bContext *C, wmDrag *drag, wmEvent *event)
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
const char *name;
|
||||
ARegion *ar_iter = NULL;
|
||||
const char *name = NULL;
|
||||
const char *name_overlap = NULL;
|
||||
|
||||
name = dropbox_active(C, &win->handlers, drag, event);
|
||||
if (name) return name;
|
||||
@@ -208,7 +229,27 @@ static const char *wm_dropbox_active(bContext *C, wmDrag *drag, wmEvent *event)
|
||||
if (name) return name;
|
||||
|
||||
name = dropbox_active(C, &ar->handlers, drag, event);
|
||||
if (name) return name;
|
||||
|
||||
/* Make sure overlapping regions are preferred over non-overlapping ones */
|
||||
if (!ar->overlap) {
|
||||
for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) {
|
||||
if (ar_iter->overlap) {
|
||||
/* only update name_overlap if none was found yet */
|
||||
if (name_overlap == NULL) {
|
||||
/* We've got to fake the region for a little bit */
|
||||
CTX_wm_region_set(C, ar_iter);
|
||||
name_overlap = dropbox_active(C, &ar_iter->handlers, drag, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* make sure proper region is restored */
|
||||
CTX_wm_region_set(C, ar);
|
||||
|
||||
if (name_overlap)
|
||||
return name_overlap;
|
||||
if (name)
|
||||
return name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -279,6 +320,11 @@ static const char *wm_drag_name(wmDrag *drag)
|
||||
return drag->path;
|
||||
case WM_DRAG_NAME:
|
||||
return (char *)drag->path;
|
||||
case WM_DRAG_OP:
|
||||
{
|
||||
wmOperatorType *ot = (wmOperatorType*)drag->poin;
|
||||
return ot->name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@@ -109,8 +109,16 @@ void wm_event_free(wmEvent *event)
|
||||
if (event->customdata) {
|
||||
if (event->customdatafree) {
|
||||
/* note: pointer to listbase struct elsewhere */
|
||||
if (event->custom == EVT_DATA_LISTBASE)
|
||||
if (event->custom == EVT_DATA_LISTBASE) {
|
||||
if (event->type == EVT_DROP) {
|
||||
ListBase *lb = (ListBase *)event->customdata;
|
||||
wmDrag *drag;
|
||||
for (drag = lb->first; drag; drag = drag->next) {
|
||||
wm_drag_free(drag);
|
||||
}
|
||||
}
|
||||
BLI_freelistN(event->customdata);
|
||||
}
|
||||
else
|
||||
MEM_freeN(event->customdata);
|
||||
}
|
||||
@@ -638,6 +646,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int cal
|
||||
wm_add_reports(C, op->reports);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* this function is mainly to check that the rules for freeing
|
||||
* an operator are kept in sync.
|
||||
*/
|
||||
@@ -645,8 +654,9 @@ static int wm_operator_register_check(wmWindowManager *wm, wmOperatorType *ot)
|
||||
{
|
||||
return wm && (wm->op_undo_depth == 0) && (ot->flag & OPTYPE_REGISTER);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
|
||||
static void wm_operator_finished(bContext *C, wmOperator *op, int UNUSED(repeat))
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
|
||||
@@ -655,10 +665,16 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
|
||||
/* we don't want to do undo pushes for operators that are being
|
||||
* called from operators that already do an undo push. usually
|
||||
* this will happen for python operators that call C operators */
|
||||
if (wm->op_undo_depth == 0)
|
||||
if (op->type->flag & OPTYPE_UNDO)
|
||||
ED_undo_push_op(C, op);
|
||||
|
||||
if (wm->op_undo_depth == 0
|
||||
&& op->type->flag & OPTYPE_UNDO) {
|
||||
ED_undo_push_op(C, op);
|
||||
if (!(op->type->flag & OPTYPE_REGISTER))
|
||||
WM_operator_free(op);
|
||||
} else
|
||||
WM_operator_free(op);
|
||||
|
||||
#if 0
|
||||
// operators are registered and freed from the undo system.
|
||||
if (repeat == 0) {
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
char *buf = WM_operator_pystring(C, op->type, op->ptr, 1);
|
||||
@@ -677,6 +693,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
|
||||
WM_operator_free(op);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* if repeat is true, it doesn't register again, nor does it free */
|
||||
@@ -873,6 +890,30 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot,
|
||||
return op;
|
||||
}
|
||||
|
||||
wmOperator *WM_operator_create(const bContext *C, wmOperatorType *ot,
|
||||
PointerRNA *properties, ReportList *reports)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
return wm_operator_create(wm, ot, properties, reports);
|
||||
}
|
||||
|
||||
wmOperator *WM_operator_copy(bContext *C, wmOperator *op, bool copylink)
|
||||
{
|
||||
/* The logic wm_operator_create is used as it already
|
||||
* creates copies of the properties. Note that the
|
||||
* report list is not copied. */
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmOperator *newop = wm_operator_create(wm, op->type, op->ptr, NULL);
|
||||
|
||||
/* This likely isn't necessary. */
|
||||
if(!copylink)
|
||||
{
|
||||
newop->next = NULL;
|
||||
newop->prev = NULL;
|
||||
}
|
||||
return newop;
|
||||
}
|
||||
|
||||
static void wm_region_mouse_co(bContext *C, wmEvent *event)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
@@ -888,59 +929,68 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
#if 1 /* may want to disable operator remembering previous state for testing */
|
||||
bool WM_operator_last_properties_init(wmOperator *op)
|
||||
{
|
||||
static bool wm_operator_properties_init_set(wmOperator *op, IDProperty **properties, bool respect_skip_save, bool respect_already_set) {
|
||||
PropertyRNA *iterprop = iterprop = RNA_struct_iterator_property(op->type->srna);
|
||||
bool change = false;
|
||||
|
||||
if (op->type->last_properties) {
|
||||
PropertyRNA *iterprop;
|
||||
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
printf("%s: loading previous properties for '%s'\n", __func__, op->type->idname);
|
||||
}
|
||||
|
||||
iterprop = RNA_struct_iterator_property(op->type->srna);
|
||||
|
||||
RNA_PROP_BEGIN (op->ptr, itemptr, iterprop)
|
||||
{
|
||||
PropertyRNA *prop = itemptr.data;
|
||||
if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
|
||||
if (!RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */
|
||||
const char *identifier = RNA_property_identifier(prop);
|
||||
IDProperty *idp_src = IDP_GetPropertyFromGroup(op->type->last_properties, identifier);
|
||||
if (idp_src) {
|
||||
IDProperty *idp_dst = IDP_CopyProperty(idp_src);
|
||||
|
||||
/* note - in the future this may need to be done recursively,
|
||||
* but for now RNA doesn't access nested operators */
|
||||
idp_dst->flag |= IDP_FLAG_GHOST;
|
||||
|
||||
IDP_ReplaceInGroup(op->properties, idp_dst);
|
||||
change = true;
|
||||
}
|
||||
RNA_PROP_BEGIN (op->ptr, itemptr, iterprop)
|
||||
{
|
||||
PropertyRNA *prop = itemptr.data;
|
||||
if (!respect_skip_save || (RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
|
||||
if (!respect_already_set || !RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */
|
||||
const char *identifier = RNA_property_identifier(prop);
|
||||
IDProperty *idp_src = IDP_GetPropertyFromGroup(*properties, identifier);
|
||||
if (idp_src) {
|
||||
IDProperty *idp_dst = IDP_CopyProperty(idp_src);
|
||||
|
||||
/* note - in the future this may need to be done recursively,
|
||||
* but for now RNA doesn't access nested operators */
|
||||
idp_dst->flag |= IDP_FLAG_GHOST;
|
||||
|
||||
IDP_ReplaceInGroup(op->properties, idp_dst);
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
RNA_PROP_END;
|
||||
}
|
||||
RNA_PROP_END;
|
||||
return change;
|
||||
}
|
||||
|
||||
#if 1 /* may want to disable operator remembering previous state for testing */
|
||||
bool WM_operator_properties_init(wmOperator *op)
|
||||
{
|
||||
bool change = false;
|
||||
|
||||
if (op->type->default_properties) {
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
printf("%s: loading default properties for '%s'\n", __func__, op->type->idname);
|
||||
}
|
||||
change = wm_operator_properties_init_set(op, &(op->type->default_properties), FALSE, FALSE);
|
||||
}
|
||||
if (op->type->last_properties) {
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
printf("%s: loading previous properties for '%s'\n", __func__, op->type->idname);
|
||||
}
|
||||
// don't overwrite the previously set change flag
|
||||
change = change ? change : wm_operator_properties_init_set(op, &(op->type->last_properties), TRUE, TRUE);
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
bool WM_operator_last_properties_store(wmOperator *op)
|
||||
static bool wm_operator_properties_store(wmOperator *op, IDProperty **properties)
|
||||
{
|
||||
if (op->type->last_properties) {
|
||||
IDP_FreeProperty(op->type->last_properties);
|
||||
MEM_freeN(op->type->last_properties);
|
||||
op->type->last_properties = NULL;
|
||||
if (*properties) {
|
||||
IDP_FreeProperty(*properties);
|
||||
MEM_freeN(*properties);
|
||||
*properties = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (op->properties) {
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
printf("%s: storing properties for '%s'\n", __func__, op->type->idname);
|
||||
}
|
||||
op->type->last_properties = IDP_CopyProperty(op->properties);
|
||||
*properties = IDP_CopyProperty(op->properties);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -948,6 +998,16 @@ bool WM_operator_last_properties_store(wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
bool WM_operator_last_properties_store(wmOperator *op)
|
||||
{
|
||||
return wm_operator_properties_store(op, &(op->type->last_properties));
|
||||
}
|
||||
|
||||
bool WM_operator_default_properties_store(wmOperator *op)
|
||||
{
|
||||
return wm_operator_properties_store(op, &(op->type->default_properties));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int WM_operator_last_properties_init(wmOperator *UNUSED(op))
|
||||
@@ -978,9 +1038,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event,
|
||||
|
||||
/* initialize setting from previous run */
|
||||
if (!is_nested_call) { /* not called by py script */
|
||||
WM_operator_last_properties_init(op);
|
||||
WM_operator_properties_init(op);
|
||||
}
|
||||
|
||||
|
||||
if ((G.debug & G_DEBUG_HANDLERS) && ((event == NULL) || (event->type != MOUSEMOVE))) {
|
||||
printf("%s: handle evt %d win %d op %s\n",
|
||||
__func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname);
|
||||
@@ -1698,7 +1758,11 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
|
||||
WM_operator_last_properties_store(handler->op);
|
||||
}
|
||||
|
||||
WM_operator_free(handler->op);
|
||||
// Only free if it wasn't registered
|
||||
if (!(handler->op->type
|
||||
&& (handler->op->type->flag & OPTYPE_REGISTER)
|
||||
&& (handler->op->type->flag & OPTYPE_UNDO)))
|
||||
WM_operator_free(handler->op);
|
||||
}
|
||||
else {
|
||||
if (handler->op->type->cancel) {
|
||||
@@ -1876,24 +1940,27 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
|
||||
for (drag = lb->first; drag; drag = drag->next) {
|
||||
if (drop->poll(C, drag, event)) {
|
||||
|
||||
drop->copy(drag, drop);
|
||||
drop->copy(C, event, drag, drop);
|
||||
|
||||
/* free the drags before calling operator */
|
||||
BLI_freelistN(event->customdata);
|
||||
event->customdata = NULL;
|
||||
event->custom = 0;
|
||||
|
||||
WM_operator_name_call(C, drop->ot->idname, drop->opcontext, drop->ptr);
|
||||
action |= WM_HANDLER_BREAK;
|
||||
|
||||
|
||||
/* XXX fileread case */
|
||||
if (CTX_wm_window(C) == NULL)
|
||||
return action;
|
||||
|
||||
/* escape from drag loop, got freed */
|
||||
/* escape from drag loop... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* and free all the drags */
|
||||
for (drag = lb->first; drag; drag = drag->next) {
|
||||
wm_drag_free(drag);
|
||||
}
|
||||
BLI_freelistN(lb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2077,18 +2144,34 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
|
||||
if (event->type == MOUSEMOVE)
|
||||
win->screen->do_draw_drag = TRUE;
|
||||
else if (event->type == ESCKEY) {
|
||||
wmDrag *drag;
|
||||
for (drag = wm->drags.first; drag; drag = drag->next) {
|
||||
wm_drag_free(drag);
|
||||
}
|
||||
BLI_freelistN(&wm->drags);
|
||||
win->screen->do_draw_drag = TRUE;
|
||||
}
|
||||
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
event->type = EVT_DROP;
|
||||
|
||||
/* create customdata, first free existing */
|
||||
if (event->customdata) {
|
||||
if (event->customdatafree)
|
||||
MEM_freeN(event->customdata);
|
||||
if (event->customdatafree) {
|
||||
if (event->custom == EVT_DATA_LISTBASE) {
|
||||
if (event->type == EVT_DROP) {
|
||||
ListBase *lb = (ListBase *)event->customdata;
|
||||
wmDrag *drag;
|
||||
for (drag = lb->first; drag; drag = drag->next) {
|
||||
wm_drag_free(drag);
|
||||
}
|
||||
}
|
||||
BLI_freelistN(event->customdata);
|
||||
}
|
||||
else
|
||||
MEM_freeN(event->customdata);
|
||||
}
|
||||
}
|
||||
|
||||
event->type = EVT_DROP;
|
||||
event->custom = EVT_DATA_LISTBASE;
|
||||
event->customdata = &wm->drags;
|
||||
event->customdatafree = 1;
|
||||
@@ -2216,29 +2299,37 @@ void wm_event_do_handlers(bContext *C)
|
||||
CTX_wm_area_set(C, sa);
|
||||
|
||||
if ((action & WM_HANDLER_BREAK) == 0) {
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
if (wm_event_inside_i(event, &ar->winrct)) {
|
||||
CTX_wm_region_set(C, ar);
|
||||
|
||||
/* call even on non mouse events, since the */
|
||||
wm_region_mouse_co(C, event);
|
||||
/* Go through the regions twice, first for floating regions, then for normal ones.
|
||||
This entails that floating panels catch events first. This is done because floating
|
||||
panels should be drawn over other regions. */
|
||||
for (int i=0; i<2; i++) {
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
if ((i == 0 && ar->alignment == RGN_ALIGN_FLOAT) ||
|
||||
(i == 1 && ar->alignment != RGN_ALIGN_FLOAT)) {
|
||||
if (wm_event_inside_i(event, &ar->winrct)) {
|
||||
CTX_wm_region_set(C, ar);
|
||||
|
||||
/* call even on non mouse events, since the */
|
||||
wm_region_mouse_co(C, event);
|
||||
|
||||
/* does polls for drop regions and checks uibuts */
|
||||
/* need to be here to make sure region context is true */
|
||||
if (ELEM(event->type, MOUSEMOVE, EVT_DROP)) {
|
||||
wm_drags_check_ops(C, event);
|
||||
/* does polls for drop regions and checks uibuts */
|
||||
/* need to be here to make sure region context is true */
|
||||
if (ELEM(event->type, MOUSEMOVE, EVT_DROP)) {
|
||||
wm_drags_check_ops(C, event);
|
||||
}
|
||||
|
||||
action |= wm_handlers_do(C, event, &ar->handlers);
|
||||
|
||||
/* fileread case (python), [#29489] */
|
||||
if (CTX_wm_window(C) == NULL)
|
||||
return;
|
||||
|
||||
doit |= (BLI_rcti_isect_pt_v(&ar->winrct, &event->x));
|
||||
|
||||
if (action & WM_HANDLER_BREAK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
action |= wm_handlers_do(C, event, &ar->handlers);
|
||||
|
||||
/* fileread case (python), [#29489] */
|
||||
if (CTX_wm_window(C) == NULL)
|
||||
return;
|
||||
|
||||
doit |= (BLI_rcti_isect_pt_v(&ar->winrct, &event->x));
|
||||
|
||||
if (action & WM_HANDLER_BREAK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -484,7 +484,7 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
|
||||
}
|
||||
#endif
|
||||
|
||||
BKE_reset_undo();
|
||||
BKE_reset_undo(C);
|
||||
BKE_write_undo(C, "original"); /* save current state */
|
||||
}
|
||||
else if (retval == BKE_READ_EXOTIC_OK_OTHER)
|
||||
@@ -594,7 +594,7 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
|
||||
// refresh_interface_font();
|
||||
|
||||
// undo_editmode_clear();
|
||||
BKE_reset_undo();
|
||||
BKE_reset_undo(C);
|
||||
BKE_write_undo(C, "original"); /* save current state */
|
||||
|
||||
ED_editors_init(C);
|
||||
|
@@ -395,6 +395,7 @@ void WM_exit_ext(bContext *C, const short do_python)
|
||||
wmWindow *win;
|
||||
|
||||
if (!G.background) {
|
||||
|
||||
if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) {
|
||||
/* save the undo state as quit.blend */
|
||||
char filename[FILE_MAX];
|
||||
@@ -493,7 +494,7 @@ void WM_exit_ext(bContext *C, const short do_python)
|
||||
GPU_free_unused_buffers();
|
||||
GPU_extensions_exit();
|
||||
|
||||
BKE_reset_undo();
|
||||
BKE_reset_undo(C);
|
||||
|
||||
ED_file_exit(); /* for fsmenu */
|
||||
|
||||
|
@@ -91,6 +91,7 @@
|
||||
#include "ED_object.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "RNA_types.h"
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
@@ -113,6 +114,8 @@ static GHash *global_ops_hash = NULL;
|
||||
|
||||
#define UNDOCUMENTED_OPERATOR_TIP N_("(undocumented operator)")
|
||||
|
||||
#define MAX_CUSTOM_PANELS 1000
|
||||
|
||||
/* ************ operator API, exported ********** */
|
||||
|
||||
|
||||
@@ -467,6 +470,14 @@ int WM_operatortype_remove(const char *idname)
|
||||
IDP_FreeProperty(ot->last_properties);
|
||||
MEM_freeN(ot->last_properties);
|
||||
}
|
||||
|
||||
if (ot->default_properties) {
|
||||
IDP_FreeProperty(ot->default_properties);
|
||||
MEM_freeN(ot->default_properties);
|
||||
}
|
||||
|
||||
if(ot->default_properties_op)
|
||||
WM_operator_free(ot->default_properties_op);
|
||||
|
||||
if (ot->macro.first)
|
||||
wm_operatortype_free_macro(ot);
|
||||
@@ -1217,7 +1228,9 @@ wmOperator *WM_operator_last_redo(const bContext *C)
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmOperator *op;
|
||||
|
||||
/* only for operators that are registered and did an undo push */
|
||||
/* Only for operators that are registered and did an undo push.
|
||||
These should be the only ones in here anyway.
|
||||
*/
|
||||
for (op = wm->operators.last; op; op = op->prev)
|
||||
if ((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
|
||||
break;
|
||||
@@ -1235,8 +1248,10 @@ static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event))
|
||||
}
|
||||
else {
|
||||
/* operator not executed yet, call it */
|
||||
ED_undo_push_op(C, op);
|
||||
wm_operator_register(C, op);
|
||||
/* -- When does this happen?
|
||||
-- Also, the undo stack should be updated when the operator finishes
|
||||
~ ack-err */
|
||||
//ED_undo_push_op(C, op);
|
||||
|
||||
WM_operator_repeat(C, op);
|
||||
}
|
||||
@@ -1385,7 +1400,7 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
|
||||
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, style);
|
||||
|
||||
/* since ui is defined the auto-layout args are not used */
|
||||
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
|
||||
uiLayoutOperatorButs(C, layout, op, NULL, 'H', 0);
|
||||
|
||||
uiPopupBoundsBlock(block, 4, 0, 0);
|
||||
uiEndBlock(C, block);
|
||||
@@ -4137,6 +4152,286 @@ static void operatortype_ghash_free_cb(wmOperatorType *ot)
|
||||
MEM_freeN(ot);
|
||||
}
|
||||
|
||||
/* ******************************************************* */
|
||||
|
||||
void add_to_icon_shelf(bContext *C, void *ot_arg, void *opptr_arg)
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_MENU_BAR);
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
|
||||
if (ar && ot_arg)
|
||||
{
|
||||
wmOperatorType *ot = (wmOperatorType*)ot_arg;
|
||||
OperatorListItem *oli;
|
||||
PointerRNA *opptr = (PointerRNA*)opptr_arg;
|
||||
|
||||
if (uiOperatorListItemPresent(&ar->operators, ot->idname, opptr->data, CTX_data_mode_string(C))) {
|
||||
BKE_reportf(&wm->reports, RPT_INFO, "This operator (%s) is already present in the menubar.", ot->idname);
|
||||
return;
|
||||
}
|
||||
|
||||
oli = MEM_callocN(sizeof(OperatorListItem), "add operator list item to icon shelf");
|
||||
|
||||
BLI_strncpy(oli->optype_idname, ot->idname, OP_MAX_TYPENAME);
|
||||
BLI_strncpy(oli->context, CTX_data_mode_string(C), MAX_NAME);
|
||||
|
||||
if (opptr) {
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_struct_find_property(opptr, "COPY_opcontext");
|
||||
if(prop)
|
||||
oli->opcontext = RNA_property_int_get(opptr, prop);
|
||||
|
||||
/* clear the properties that were only necessary for this operator execution */
|
||||
/* TODO: see if this can all be done a little bit nicer by including a pointer as a property */
|
||||
RNA_struct_idprops_unset(opptr, "COPY_opcontext");
|
||||
RNA_struct_idprops_unset(opptr, "COPY_idname");
|
||||
|
||||
oli->properties = IDP_CopyProperty(opptr->data);
|
||||
}
|
||||
|
||||
BLI_addtail(&ar->operators, oli);
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
}
|
||||
|
||||
void add_to_custom_panel_menu(bContext *C, uiLayout *layout, void *arg1)
|
||||
{
|
||||
ARegion *ar;
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
PanelType *pt;
|
||||
PropertyRNA *prop;
|
||||
wmOperatorType *optype = (wmOperatorType*)arg1;
|
||||
|
||||
ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
|
||||
if (ar == NULL) return;
|
||||
|
||||
for (pt = ar->type->paneltypes.first; pt; pt = pt->next) {
|
||||
if(strcmp(pt->context, context) == 0
|
||||
// && pt->space_type == sa->type->spaceid
|
||||
// && pt->region_type == RGN_TYPE_TOOLS
|
||||
&& pt->flag & PNL_CUSTOM_PANELTYPE) {
|
||||
|
||||
PointerRNA op_ptr = uiItemFullO(layout, "WM_OT_add_to_custom_panel", pt->label, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS);
|
||||
|
||||
prop = RNA_struct_find_property(&op_ptr, "COPY_idname");
|
||||
RNA_property_string_set(&op_ptr, prop, optype->idname);
|
||||
|
||||
prop = RNA_struct_find_property(&op_ptr, "COPY_paneltypeid");
|
||||
RNA_property_string_set(&op_ptr, prop, pt->idname);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int wm_create_custom_panel_poll(bContext *C)
|
||||
{
|
||||
ScrArea *sa;
|
||||
ARegion *ar;
|
||||
|
||||
if (CTX_wm_window(C) == NULL)
|
||||
return 0;
|
||||
|
||||
sa = CTX_wm_area(C);
|
||||
ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
|
||||
return (ar != NULL);
|
||||
}
|
||||
|
||||
static int wm_create_custom_panel_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar;
|
||||
PanelType *pt_iter;
|
||||
char *name = NULL;
|
||||
int name_taken = 1;
|
||||
|
||||
// find RGN_TYPE_TOOLS
|
||||
ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
if (ar == NULL) return OPERATOR_CANCELLED;
|
||||
|
||||
// find new name for paneltype
|
||||
for (int i=0; i < MAX_CUSTOM_PANELS; i++) {
|
||||
// generate name
|
||||
name = BLI_sprintfN("custom panel %i", i);
|
||||
name_taken = 0;
|
||||
// see if it is taken
|
||||
for (pt_iter = ar->type->paneltypes.first; pt_iter; pt_iter = pt_iter->next) {
|
||||
if (strcmp(pt_iter->idname, name) == 0) {
|
||||
name_taken = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// clear if taken
|
||||
if(name_taken) {
|
||||
MEM_freeN(name);
|
||||
continue;
|
||||
} else {
|
||||
// name the new panel type if not taken
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've run out of names (too many custom panels)
|
||||
if (name_taken)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
uiCreateCustomPanelType(sa, ar, CTX_data_mode_string(C), name, "Custom Panel");
|
||||
|
||||
MEM_freeN(name);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void WM_OT_create_custom_panel(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Create Custom Panel";
|
||||
ot->idname = "WM_OT_create_custom_panel";
|
||||
ot->description = "Create a custom panel in the current region's toolbar";
|
||||
|
||||
ot->exec = wm_create_custom_panel_exec;
|
||||
ot->poll = wm_create_custom_panel_poll;
|
||||
}
|
||||
|
||||
static int wm_add_to_custom_panel_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
// get operator properties: paneltype idname, property name
|
||||
PropertyRNA *prop;
|
||||
char *idname = NULL, *panelid = NULL;
|
||||
ARegion *ar;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
Panel *pa;
|
||||
wmOperatorType *ot;
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "COPY_idname");
|
||||
if(prop == NULL) return OPERATOR_CANCELLED;
|
||||
idname = RNA_property_string_get_alloc(op->ptr, prop, NULL, 0, NULL);
|
||||
|
||||
ot = WM_operatortype_find(idname, 1);
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "COPY_paneltypeid");
|
||||
if(prop == NULL) return OPERATOR_CANCELLED;
|
||||
panelid = RNA_property_string_get_alloc(op->ptr, prop, NULL, 0, NULL);
|
||||
|
||||
// get panel
|
||||
ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
if (pa->type && strcmp(pa->type->idname, panelid) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pa == NULL) {
|
||||
MEM_freeN(idname);
|
||||
MEM_freeN(panelid);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
// This shouldn't be necessary, already checked in the dragg poll
|
||||
if (uiOperatorListItemPresent(&pa->operators, idname, op->ptr->data, CTX_data_mode_string(C))) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
uiPanelAddOperator(C, pa, ot, op->ptr);
|
||||
|
||||
MEM_freeN(idname);
|
||||
MEM_freeN(panelid);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int wm_add_to_custom_panel_poll(bContext *UNUSED(C))
|
||||
{
|
||||
// TODO: what are the necessary conditions?
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void WM_OT_add_to_custom_panel(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name = "Add to Custom Panel";
|
||||
ot->idname = "WM_OT_add_to_custom_panel";
|
||||
ot->description = "Add the selected operator to the custom panel";
|
||||
|
||||
// ot->invoke = wm_create_custom_panel_invoke;
|
||||
ot->exec = wm_add_to_custom_panel_exec;
|
||||
ot->poll = wm_add_to_custom_panel_poll;
|
||||
|
||||
ot->flag |= OPTYPE_INTERNAL;
|
||||
|
||||
prop = RNA_def_string(ot->srna, "COPY_idname", "", OP_MAX_TYPENAME, "Operator to add", "The operator id to add to the panel");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE | PROP_REQUIRED);
|
||||
|
||||
prop = RNA_def_string(ot->srna, "COPY_paneltypeid", "", OP_MAX_TYPENAME, "idname of PanelType", "idname of the PanelType to add the operator to");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE | PROP_REQUIRED);
|
||||
|
||||
prop = RNA_def_int(ot->srna, "COPY_opcontext", 0, 0, 0, "Operator context", "The original opcontext that was set for the button", 0, 0);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE | PROP_REQUIRED);
|
||||
|
||||
}
|
||||
|
||||
static int wm_menubar_add_dragged_operator_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
char *idname = NULL;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_MENU_BAR);
|
||||
wmOperatorType *ot;
|
||||
|
||||
if (ar == NULL) return OPERATOR_CANCELLED;
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "COPY_idname");
|
||||
if(prop == NULL) return OPERATOR_CANCELLED;
|
||||
idname = RNA_property_string_get_alloc(op->ptr, prop, NULL, 0, NULL);
|
||||
|
||||
ot = WM_operatortype_find(idname, 1);
|
||||
|
||||
add_to_icon_shelf(C, ot, op->ptr);
|
||||
|
||||
MEM_freeN(idname);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int wm_menubar_add_dragged_operator_poll(bContext *UNUSED(C))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void WM_OT_menubar_add_dragged_operator(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name = "Add Operator to Menubar";
|
||||
ot->idname = "WM_OT_menubar_add_dragged_operator";
|
||||
ot->description = "Add the dragged operator to the current menubar";
|
||||
|
||||
ot->exec = wm_menubar_add_dragged_operator_exec;
|
||||
ot->poll = wm_menubar_add_dragged_operator_poll;
|
||||
|
||||
ot->flag = OPTYPE_INTERNAL;
|
||||
|
||||
prop = RNA_def_string(ot->srna, "COPY_idname", "", MAX_NAME, "Operator Name", "The name of the operator to add");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE | PROP_REQUIRED);
|
||||
prop = RNA_def_int(ot->srna, "COPY_opcontext", 0, 0, 0, "Operator context", "The original opcontext that was set for the button", 0, 0);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE | PROP_REQUIRED);
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************* */
|
||||
/* called on initialize WM_exit() */
|
||||
void wm_operatortype_free(void)
|
||||
@@ -4177,6 +4472,9 @@ void wm_operatortype_init(void)
|
||||
WM_operatortype_append(WM_OT_call_menu);
|
||||
WM_operatortype_append(WM_OT_radial_control);
|
||||
WM_operatortype_append(WM_OT_ndof_sensitivity_change);
|
||||
WM_operatortype_append(WM_OT_create_custom_panel);
|
||||
WM_operatortype_append(WM_OT_add_to_custom_panel);
|
||||
WM_operatortype_append(WM_OT_menubar_add_dragged_operator);
|
||||
#if defined(WIN32)
|
||||
WM_operatortype_append(WM_OT_console_toggle);
|
||||
#endif
|
||||
|
@@ -992,7 +992,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
|
||||
/* try to get icon type from extension */
|
||||
icon = ED_file_extension_icon((char *)stra->strings[a]);
|
||||
|
||||
WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0);
|
||||
WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, NULL, 0);
|
||||
/* void poin should point to string, it makes a copy */
|
||||
break; /* only one drop element supported now */
|
||||
}
|
||||
|
Reference in New Issue
Block a user