Commit: 91d0f6f1139054abcfca3d8044eae6e2bb82fb9a
Author: Julian Eisel
Date:   Fri Mar 6 17:21:34 2015 +0100
Branches: gooseberry
https://developer.blender.org/rB91d0f6f1139054abcfca3d8044eae6e2bb82fb9a

Modifier Drag&Drop

**Warning: WIP!** Basic functionality works fine and there shouldn't be any 
crashes, however, if you occur issues, feel free to report them to me (not in 
the bug tracker!)

Some more effort is needed to get this ready for master, but I thought it would 
be nice as a little present for the Gooseberry-team (I heard some of you were 
requesting this?) and the ones using the Gooseberry-builds :)

Oh, and better not look at that code, it's ugly and a lot of changes are 
planned, I just wanted to get something working before getting into details.

===================================================================

M       release/scripts/startup/bl_ui/properties_data_modifier.py
M       source/blender/editors/include/UI_interface.h
M       source/blender/editors/interface/interface.c
M       source/blender/editors/interface/interface_handlers.c
M       source/blender/editors/interface/interface_intern.h
M       source/blender/editors/interface/interface_layout.c
M       source/blender/editors/interface/interface_panel.c
M       source/blender/editors/interface/interface_templates.c
M       source/blender/editors/interface/interface_utils.c
M       source/blender/editors/interface/interface_widgets.c
M       source/blender/editors/mesh/editmesh_select.c
M       source/blender/makesrna/intern/rna_ui_api.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py 
b/release/scripts/startup/bl_ui/properties_data_modifier.py
index f530a05..9c9c42b 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -40,10 +40,12 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         layout.operator_menu_enum("object.modifier_add", "type")
 
         for md in ob.modifiers:
+            layout.subblock_begin(md.name)
             box = layout.template_modifier(md)
             if box:
                 # match enum type to our functions, avoids a lookup table.
                 getattr(self, md.type)(box, ob, md)
+            layout.subblock_end()
 
     # the mt.type enum is (ab)used for a lookup on function names
     # ...to avoid lengthy if statements
diff --git a/source/blender/editors/include/UI_interface.h 
b/source/blender/editors/include/UI_interface.h
index 154554a..3716fe7 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -144,6 +144,7 @@ enum {
 
 #define UI_BLOCK_LIST_ITEM   (1 << 19)
 #define UI_BLOCK_RADIAL      (1 << 20)
+#define UI_BLOCK_DRAGGABLE   (1 << 21)
 
 /* uiPopupBlockHandle->menuretval */
 #define UI_RETURN_CANCEL     (1 << 0)   /* cancel all menus cascading */
@@ -823,6 +824,8 @@ enum {
 uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int 
size, int em, int padding, struct uiStyle *style);
 void UI_block_layout_set_current(uiBlock *block, uiLayout *layout);
 void UI_block_layout_resolve(uiBlock *block, int *x, int *y);
+void uiLayoutSubblockBegin(uiLayout *layout, const char *identifier);
+void uiLayoutSubblockEnd(uiLayout *layout);
 
 uiBlock *uiLayoutGetBlock(uiLayout *layout);
 
@@ -1023,6 +1026,9 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut 
**but_p);
 bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut 
*but_src);
 void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p);
 
+/* UI_subblock_ helplers */
+bool UI_subblock_is_dragging(uiBlock *block);
+
 
 /* Float precision helpers */
 #define UI_PRECISION_FLOAT_MAX 7
diff --git a/source/blender/editors/interface/interface.c 
b/source/blender/editors/interface/interface.c
index bad09a7..2056269 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1188,6 +1188,16 @@ void UI_block_update_from_old(const bContext *C, uiBlock 
*block)
        block->auto_open_last = block->oldblock->auto_open_last;
        block->tooltipdisabled = block->oldblock->tooltipdisabled;
        BLI_movelisttolist(&block->color_pickers.list, 
&block->oldblock->color_pickers.list);
+       /* sub-block drag & drop data */
+       if (UI_subblock_is_dragging(block->oldblock)) {
+               block->subblock.drag_state = 
block->oldblock->subblock.drag_state;
+               block->subblock.rect = block->oldblock->subblock.rect;
+               block->subblock.rect_above = 
block->oldblock->subblock.rect_above;
+               block->subblock.rect_below = 
block->oldblock->subblock.rect_below;
+               copy_v2_v2_int(block->subblock.click_xy, 
block->oldblock->subblock.click_xy);
+               copy_v2_v2_int(block->subblock.drag_xy_prev, 
block->oldblock->subblock.drag_xy_prev);
+               BLI_strncpy(block->subblock.dragged_subblock, 
block->oldblock->subblock.dragged_subblock, MAX_NAME);
+       }
 
        block->oldblock = NULL;
 }
