From b71749305a3b6db54f6676e87803703aa7acdebb Mon Sep 17 00:00:00 2001 From: Elia Sarti Date: Mon, 7 Dec 2009 21:51:44 +0000 Subject: [PATCH] Pythonazed DopeSheet and NLA editors headers UI. --- release/scripts/ui/space_dopesheet.py | 192 ++++++++++++++++++ release/scripts/ui/space_graph.py | 2 +- release/scripts/ui/space_nla.py | 170 ++++++++++++++++ .../editors/space_action/space_action.c | 21 +- source/blender/editors/space_nla/space_nla.c | 21 +- source/blender/makesrna/intern/rna_space.c | 45 ++-- 6 files changed, 400 insertions(+), 51 deletions(-) create mode 100644 release/scripts/ui/space_dopesheet.py create mode 100644 release/scripts/ui/space_nla.py diff --git a/release/scripts/ui/space_dopesheet.py b/release/scripts/ui/space_dopesheet.py new file mode 100644 index 00000000000..520d8283ae9 --- /dev/null +++ b/release/scripts/ui/space_dopesheet.py @@ -0,0 +1,192 @@ +# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy + + +class DOPESHEET_HT_header(bpy.types.Header): + bl_space_type = 'DOPESHEET_EDITOR' + + def draw(self, context): + layout = self.layout + + st = context.space_data + + row = layout.row(align=True) + row.template_header() + + if context.area.show_menus: + sub = row.row(align=True) + + sub.menu("DOPESHEET_MT_view") + sub.menu("DOPESHEET_MT_select") + + if st.mode == 'DOPESHEET' or (st.mode == 'ACTION' and st.action != None): + sub.menu("DOPESHEET_MT_channel") + elif st.mode == 'GPENCIL': + # gpencil Channel menu + pass + + if st.mode != 'GPENCIL': + sub.menu("DOPESHEET_MT_key") + + layout.prop(st, "mode", text="") + layout.prop(st.dopesheet, "display_summary", text="Summary") + + if st.mode == 'DOPESHEET': + layout.template_dopesheet_filter(st.dopesheet) + elif st.mode == 'ACTION': + layout.template_ID(st, "action", "action.new") + + if st.mode != 'GPENCIL': + layout.prop(st, "autosnap", text="") + + row = layout.row(align=True) + row.operator("action.copy", text="", icon='ICON_COPYDOWN') + row.operator("action.paste", text="", icon='ICON_PASTEDOWN') + + +class DOPESHEET_MT_view(bpy.types.Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + + st = context.space_data + + layout.column() + + layout.prop(st, "show_cframe_indicator") + layout.prop(st, "show_sliders") + layout.prop(st, "automerge_keyframes") + + if st.show_seconds: + layout.operator("anim.time_toggle", text="Show Frames") + else: + layout.operator("anim.time_toggle", text="Show Seconds") + + layout.separator() + layout.operator("anim.previewrange_set") + layout.operator("anim.previewrange_clear") + layout.operator("action.previewrange_set") + + layout.separator() + layout.operator("action.frame_jump") + layout.operator("action.view_all") + + layout.separator() + layout.operator("screen.area_dupli") + layout.operator("screen.screen_full_area") + + +class DOPESHEET_MT_select(bpy.types.Menu): + bl_label = "Select" + + def draw(self, context): + layout = self.layout + + layout.column() + # This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None + layout.operator("action.select_all_toggle") + layout.operator("action.select_all_toggle", text="Invert Selection").invert = True + + layout.separator() + layout.operator("action.select_border") + layout.operator("action.select_border", text="Border Axis Range").axis_range = True + + layout.separator() + layout.operator("action.select_column", text="Columns on Selected Keys").mode = 'KEYS' + layout.operator("action.select_column", text="Column on Current Frame").mode = 'CFRA' + + layout.operator("action.select_column", text="Columns on Selected Markers").mode = 'MARKERS_COLUMN' + layout.operator("action.select_column", text="Between Selected Markers").mode = 'MARKERS_BETWEEN' + + +class DOPESHEET_MT_channel(bpy.types.Menu): + bl_label = "Channel" + + def draw(self, context): + layout = self.layout + + layout.column() + layout.operator("anim.channels_setting_toggle") + layout.operator("anim.channels_setting_enable") + layout.operator("anim.channels_setting_disable") + + layout.separator() + layout.operator("anim.channels_editable_toggle") + + layout.separator() + layout.operator("anim.channels_expand") + layout.operator("anim.channels_collapse") + + +class DOPESHEET_MT_key(bpy.types.Menu): + bl_label = "Key" + + def draw(self, context): + layout = self.layout + + layout.column() + layout.menu("DOPESHEET_MT_key_transform", text="Transform") + + layout.operator_menu_enum("action.snap", property="type", text="Snap") + layout.operator_menu_enum("action.mirror", property="type", text="Mirror") + + layout.separator() + # Inconsistent naming? act/action + layout.operator("act.keyframe_insert") + + layout.separator() + layout.operator("action.duplicate") + layout.operator("action.delete") + + layout.separator() + layout.operator_menu_enum("action.keyframe_type", property="type", text="Keyframe Type") + layout.operator_menu_enum("action.handle_type", property="type", text="Handle Type") + layout.operator_menu_enum("action.interpolation_type", property="type", text="Interpolation Mode") + layout.operator_menu_enum("action.extrapolation_type", property="type", text="Extrapolation Mode") + + layout.separator() + layout.operator("action.clean") + layout.operator("action.sample") + + layout.separator() + layout.operator("action.copy") + layout.operator("action.paste") + + +class DOPESHEET_MT_key_transform(bpy.types.Menu): + bl_label = "Transform" + + def draw(self, context): + layout = self.layout + + layout.column() + layout.operator("tfm.translate", text="Grab/Move") + layout.operator("tfm.transform", text="Extend").mode = 'TIME_EXTEND' + layout.operator("tfm.resize", text="Scale") + + +bpy.types.register(DOPESHEET_HT_header) # header/menu classes +bpy.types.register(DOPESHEET_MT_view) +bpy.types.register(DOPESHEET_MT_select) +bpy.types.register(DOPESHEET_MT_channel) +bpy.types.register(DOPESHEET_MT_key) +bpy.types.register(DOPESHEET_MT_key_transform) diff --git a/release/scripts/ui/space_graph.py b/release/scripts/ui/space_graph.py index 38f6b526e9a..0a7ae02df29 100644 --- a/release/scripts/ui/space_graph.py +++ b/release/scripts/ui/space_graph.py @@ -67,7 +67,7 @@ class GRAPH_MT_view(bpy.types.Menu): layout.column() layout.separator() - layout.operator("graph.properties") + layout.operator("graph.properties", icon="ICON_MENU_PANEL") layout.prop(st, "show_cframe_indicator") layout.prop(st, "show_cursor") diff --git a/release/scripts/ui/space_nla.py b/release/scripts/ui/space_nla.py new file mode 100644 index 00000000000..afd5e424b2d --- /dev/null +++ b/release/scripts/ui/space_nla.py @@ -0,0 +1,170 @@ +# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy + + +class NLA_HT_header(bpy.types.Header): + bl_space_type = 'NLA_EDITOR' + + def draw(self, context): + layout = self.layout + + st = context.space_data + + row = layout.row(align=True) + row.template_header() + + if context.area.show_menus: + sub = row.row(align=True) + + sub.menu("NLA_MT_view") + sub.menu("NLA_MT_select") + sub.menu("NLA_MT_edit") + sub.menu("NLA_MT_add") + + layout.template_dopesheet_filter(st.dopesheet) + + layout.prop(st, "autosnap", text="") + + +class NLA_MT_view(bpy.types.Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + + st = context.space_data + + layout.column() + + layout.operator("nla.properties", icon="ICON_MENU_PANEL") + + layout.separator() + layout.prop(st, "show_cframe_indicator") + + if st.show_seconds: + layout.operator("anim.time_toggle", text="Show Frames") + else: + layout.operator("anim.time_toggle", text="Show Seconds") + + layout.prop(st, "show_strip_curves") + + layout.separator() + layout.operator("anim.previewrange_set") + layout.operator("anim.previewrange_clear") + + layout.separator() + layout.operator("screen.area_dupli") + layout.operator("screen.screen_full_area") + + +class NLA_MT_select(bpy.types.Menu): + bl_label = "Select" + + def draw(self, context): + layout = self.layout + + layout.column() + # This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None + layout.operator("nla.select_all_toggle") + layout.operator("nla.select_all_toggle", text="Invert Selection").invert = True + + layout.separator() + layout.operator("nla.select_border") + layout.operator("nla.select_border", text="Border Axis Range").axis_range = True + + +class NLA_MT_edit(bpy.types.Menu): + bl_label = "Edit" + + def draw(self, context): + layout = self.layout + + layout.column() + layout.menu("NLA_MT_edit_transform", text="Transform") + + layout.operator_menu_enum("nla.snap", property="type", text="Snap") + + layout.separator() + layout.operator("nla.duplicate") + layout.operator("nla.split") + layout.operator("nla.delete") + + layout.separator() + layout.operator("nla.mute_toggle") + + layout.separator() + layout.operator("nla.apply_scale") + layout.operator("nla.clear_scale") + + layout.separator() + layout.operator("nla.move_up") + layout.operator("nla.move_down") + + """ + XXX not sure if we need this check and so scene.flag wrapped? + // TODO: names of these tools for 'tweakmode' need changing? + if (scene->flag & SCE_NLA_EDIT_ON) + uiItemO(layout, "Stop Tweaking Strip Actions", 0, "NLA_OT_tweakmode_exit"); + else + uiItemO(layout, "Start Tweaking Strip Actions", 0, "NLA_OT_tweakmode_enter"); + """ + layout.separator() + layout.operator("nla.tweakmode_exit") + layout.operator("nla.tweakmode_enter") + + +class NLA_MT_add(bpy.types.Menu): + bl_label = "Add" + + def draw(self, context): + layout = self.layout + + layout.column() + layout.operator("nla.actionclip_add") + layout.operator("nla.transition_add") + + layout.separator() + layout.operator("nla.meta_add") + layout.operator("nla.meta_remove") + + layout.separator() + layout.operator("nla.tracks_add") + layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True + + +class NLA_MT_edit_transform(bpy.types.Menu): + bl_label = "Transform" + + def draw(self, context): + layout = self.layout + + layout.column() + layout.operator("tfm.translate", text="Grab/Move") + layout.operator("tfm.transform", text="Extend").mode = 'TIME_EXTEND' + layout.operator("tfm.resize", text="Scale") + + +bpy.types.register(NLA_HT_header) # header/menu classes +bpy.types.register(NLA_MT_view) +bpy.types.register(NLA_MT_select) +bpy.types.register(NLA_MT_edit) +bpy.types.register(NLA_MT_add) +bpy.types.register(NLA_MT_edit_transform) diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index d4f8fcfb449..0bf3e3f70cb 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -259,29 +259,12 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void action_header_area_init(wmWindowManager *wm, ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + ED_region_header_init(ar); } static void action_header_area_draw(const bContext *C, ARegion *ar) { - float col[3]; - - /* clear */ - if(ED_screen_area_active(C)) - UI_GetThemeColor3fv(TH_HEADER, col); - else - UI_GetThemeColor3fv(TH_HEADERDESEL, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - action_header_buttons(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + ED_region_header(C, ar); } static void action_channel_area_listener(ARegion *ar, wmNotifier *wmn) diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index a019e684239..572ad44f680 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -331,29 +331,12 @@ static void nla_main_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void nla_header_area_init(wmWindowManager *wm, ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + ED_region_header_init(ar); } static void nla_header_area_draw(const bContext *C, ARegion *ar) { - float col[3]; - - /* clear */ - if(ED_screen_area_active(C)) - UI_GetThemeColor3fv(TH_HEADER, col); - else - UI_GetThemeColor3fv(TH_HEADERDESEL, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - nla_header_buttons(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + ED_region_header(C, ar); } /* add handlers, stuff you only do once or on area/region changes */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ef5f8ccb87b..4a55d259be9 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -83,6 +83,13 @@ static EnumPropertyItem transform_orientation_items[] = { {V3D_MANIP_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"}, {0, NULL, 0, NULL, NULL}}; +static EnumPropertyItem autosnap_items[] = { + {SACTSNAP_OFF, "NONE", 0, "None", ""}, + {SACTSNAP_STEP, "STEP", 0, "Step", "Snap to 1.0 frame/second intervals."}, + {SACTSNAP_FRAME, "FRAME", 0, "Frame", "Snap to actual frames/seconds (nla-action time)."}, + {SACTSNAP_MARKER, "MARKER", 0, "Marker", "Snap to nearest marker."}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" @@ -1262,8 +1269,19 @@ static void rna_def_space_dopesheet(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NOTRANSKEYCULL); RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Show handles of Bezier control points."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); - - // TODO... autosnap, dopesheet? + + /* dopesheet */ + prop= RNA_def_property(srna, "dopesheet", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "DopeSheet"); + RNA_def_property_pointer_sdna(prop, NULL, "ads"); + RNA_def_property_ui_text(prop, "DopeSheet", "Settings for filtering animation data."); + + /* autosnap */ + prop= RNA_def_property(srna, "autosnap", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "autosnap"); + RNA_def_property_enum_items(prop, autosnap_items); + RNA_def_property_ui_text(prop, "Auto Snap", "Automatic time snapping settings for transformations."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); } static void rna_def_space_graph(BlenderRNA *brna) @@ -1285,13 +1303,6 @@ static void rna_def_space_graph(BlenderRNA *brna) //{V3D_ACTIVE, "ACTIVE_ELEMENT", 0, "Active Element", ""}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem autosnap_items[] = { - {SACTSNAP_OFF, "NONE", 0, "None", ""}, - {SACTSNAP_STEP, "STEP", 0, "Step", "Snap to 1.0 frame/second intervals."}, - {SACTSNAP_FRAME, "FRAME", 0, "Frame", "Snap to actual frames/seconds (nla-action time)."}, - {SACTSNAP_MARKER, "MARKER", 0, "Marker", "Snap to nearest marker."}, - {0, NULL, 0, NULL, NULL}}; - srna= RNA_def_struct(brna, "SpaceGraphEditor", "Space"); RNA_def_struct_sdna(srna, "SpaceIpo"); @@ -1398,9 +1409,19 @@ static void rna_def_space_nla(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NOSTRIPCURVES); RNA_def_property_ui_text(prop, "Show Control Curves", "Show influence curves on strips."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NLA, NULL); - - /* editing */ - // TODO... autosnap, dopesheet? + + /* dopesheet */ + prop= RNA_def_property(srna, "dopesheet", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "DopeSheet"); + RNA_def_property_pointer_sdna(prop, NULL, "ads"); + RNA_def_property_ui_text(prop, "DopeSheet", "Settings for filtering animation data."); + + /* autosnap */ + prop= RNA_def_property(srna, "autosnap", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "autosnap"); + RNA_def_property_enum_items(prop, autosnap_items); + RNA_def_property_ui_text(prop, "Auto Snap", "Automatic time snapping settings for transformations."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NLA, NULL); } static void rna_def_space_time(BlenderRNA *brna)