diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-01-25 08:28:06 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-01-25 08:32:43 +0300 |
commit | 38dafd5f44a07b4937ca53cf67cce4093d5797f7 (patch) | |
tree | 02612f48da66659340d3fd5b7ebd514502fd8e29 | |
parent | 032129ef3527424de241f381376a3b94a2247965 (diff) | |
parent | 693b41eb17557ba12e7c64c5ba589c499ff45c4d (diff) |
Merge branch 'master' into blender2.8
15 files changed, 202 insertions, 112 deletions
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 6bd88099792..754f59d2e33 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -429,6 +429,9 @@ void BKE_screen_free(bScreen *sc) BLI_freelistN(&sc->areabase); BKE_previewimg_free(&sc->preview); + + /* Region and timer are freed by the window manager. */ + MEM_SAFE_FREE(sc->tool_tip); } /* for depsgraph */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2cb799d39b9..236b14af8b0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6667,6 +6667,7 @@ static void lib_link_screen(FileData *fd, Main *main) sc->scene = newlibadr(fd, sc->id.lib, sc->scene); sc->animtimer = NULL; /* saved in rare cases */ + sc->tool_tip = NULL; sc->scrubbing = false; for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 5d7a45a7e48..6e09318314d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1105,6 +1105,8 @@ void UI_context_active_but_prop_get_templateID( struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop); +uiBut *UI_region_active_but_get(struct ARegion *ar); + /* Styled text draw */ void UI_fontstyle_set(const struct uiFontStyle *fs); void UI_fontstyle_draw_ex(const struct uiFontStyle *fs, const struct rcti *rect, const char *str, @@ -1151,7 +1153,7 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p); /* ui_interface_region_tooltip.c */ struct ARegion *UI_tooltip_create_from_button(struct bContext *C, struct ARegion *butregion, uiBut *but); struct ARegion *UI_tooltip_create_from_manipulator(struct bContext *C, struct wmManipulator *mpr); -void UI_tooltip_free(struct bContext *C, struct ARegion *ar); +void UI_tooltip_free(struct bContext *C, struct bScreen *sc, struct ARegion *ar); /* How long before a tool-tip shows. */ #define UI_TOOLTIP_DELAY 0.5 diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 9c1cee915e4..1e31837f088 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -296,8 +296,6 @@ typedef struct uiHandleButtonData { ColorBand *coba; /* tooltip */ - ARegion *tooltip; - wmTimer *tooltiptimer; unsigned int tooltip_force : 1; /* auto open */ @@ -7701,12 +7699,12 @@ static bool button_modal_state(uiHandleButtonState state) */ void UI_but_tooltip_refresh(bContext *C, uiBut *but) { - uiHandleButtonData *data; - - data = but->active; - if (data && data->tooltip) { - UI_tooltip_free(C, data->tooltip); - data->tooltip = UI_tooltip_create_from_button(C, data->region, but); + uiHandleButtonData *data = but->active; + if (data) { + bScreen *sc = WM_window_get_active_screen(data->window); + if (sc->tool_tip && sc->tool_tip->region) { + WM_tooltip_refresh(C, data->window); + } } } @@ -7717,39 +7715,36 @@ void UI_but_tooltip_timer_remove(bContext *C, uiBut *but) data = but->active; if (data) { - - if (data->tooltiptimer) { - WM_event_remove_timer(data->wm, data->window, data->tooltiptimer); - data->tooltiptimer = NULL; - } - if (data->tooltip) { - UI_tooltip_free(C, data->tooltip); - data->tooltip = NULL; - } - if (data->autoopentimer) { WM_event_remove_timer(data->wm, data->window, data->autoopentimer); data->autoopentimer = NULL; } + + WM_tooltip_clear(C, data->window); } } +static ARegion *ui_but_tooltip_init(bContext *C, ARegion *ar, bool *r_exit_on_event) +{ + uiBut *but = UI_region_active_but_get(ar); + *r_exit_on_event = false; + if (but) { + return UI_tooltip_create_from_button(C, ar, but); + } + return NULL; +} + static void button_tooltip_timer_reset(bContext *C, uiBut *but) { wmWindowManager *wm = CTX_wm_manager(C); - uiHandleButtonData *data; - - data = but->active; + uiHandleButtonData *data = but->active; - if (data->tooltiptimer) { - WM_event_remove_timer(data->wm, data->window, data->tooltiptimer); - data->tooltiptimer = NULL; - } + WM_tooltip_timer_clear(C, data->window); if ((U.flag & USER_TOOLTIPS) || (data->tooltip_force)) { if (!but->block->tooltipdisabled) { if (!wm->drags.first) { - data->tooltiptimer = WM_event_add_timer(data->wm, data->window, TIMER, UI_TOOLTIP_DELAY); + WM_tooltip_timer_init(C, data->window, data->region, ui_but_tooltip_init); } } } @@ -8109,12 +8104,10 @@ void ui_but_active_free(const bContext *C, uiBut *but) } /* returns the active button with an optional checking function */ -static uiBut *ui_context_button_active(const bContext *C, bool (*but_check_cb)(uiBut *)) +static uiBut *ui_context_button_active(ARegion *ar, bool (*but_check_cb)(uiBut *)) { uiBut *but_found = NULL; - ARegion *ar = CTX_wm_region(C); - while (ar) { uiBlock *block; uiBut *but, *activebut = NULL; @@ -8157,12 +8150,17 @@ static bool ui_context_rna_button_active_test(uiBut *but) } static uiBut *ui_context_rna_button_active(const bContext *C) { - return ui_context_button_active(C, ui_context_rna_button_active_test); + return ui_context_button_active(CTX_wm_region(C), ui_context_rna_button_active_test); } uiBut *UI_context_active_but_get(const struct bContext *C) { - return ui_context_button_active(C, NULL); + return ui_context_button_active(CTX_wm_region(C), NULL); +} + +uiBut *UI_region_active_but_get(ARegion *ar) +{ + return ui_context_button_active(ar, NULL); } /** @@ -8445,16 +8443,8 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) } case TIMER: { - /* handle tooltip timer */ - if (event->customdata == data->tooltiptimer) { - WM_event_remove_timer(data->wm, data->window, data->tooltiptimer); - data->tooltiptimer = NULL; - - if (!data->tooltip) - data->tooltip = UI_tooltip_create_from_button(C, data->region, but); - } /* handle menu auto open timer */ - else if (event->customdata == data->autoopentimer) { + if (event->customdata == data->autoopentimer) { WM_event_remove_timer(data->wm, data->window, data->autoopentimer); data->autoopentimer = NULL; diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 9a818efebee..07fbefa42e1 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -953,9 +953,9 @@ ARegion *UI_tooltip_create_from_manipulator(bContext *C, wmManipulator *mpr) return ui_tooltip_create_with_data(C, data, init_position, aspect); } -void UI_tooltip_free(bContext *C, ARegion *ar) +void UI_tooltip_free(bContext *C, bScreen *sc, ARegion *ar) { - ui_region_temp_remove(C, CTX_wm_screen(C), ar); + ui_region_temp_remove(C, sc, ar); } /** \} */ diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index dd716014f66..375641d1115 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -45,6 +45,8 @@ struct PanelType; struct Scene; struct uiLayout; struct wmTimer; +struct wmTooltipState; + typedef struct bScreen { ID id; @@ -77,6 +79,8 @@ typedef struct bScreen { struct wmTimer *animtimer; /* if set, screen has timer handler added in window */ void *context; /* context callback */ + struct wmTooltipState *tool_tip; /* runtime */ + PreviewImage *preview; } bScreen; diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index b5784fe543c..059055daea9 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -73,6 +73,7 @@ set(SRC intern/wm_window.c intern/wm_stereo.c intern/wm_toolsystem.c + intern/wm_tooltip.c manipulators/intern/wm_manipulator.c manipulators/intern/wm_manipulator_group.c manipulators/intern/wm_manipulator_group_type.c diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 85f94721d40..7a66cc04014 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -576,6 +576,17 @@ void WM_toolsystem_link(struct bContext *C, struct WorkSpace *workspace); void WM_toolsystem_set(struct bContext *C, const struct bToolDef *tool); void WM_toolsystem_init(struct bContext *C); +/* wm_tooltip.c */ +typedef struct ARegion *(*wmTooltipInitFn)(struct bContext *, struct ARegion *, bool *); + +void WM_tooltip_timer_init( + struct bContext *C, struct wmWindow *win, struct ARegion *ar, + wmTooltipInitFn init); +void WM_tooltip_timer_clear(struct bContext *C, struct wmWindow *win); +void WM_tooltip_clear(struct bContext *C, struct wmWindow *win); +void WM_tooltip_init(struct bContext *C, struct wmWindow *win); +void WM_tooltip_refresh(struct bContext *C, struct wmWindow *win); + #ifdef __cplusplus } #endif diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 883a680acd7..7254301b874 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -702,6 +702,15 @@ typedef struct wmDropBox { } wmDropBox; +typedef struct wmTooltipState { + struct wmTimer *timer; + struct ARegion *region_from; + struct ARegion *region; + struct ARegion *(*init)(struct bContext *, struct ARegion *, bool *r_exit_on_event); + /* Exit on any event, not needed for buttons since their highlight state is used. */ + bool exit_on_event; +} wmTooltipState; + /* *************** migrated stuff, clean later? ************** */ typedef struct RecentFile { diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 6e559ef7157..133ac6564f8 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2275,30 +2275,13 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers wm_manipulatormap_handler_context(C, handler); wm_region_mouse_co(C, event); - if (event->type == MOUSEMOVE) { - WM_manipulatormap_tooltip_clear(C, mmap); - } - /* handle manipulator highlighting */ if (event->type == MOUSEMOVE && !wm_manipulatormap_modal_get(mmap)) { int part; mpr = wm_manipulatormap_highlight_find(mmap, C, event, &part); wm_manipulatormap_highlight_set(mmap, C, mpr, part); if (mpr != NULL) { - WM_manipulatormap_tooltip_timer_init(C, mmap); - } - } - /* handle user configurable manipulator-map keymap */ - else if ((event->type == TIMER) && - (event->customdata == WM_manipulatormap_tooltip_timer_get(mmap))) - { - if (mpr) { - if (mpr->state & WM_MANIPULATOR_STATE_MODAL) { - WM_manipulatormap_tooltip_clear(C, mmap); - } - else { - WM_manipulatormap_tooltip_create(C, mmap); - } + WM_tooltip_timer_init(C, CTX_wm_window(C), region, WM_manipulatormap_tooltip_init); } } else { @@ -2735,6 +2718,13 @@ void wm_event_do_handlers(bContext *C) CTX_wm_window_set(C, win); + /* Clear tool-tip on mouse move. */ + if (screen->tool_tip && screen->tool_tip->exit_on_event) { + if (ISMOUSE(event->type)) { + WM_tooltip_clear(C, win); + } + } + /* we let modal handlers get active area/region, also wm_paintcursor_test needs it */ CTX_wm_area_set(C, area_event_inside(C, &event->x)); CTX_wm_region_set(C, region_event_inside(C, &event->x)); @@ -2751,7 +2741,16 @@ void wm_event_do_handlers(bContext *C) /* fileread case */ if (CTX_wm_window(C) == NULL) return; - + + /* check for a tooltip */ + if (screen == WM_window_get_active_screen(win)) { + if (screen->tool_tip && screen->tool_tip->timer) { + if ((event->type == TIMER) && (event->customdata == screen->tool_tip->timer)) { + WM_tooltip_init(C, win); + } + } + } + /* check dragging, creates new event or frees, adds draw tag */ wm_event_drag_test(wm, win, event); diff --git a/source/blender/windowmanager/intern/wm_tooltip.c b/source/blender/windowmanager/intern/wm_tooltip.c new file mode 100644 index 00000000000..83d620d1522 --- /dev/null +++ b/source/blender/windowmanager/intern/wm_tooltip.c @@ -0,0 +1,106 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/intern/wm_tooltip.c + * \ingroup wm + * + * Manages a per-window tool-tip. + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "BKE_context.h" + +#include "ED_screen.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +void WM_tooltip_timer_init( + bContext *C, wmWindow *win, ARegion *ar, + wmTooltipInitFn init) +{ + bScreen *screen = WM_window_get_active_screen(win); + wmWindowManager *wm = CTX_wm_manager(C); + if (screen->tool_tip == NULL) { + screen->tool_tip = MEM_callocN(sizeof(*screen->tool_tip), __func__); + } + screen->tool_tip->region_from = ar; + screen->tool_tip->timer = WM_event_add_timer(wm, win, TIMER, UI_TOOLTIP_DELAY); + screen->tool_tip->init = init; +} + +void WM_tooltip_timer_clear(bContext *C, wmWindow *win) +{ + wmWindowManager *wm = CTX_wm_manager(C); + bScreen *screen = WM_window_get_active_screen(win); + if (screen->tool_tip != NULL) { + if (screen->tool_tip->timer != NULL) { + WM_event_remove_timer(wm, win, screen->tool_tip->timer); + screen->tool_tip->timer = NULL; + } + } +} + +void WM_tooltip_clear(bContext *C, wmWindow *win) +{ + WM_tooltip_timer_clear(C, win); + bScreen *screen = WM_window_get_active_screen(win); + if (screen->tool_tip != NULL) { + if (screen->tool_tip->region) { + UI_tooltip_free(C, screen, screen->tool_tip->region); + screen->tool_tip->region = NULL; + } + MEM_freeN(screen->tool_tip); + screen->tool_tip = NULL; + } +} + +void WM_tooltip_init(bContext *C, wmWindow *win) +{ + WM_tooltip_timer_clear(C, win); + bScreen *screen = WM_window_get_active_screen(win); + if (screen->tool_tip->region) { + UI_tooltip_free(C, screen, screen->tool_tip->region); + screen->tool_tip->region = NULL; + } + screen->tool_tip->region = screen->tool_tip->init( + C, screen->tool_tip->region_from, &screen->tool_tip->exit_on_event); + if (screen->tool_tip->region == NULL) { + WM_tooltip_clear(C, win); + } +} + +void WM_tooltip_refresh(bContext *C, wmWindow *win) +{ + WM_tooltip_timer_clear(C, win); + bScreen *screen = WM_window_get_active_screen(win); + if (screen->tool_tip != NULL) { + if (screen->tool_tip->region) { + UI_tooltip_free(C, screen, screen->tool_tip->region); + screen->tool_tip->region = NULL; + } + WM_tooltip_init(C, win); + } +} diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index 097af2dadcc..53bee9c6775 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -259,14 +259,8 @@ bool WM_manipulatormap_minmax( const struct wmManipulatorMap *mmap, bool use_hidden, bool use_select, float r_min[3], float r_max[3]); -void WM_manipulatormap_tooltip_create( - struct bContext *C, struct wmManipulatorMap *mmap); -void WM_manipulatormap_tooltip_clear( - struct bContext *C, struct wmManipulatorMap *mmap); -void WM_manipulatormap_tooltip_timer_init( - struct bContext *C, struct wmManipulatorMap *mmap); -const void *WM_manipulatormap_tooltip_timer_get( - struct wmManipulatorMap *mmap); +struct ARegion *WM_manipulatormap_tooltip_init( + struct bContext *C, struct ARegion *ar, bool *r_exit_on_event); /* -------------------------------------------------------------------- */ /* wmManipulatorMapType */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c index 354fd32cbd6..0e63f3d6ffe 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c @@ -500,7 +500,7 @@ static int manipulator_tweak_invoke(bContext *C, wmOperator *op, const wmEvent * wmManipulator *mpr = mmap->mmap_context.highlight; /* Needed for single click actions which don't enter modal state. */ - WM_manipulatormap_tooltip_clear(C, mmap); + WM_tooltip_clear(C, CTX_wm_window(C)); if (!mpr) { /* wm_handlers_do_intern shouldn't let this happen */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h index ef3ccaaf47f..b7982cf00df 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h @@ -115,9 +115,6 @@ struct wmManipulatorMap { /* cursor location at point of entering modal (see: WM_MANIPULATOR_GRAB_CURSOR) */ int event_xy[2]; short event_grabcursor; - - struct ARegion *tooltip; - struct wmTimer *tooltip_timer; } mmap_context; }; diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index 5bd717d3f50..a9875020fbb 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -904,7 +904,7 @@ void wm_manipulatormap_modal_set( BLI_assert(mmap->mmap_context.modal == NULL); wmWindow *win = CTX_wm_window(C); - WM_manipulatormap_tooltip_clear(C, mmap); + WM_tooltip_clear(C, win); if (mpr->type->invoke && (mpr->type->modal || mpr->custom_modal)) @@ -1018,45 +1018,18 @@ void WM_manipulatormap_message_subscribe( * * \{ */ - -void WM_manipulatormap_tooltip_create( - bContext *C, wmManipulatorMap *mmap) -{ - WM_manipulatormap_tooltip_clear(C, mmap); - if (mmap->mmap_context.highlight) { - mmap->mmap_context.tooltip = UI_tooltip_create_from_manipulator(C, mmap->mmap_context.highlight); - } -} - -void WM_manipulatormap_tooltip_clear( - bContext *C, wmManipulatorMap *mmap) -{ - if (mmap->mmap_context.tooltip_timer != NULL) { - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = CTX_wm_window(C); - WM_event_remove_timer(wm, win, mmap->mmap_context.tooltip_timer); - mmap->mmap_context.tooltip_timer = NULL; - } - if (mmap->mmap_context.tooltip != NULL) { - UI_tooltip_free(C, mmap->mmap_context.tooltip); - mmap->mmap_context.tooltip = NULL; - } -} - -void WM_manipulatormap_tooltip_timer_init( - bContext *C, wmManipulatorMap *mmap) +struct ARegion *WM_manipulatormap_tooltip_init( + struct bContext *C, struct ARegion *ar, bool *r_exit_on_event) { - if (mmap->mmap_context.tooltip_timer == NULL) { - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = CTX_wm_window(C); - /* TODO: BUTTON_TOOLTIP_DELAY */ - mmap->mmap_context.tooltip_timer = WM_event_add_timer(wm, win, TIMER, UI_TOOLTIP_DELAY); + wmManipulatorMap *mmap = ar->manipulator_map; + *r_exit_on_event = true; + if (mmap) { + wmManipulator *mpr = mmap->mmap_context.highlight; + if (mpr) { + return UI_tooltip_create_from_manipulator(C, mpr); + } } -} - -const void *WM_manipulatormap_tooltip_timer_get(wmManipulatorMap *mmap) -{ - return mmap->mmap_context.tooltip_timer; + return NULL; } /** \} */ /* wmManipulatorMapType */ |