@@ -1319,10 +1329,25 @@ static void ui_but_to_pixelrect(rcti *rect, const 
ARegion *ar, uiBlock *block, u
        rect->ymax = floorf(rectf.ymax);
 }
 
+static void ui_but_draw(const bContext *C, ARegion *ar, uiStyle *style, uiBut 
*but, rcti *rect)
+{
+       /* XXX: figure out why invalid coordinates happen when closing render 
window */
+       /* and material preview is redrawn in main window (temp fix for bug 
#23848) */
+       if (rect->xmin < rect->xmax && rect->ymin < rect->ymax)
+               ui_draw_but(C, ar, style, but, rect);
+}
+
+static bool ui_subblock_is_but_dragged(uiBlock *block, uiBut *but)
+{
+       return (but->subblock_id[0] && STREQ(but->subblock_id, 
block->subblock.dragged_subblock));
+}
+
+#include "BIF_glutil.h"
 /* uses local copy of style, to scale things down, and allow widgets to change 
stuff */
 void UI_block_draw(const bContext *C, uiBlock *block)
 {
        uiStyle style = *UI_style_get_dpi();  /* XXX pass on as arg */
+       wmWindow *win = CTX_wm_window(C);
        ARegion *ar;
        uiBut *but;
        rcti rect;
@@ -1370,17 +1395,59 @@ void UI_block_draw(const bContext *C, uiBlock *block)
        else if (block->panel)
                ui_draw_aligned_panel(&style, block, &rect, 
UI_panel_category_is_visible(ar));
 
-       /* widgets */
+       /********** widgets **********/
+
+       /* first pass: draw not-dragged widgets */
        for (but = block->buttons.first; but; but = but->next) {
                if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) {
                        ui_but_to_pixelrect(&rect, ar, block, but);
-               
-                       /* XXX: figure out why invalid coordinates happen when 
closing render window */
-                       /* and material preview is redrawn in main window (temp 
fix for bug #23848) */
-                       if (rect.xmin < rect.xmax && rect.ymin < rect.ymax)
-                               ui_draw_but(C, ar, &style, but, &rect);
+
+                       if (UI_subblock_is_dragging(block)) {
+                               if (ui_subblock_is_but_dragged(block, but)) {
+                                       continue;
+                               }
+                       }
+
+                       ui_but_draw(C, ar, &style, but, &rect);
+               }
+       }
+
+       /* second pass: draw dragged widgets above others */
+       if (UI_subblock_is_dragging(block)) {
+               int mx = win->eventstate->x, my = win->eventstate->y;
+               int drag_ofs_y = my - block->subblock.drag_xy_prev[1];
+               int ofs = 0;
+
+               ui_window_to_block(ar, block, &mx, &my);
+               ofs = block->subblock.click_xy[1] - (my - 
(block->subblock.rect.ymin + drag_ofs_y));
+
+               for (but = block->buttons.first; but; but = but->next) {
+                       if (ui_subblock_is_but_dragged(block, but) &&
+                           !(but->flag & (UI_HIDDEN | UI_SCROLLED)))
+                       {
+                               ui_but_to_pixelrect(&rect, ar, block, but);
+                               BLI_rcti_translate(&rect, 0, drag_ofs_y - ofs);
+
+                               ui_but_draw(C, ar, &style, but, &rect);
+                       }
                }
+               BLI_rctf_translate(&block->subblock.rect, 0, drag_ofs_y - ofs);
+       }
+
+#if 0 /* debugging - draw border around sub-blocks */
+       if (UI_subblock_is_dragging(block)) {
+               rctf rectf = block->subblock.rect;
+               
+               ui_block_to_window_rctf(ar, block, &rectf, 
&block->subblock.rect);
+               
+               rectf.xmin -= ar->winrct.xmin;
+               rectf.ymin -= ar->winrct.ymin;
+               rectf.xmax -= ar->winrct.xmin;
+               rectf.ymax -= ar->winrct.ymin;
+
+               fdrawbox(rectf.xmin, rectf.ymin, rectf.xmax, rectf.ymax);
        }
