Manipulator: tooltip support
Currently operators and properties are used.
This commit is contained in:
@@ -73,6 +73,7 @@ struct bNodeSocket;
|
||||
struct wmDropBox;
|
||||
struct wmDrag;
|
||||
struct wmEvent;
|
||||
struct wmManipulator;
|
||||
struct wmMsgBus;
|
||||
|
||||
typedef struct uiBut uiBut;
|
||||
@@ -1137,6 +1138,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);
|
||||
|
||||
/* How long before a tool-tip shows. */
|
||||
|
||||
@@ -620,6 +620,112 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
|
||||
}
|
||||
}
|
||||
|
||||
static uiTooltipData *ui_tooltip_data_from_manipulator(bContext *C, wmManipulator *mpr)
|
||||
{
|
||||
uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
|
||||
|
||||
/* TODO(campbell): a way for manipulators to have their own descriptions (low priority). */
|
||||
|
||||
/* Operator Actions */
|
||||
{
|
||||
bool use_drag = mpr->drag_part != -1 && mpr->highlight_part != mpr->drag_part;
|
||||
|
||||
const struct {
|
||||
int part;
|
||||
const char *prefix;
|
||||
} mpop_actions[] = {
|
||||
{
|
||||
.part = mpr->highlight_part,
|
||||
.prefix = use_drag ? TIP_("Click") : NULL,
|
||||
}, {
|
||||
.part = use_drag ? mpr->drag_part : -1,
|
||||
.prefix = use_drag ? TIP_("Drag") : NULL,
|
||||
},
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(mpop_actions); i++) {
|
||||
wmManipulatorOpElem *mpop = (mpop_actions[i].part != -1) ? WM_manipulator_operator_get(mpr, mpop_actions[i].part) : NULL;
|
||||
if (mpop != NULL) {
|
||||
/* Description */
|
||||
const char *info = RNA_struct_ui_description(mpop->type->srna);
|
||||
if (!(info && info[0])) {
|
||||
info = RNA_struct_ui_name(mpop->type->srna);
|
||||
}
|
||||
|
||||
if (info && info[0]) {
|
||||
char *text = NULL;
|
||||
if (mpop_actions[i].prefix != NULL) {
|
||||
text = BLI_sprintfN("%s: %s", mpop_actions[i].prefix, info);
|
||||
}
|
||||
else {
|
||||
text = BLI_strdup(info);
|
||||
}
|
||||
|
||||
if (text != NULL) {
|
||||
uiTooltipField *field = text_field_add(
|
||||
data, &(uiTooltipFormat){
|
||||
.style = UI_TIP_STYLE_HEADER,
|
||||
.color_id = UI_TIP_LC_VALUE,
|
||||
.is_pad = true,
|
||||
});
|
||||
field->text = text;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shortcut */
|
||||
{
|
||||
bool found = false;
|
||||
IDProperty *prop = mpop->ptr.data;
|
||||
char buf[128];
|
||||
if (WM_key_event_operator_string(
|
||||
C, mpop->type->idname, WM_OP_INVOKE_DEFAULT, prop, true,
|
||||
buf, ARRAY_SIZE(buf)))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
uiTooltipField *field = text_field_add(
|
||||
data, &(uiTooltipFormat){
|
||||
.style = UI_TIP_STYLE_NORMAL,
|
||||
.color_id = UI_TIP_LC_VALUE,
|
||||
.is_pad = true,
|
||||
});
|
||||
field->text = BLI_sprintfN(TIP_("Shortcut: %s"), found ? buf : "None");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Property Actions */
|
||||
if (mpr->type->target_property_defs_len) {
|
||||
wmManipulatorProperty *mpr_prop_array = WM_manipulator_target_property_array(mpr);
|
||||
for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
|
||||
/* TODO(campbell): function callback descriptions. */
|
||||
wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
|
||||
if (mpr_prop->prop != NULL) {
|
||||
const char *info = RNA_property_ui_description(mpr_prop->prop);
|
||||
if (info && info[0]) {
|
||||
uiTooltipField *field = text_field_add(
|
||||
data, &(uiTooltipFormat){
|
||||
.style = UI_TIP_STYLE_NORMAL,
|
||||
.color_id = UI_TIP_LC_VALUE,
|
||||
.is_pad = true,
|
||||
});
|
||||
field->text = BLI_strdup(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data->fields_len == 0) {
|
||||
MEM_freeN(data);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ARegion *ui_tooltip_create_with_data(
|
||||
bContext *C, uiTooltipData *data,
|
||||
const float init_position[2],
|
||||
@@ -827,6 +933,23 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b
|
||||
return ui_tooltip_create_with_data(C, data, init_position, aspect);
|
||||
}
|
||||
|
||||
ARegion *UI_tooltip_create_from_manipulator(bContext *C, wmManipulator *mpr)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const float aspect = 1.0f;
|
||||
float init_position[2];
|
||||
|
||||
uiTooltipData *data = ui_tooltip_data_from_manipulator(C, mpr);
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
init_position[0] = win->eventstate->x;
|
||||
init_position[1] = win->eventstate->y;
|
||||
|
||||
return ui_tooltip_create_with_data(C, data, init_position, aspect);
|
||||
}
|
||||
|
||||
void UI_tooltip_free(bContext *C, ARegion *ar)
|
||||
{
|
||||
ui_region_temp_remove(C, CTX_wm_screen(C), ar);
|
||||
|
||||
@@ -2251,13 +2251,32 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Either we operate on a single highlighted item
|
||||
* or groups attached to the selected manipulators.
|
||||
|
||||
@@ -259,6 +259,15 @@ 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);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* wmManipulatorMapType */
|
||||
|
||||
|
||||
@@ -115,6 +115,9 @@ 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
#include "WM_types.h"
|
||||
#include "wm_event_system.h"
|
||||
|
||||
/* for tool-tips */
|
||||
#include "UI_interface.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
/* own includes */
|
||||
@@ -888,6 +891,8 @@ void wm_manipulatormap_modal_set(
|
||||
BLI_assert(mmap->mmap_context.modal == NULL);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
WM_manipulatormap_tooltip_clear(C, mmap);
|
||||
|
||||
/* For now only grab cursor for 3D manipulators. */
|
||||
int retval = OPERATOR_RUNNING_MODAL;
|
||||
|
||||
@@ -996,6 +1001,54 @@ void WM_manipulatormap_message_subscribe(
|
||||
/** \} */ /* wmManipulatorMap */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tooltip Handling
|
||||
*
|
||||
* \{ */
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
const void *WM_manipulatormap_tooltip_timer_get(wmManipulatorMap *mmap)
|
||||
{
|
||||
return mmap->mmap_context.tooltip_timer;
|
||||
}
|
||||
|
||||
/** \} */ /* wmManipulatorMapType */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name wmManipulatorMapType
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user