Commit: def5999f9b04368aa21485b514c0931f6fb43d8e
Author: Campbell Barton
Date:   Wed Apr 2 18:42:08 2014 +1100
https://developer.blender.org/rBdef5999f9b04368aa21485b514c0931f6fb43d8e

UI: support for dragging popups title area

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

M       source/blender/editors/include/ED_screen.h
M       source/blender/editors/interface/interface_handlers.c
M       source/blender/editors/interface/interface_intern.h
M       source/blender/editors/screen/area.c
M       source/blender/windowmanager/intern/wm_subwindow.c
M       source/blender/windowmanager/wm_subwindow.h

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

diff --git a/source/blender/editors/include/ED_screen.h 
b/source/blender/editors/include/ED_screen.h
index 5e20734..1d1777a 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -55,6 +55,7 @@ void    ED_region_do_draw(struct bContext *C, struct ARegion 
*ar);
 void    ED_region_exit(struct bContext *C, struct ARegion *ar);
 void    ED_region_pixelspace(struct ARegion *ar);
 void    ED_region_set(const struct bContext *C, struct ARegion *ar);
+void    ED_region_update_rect(struct bContext *C, struct ARegion *ar);
 void    ED_region_init(struct bContext *C, struct ARegion *ar);
 void    ED_region_tag_redraw(struct ARegion *ar);
 void    ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct);
diff --git a/source/blender/editors/interface/interface_handlers.c 
b/source/blender/editors/interface/interface_handlers.c
index 5a520a6..e7c9900 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -96,6 +96,9 @@
 /* so we can avoid very small mouse-moves from jumping away from keyboard 
navigation [#34936] */
 #define USE_KEYNAV_LIMIT
 
+/* drag popups by their header */
+#define USE_DRAG_POPUP
+
 /* proto */
 static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
 static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
@@ -7862,13 +7865,14 @@ static int ui_handle_menu_button(bContext *C, const 
wmEvent *event, uiPopupBlock
 }
 
 static int ui_handle_menu_event(bContext *C, const wmEvent *event, 
uiPopupBlockHandle *menu,
-                                int level, const bool is_parent_inside)
+                                int level, const bool is_parent_inside, const 
bool is_floating)
 {
        ARegion *ar;
        uiBlock *block;
        uiBut *but, *bt;
        int mx, my, retval;
        bool inside;
+       bool inside_title;  /* check for title dragging */
 
        ar = menu->region;
        block = ar->uiblocks.first;
@@ -7881,10 +7885,35 @@ static int ui_handle_menu_event(bContext *C, const 
wmEvent *event, uiPopupBlockH
 
        /* check if mouse is inside block */
        inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+       inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.xmax);
 
        /* if there's an active modal button, don't check events or outside, 
except for search menu */
        but = ui_but_find_activated(ar);
 
+#ifdef USE_DRAG_POPUP
+       if (menu->is_grab) {
+               if (event->type == LEFTMOUSE) {
+                       menu->is_grab = false;
+               }
+               else {
+                       if (event->type == MOUSEMOVE) {
+                               int mdiff[2];
+
+                               sub_v2_v2v2_int(mdiff, &event->x, 
menu->grab_xy_prev);
+                               copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+
+                               BLI_rcti_translate(&ar->winrct, UNPACK2(mdiff));
+
+                               ED_region_update_rect(C, ar);
+
+                               ED_region_tag_redraw(ar);
+                       }
+
+                       return retval;
+               }
+       }
+#endif
+
        if (but && button_modal_state(but->active->state)) {
                if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
                        /* if a button is activated modal, always reset the 
start mouse
@@ -8220,6 +8249,16 @@ static int ui_handle_menu_event(bContext *C, const 
wmEvent *event, uiPopupBlockH
                                if (!ui_but_find_activated(ar))
                                        menu->menuretval = UI_RETURN_CANCEL | 
UI_RETURN_POPUP_OK;
                        }
+#ifdef USE_DRAG_POPUP
+                       else if ((event->type == LEFTMOUSE) && (event->val == 
KM_PRESS) &&
+                                (inside && is_floating && inside_title))
+                       {
+                               if (!ui_but_find_activated(ar)) {
+                                       menu->is_grab = true;
+                                       copy_v2_v2_int(menu->grab_xy_prev, 
&event->x);
+                               }
+                       }
+#endif
                        else {
 
                                /* check mouse moving outside of the menu */
@@ -8328,7 +8367,7 @@ static int ui_handle_menu_return_submenu(bContext *C, 
const wmEvent *event, uiPo
 }
 
 static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, 
uiPopupBlockHandle *menu,
-                                     int level, const bool is_parent_inside)
+                                     int level, const bool is_parent_inside, 
const bool is_floating)
 {
        uiBut *but;
        uiHandleButtonData *data;
@@ -8354,7 +8393,7 @@ static int ui_handle_menus_recursive(bContext *C, const 
wmEvent *event, uiPopupB
                        inside = BLI_rctf_isect_pt(&block->rect, mx, my);
                }
 
-               retval = ui_handle_menus_recursive(C, event, submenu, level + 
1, is_parent_inside || inside);
+               retval = ui_handle_menus_recursive(C, event, submenu, level + 
1, is_parent_inside || inside, false);
        }
 
        /* now handle events for our own menu */