+#endif
        
        /* restore matrix */
        glMatrixMode(GL_PROJECTION);
@@ -2541,6 +2608,10 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
                        oldblock->active = 0;
                        oldblock->panel = NULL;
                        oldblock->handle = NULL;
+
+                       if (UI_subblock_is_dragging(oldblock)) {
+                               block->rect = oldblock->rect;
+                       }
                }
 
                /* at the beginning of the list! for dynamical menus/blocks */
@@ -3122,6 +3193,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int 
retval, const char *str,
        
        but->pos = -1;   /* cursor invisible */
 
+       if (block->subblock.is_subblock_building) {
+               BLI_strncpy(but->subblock_id, 
block->subblock.subblock_id[block->subblock.tot_subblocks], MAX_NAME);
+       }
+
        if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {    /* add a 
space to name */
                /* slen remains unchanged from previous assignment, ensure this 
stays true */
                if (slen > 0 && slen < UI_MAX_NAME_STR - 2) {
diff --git a/source/blender/editors/interface/interface_handlers.c 
b/source/blender/editors/interface/interface_handlers.c
index 9697319..6179ab1 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -110,6 +110,9 @@
 /* This hack is needed because we don't have a good way to re-reference keymap 
items once added: T42944 */
 #define USE_KEYMAP_ADD_HACK
 
+static int ui_region_handler(bContext *C, const wmEvent *event, void 
*UNUSED(userdata));
+static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata));
+
 /* proto */
 static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to);
 static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to);
@@ -7901,6 +7904,160 @@ static int ui_handle_list_event(bContext *C, const 
wmEvent *event, ARegion *ar)
        return retval;
 }
 
+static rctf UI_subblock_boundbox_set(uiBlock *block, const char *subblock_id)
+{
+       uiBut *but;
+       rctf rect;
+
+       if (subblock_id && subblock_id[0]) {
+               for (but = block->buttons.first; but; but = but->next) {
+                       if (but->subblock_id[0] && STREQ(but->subblock_id, 
subblock_id)) {
+                               if (BLI_rctf_is_empty(&rect)) {
+                                       rect = but->rect;
+                               }
+                               BLI_rctf_union(&rect, &but->rect);
+                       }
+               }
+       }
+       else {
+               /* return empty rect */
+               rect.xmin = rect.xmax = rect.ymin = rect.ymax = 0;
+       }
+       return rect;
+}
+
+static char *UI_subblock_get_prev_id(uiBlock *block, const char *subblock_id)
+{
+       int i;
+
+       for (i = 1; i < block->subblock.tot_subblocks; i++) {
+               if (STREQ(block->subblock.subblock_id[i], subblock_id)) {
+                       if (block->subblock.subblock_id[i - 1] && 
block->subblock.subblock_id[i - 1][0]) {
+                               return block->subblock.subblock_id[i - 1];
+                       }
+               }
+       }
+       return NULL;
+}
+
+static char *UI_subblock_get_next_id(uiBlock *block, const char *subblock_id)
+{
+       int i;
+
+       for (i = 0; i < block->subblock.tot_subblocks; i++) {
+               if (STREQ(block->subblock.subblock_id[i], subblock_id)) {
+                       if (block->subblock.subblock_id[i + 1] && 
block->subblock.subblock_id[i + 1][0]) {
+                               return block->subblock.subblock_id[i + 1];
+                       }
+               }
+       }
+       return NULL;
+}
+
+static void UI_subblock_neighbours_rects_set(uiBlock *block, const char 
*subblock_id)
+{
+       block->subblock.rect_above = UI_subblock_boundbox_set(block, 
UI_subblock_get_prev_id(block, subblock_id));
+       block->subblock.rect_below = UI_subblock_boundbox_set(block, 
UI_subblock_get_next_id(block, subblock_id));
+}
+
+static int ui_subblock_handler(bContext *C, const wmEvent *event, void 
*userdata)
+{
+       uiBut *but = (uiBut *)userdata;
+       uiBlock *block = but->block;
+
+       if (UI_subblock_is_dragging(block) == false)
+               return WM_UI_HANDLER_CONTINUE;
+
+       if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+               wmWindow *win = CTX_wm_window(C);
+               ARegion *ar = CTX_wm_region(C);
+
+               block->subb

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to