@@ -8387,7 +8426,7 @@ static int ui_handle_menus_recursive(bContext *C, const 
wmEvent *event, uiPopupB
                        }
                }
                else {
-                       retval = ui_handle_menu_event(C, event, menu, level, 
is_parent_inside);
+                       retval = ui_handle_menu_event(C, event, menu, level, 
is_parent_inside, is_floating);
                }
        }
 
@@ -8484,7 +8523,7 @@ static int ui_handler_region_menu(bContext *C, const 
wmEvent *event, void *UNUSE
                        /* handle events for menus and their buttons 
recursively,
                         * this will handle events from the top to the bottom 
menu */
                        if (data->menu)
-                               retval = ui_handle_menus_recursive(C, event, 
data->menu, 0, false);
+                               retval = ui_handle_menus_recursive(C, event, 
data->menu, 0, false, false);
 
                        /* handle events for the activated button */
                        if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) 
||
@@ -8530,7 +8569,7 @@ static int ui_handler_popup(bContext *C, const wmEvent 
*event, void *userdata)
                retval = WM_UI_HANDLER_CONTINUE;
        }
 
-       ui_handle_menus_recursive(C, event, menu, 0, false);
+       ui_handle_menus_recursive(C, event, menu, 0, false, true);
 
        /* free if done, does not free handle itself */
        if (menu->menuretval) {
diff --git a/source/blender/editors/interface/interface_intern.h 
b/source/blender/editors/interface/interface_intern.h
index 2c6486b..bb32135 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -460,6 +460,11 @@ struct uiPopupBlockHandle {
 
        /* menu direction */
        int direction;
+
+/* #ifdef USE_DRAG_POPUP */
+       bool is_grab;
+       int     grab_xy_prev[2];
+/* #endif */
 };
 
 uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, 
void *arg_but);
diff --git a/source/blender/editors/screen/area.c 
b/source/blender/editors/screen/area.c
index f62166d..1efd3cc 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -408,7 +408,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
        /* see BKE_spacedata_draw_locks() */
        if (at->do_lock)
                return;
-       
+
        /* if no partial draw rect set, full rect */
        if (ar->drawrct.xmin == ar->drawrct.xmax) {
                ar->drawrct = ar->winrct;
@@ -1312,6 +1312,27 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow 
*win, ScrArea *sa)
        }
 }
 
+static void region_update_rect(ARegion *ar)
+{
+       ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
+       ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+
+       /* v2d mask is used to subtract scrollbars from a 2d view. Needs 
initialize here. */
+       BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+}
+
+/**
+ * Call to move a popup window (keep OpenGL context free!)
+ */
+void ED_region_update_rect(bContext *C, ARegion *ar)
+{
+       wmWindow *win = CTX_wm_window(C);
+
+       wm_subwindow_rect_set(win, ar->swinid, &ar->winrct);
+
+       region_update_rect(ar);
+}
+
 /* externally called for floating regions like menus */
 void ED_region_init(bContext *C, ARegion *ar)
 {
@@ -1320,11 +1341,7 @@ void ED_region_init(bContext *C, ARegion *ar)
        /* refresh can be called before window opened */
        region_subwindow(CTX_wm_window(C), ar);
        
-       ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
-       ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
-       
-       /* v2d mask is used to subtract scrollbars from a 2d view. Needs 
initialize here. */
-       BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+       region_update_rect(ar);
 
        /* UI convention */
        wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c 
b/source/blender/windowmanager/intern/wm_subwindow.c
index 1c20fe3..ecf22fe 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -180,6 +180,20 @@ void wm_subwindow_rect_get(wmWindow *win, int swinid, rcti 
*r_rect)
 }
 
 
+static void wm_swin_rect_set(wmSubWindow *swin, const rcti *rect)
+{
+       swin->winrct = *rect;
+}
+void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect)
+{
+       wmSubWindow *swin = swin_from_swinid(win, swinid);
+
+       if (swin) {
+               wm_swin_rect_set(swin, rect);
+       }
+}
+
+
 /* always sets pixel-precise 2D window/view matrices */
 /* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big 
*/
 int wm_subwindow_open(wmWindow *win, const rcti *winrct)
diff --git a/source/blender/windowmanager/wm_subwindow.h 
b/source/blender/windowmanager/wm_subwindow.h
index c1d0f9a..bf7b994 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -46,6 +46,7 @@ void  wm_subwindow_size_get(wmWindow *win, int swinid, int 
*x, int *y);
 void   wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y);
 void   wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4]);
 void   wm_subwindow_rect_get(wmWindow *win, int swinid, struct rcti *r_rect);
+void    wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect);
 
 unsigned int index_to_framebuffer(int index);

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

Reply via email to