Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_handlers.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
| Show First 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
| #include "interface_intern.h" | #include "interface_intern.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "wm_event_system.h" | #include "wm_event_system.h" | ||||
| #ifdef WITH_INPUT_IME | |||||
| # include "wm_window.h" | |||||
| # include "BLT_lang.h" | |||||
| #endif | |||||
| /* place the mouse at the scaled down location when un-grabbing */ | /* place the mouse at the scaled down location when un-grabbing */ | ||||
| #define USE_CONT_MOUSE_CORRECT | #define USE_CONT_MOUSE_CORRECT | ||||
| /* support dragging toggle buttons */ | /* support dragging toggle buttons */ | ||||
| #define USE_DRAG_TOGGLE | #define USE_DRAG_TOGGLE | ||||
| /* support dragging multiple number buttons at once */ | /* support dragging multiple number buttons at once */ | ||||
| #define USE_DRAG_MULTINUM | #define USE_DRAG_MULTINUM | ||||
| ▲ Show 20 Lines • Show All 2,903 Lines • ▼ Show 20 Lines | if (mode == UI_TEXTEDIT_CUT) { | ||||
| changed = ui_textedit_delete_selection(but, data); | changed = ui_textedit_delete_selection(but, data); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| #ifdef WITH_INPUT_IME | #if defined(WITH_IM_OVERTHESPOT) || defined(WITH_IM_ONTHESPOT) | ||||
| /* enable ime, and set up uibut ime data */ | void UI_region_im_spot_set(wmWindow *win, ARegion *ar, int x, int y, int h) | ||||
| static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but)) | |||||
| { | { | ||||
| /* XXX Is this really needed? */ | ui_region_to_window(ar, &x, &y); | ||||
| int x, y; | WM_window_IM_spot_set(win, x, y, h); | ||||
| BLI_assert(win->ime_data == NULL); | |||||
| /* enable IME and position to cursor, it's a trick */ | |||||
| x = win->eventstate->x; | |||||
| /* flip y and move down a bit, prevent the IME panel cover the edit button */ | |||||
| y = win->eventstate->y - 12; | |||||
| wm_window_IME_begin(win, x, y, 0, 0, true); | |||||
| } | } | ||||
| /* disable ime, and clear uibut ime data */ | void ui_but_im_spot_set(uiBut *but, int x, int y, int h) | ||||
| static void ui_textedit_ime_end(wmWindow *win, uiBut *UNUSED(but)) | |||||
| { | |||||
| wm_window_IME_end(win); | |||||
| } | |||||
| void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete) | |||||
| { | { | ||||
| BLI_assert(but->active); | BLI_assert(but->active); | ||||
| ui_region_to_window(but->active->region, &x, &y); | wmWindow *win = but->active->window; | ||||
| wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete); | |||||
| /* unset modal temporarily in order to force spot location to set */ | |||||
| WM_window_IM_modal_unset(win); | |||||
| UI_region_im_spot_set(win, but->active->region, x, y, h); | |||||
| WM_window_IM_modal_set(win); | |||||
| } | } | ||||
| #endif /* defined(WITH_IM_OVERTHESPOT) || defined(WITH_IM_ONTHESPOT) */ | |||||
| wmIMEData *ui_but_ime_data_get(uiBut *but) | #ifdef WITH_IM_ONTHESPOT | ||||
| wmIMData *ui_but_im_data_get(uiBut *but) | |||||
| { | { | ||||
| if (but->active && but->active->window) { | if (but->active && but->active->window) { | ||||
| return but->active->window->ime_data; | return but->active->window->im_data; | ||||
| } | } | ||||
| else { | else { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| } | } | ||||
| #endif /* WITH_INPUT_IME */ | #endif /* WITH_IM_ONTHESPOT */ | ||||
| static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) | static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| int len; | int len; | ||||
| const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER); | const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER); | ||||
| if (data->str) { | if (data->str) { | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | #endif | ||||
| /* reset alert flag (avoid confusion, will refresh on exit) */ | /* reset alert flag (avoid confusion, will refresh on exit) */ | ||||
| but->flag &= ~UI_BUT_REDALERT; | but->flag &= ~UI_BUT_REDALERT; | ||||
| ui_but_update(but); | ui_but_update(but); | ||||
| WM_cursor_modal_set(win, BC_TEXTEDITCURSOR); | WM_cursor_modal_set(win, BC_TEXTEDITCURSOR); | ||||
| #ifdef WITH_INPUT_IME | #if defined(WITH_IM_OVERTHESPOT) || defined(WITH_IM_ONTHESPOT) | ||||
| if (is_num_but == false && BLT_lang_is_ime_supported()) { | /* XXX python3 allows non-ascii variable name. is this if() really needed...? */ | ||||
| ui_textedit_ime_begin(win, but); | if (is_num_but == false) | ||||
| } | WM_window_IM_begin(win); | ||||
| else | |||||
| WM_window_IM_end(win); | |||||
| WM_window_IM_modal_set(win); | |||||
| #endif | #endif | ||||
| } | } | ||||
| static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) | static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| if (but) { | if (but) { | ||||
| Show All 23 Lines | if (but) { | ||||
| } | } | ||||
| but->editstr = NULL; | but->editstr = NULL; | ||||
| but->pos = -1; | but->pos = -1; | ||||
| } | } | ||||
| WM_cursor_modal_restore(win); | WM_cursor_modal_restore(win); | ||||
| #ifdef WITH_INPUT_IME | #if defined(WITH_IM_OVERTHESPOT) || defined(WITH_IM_ONTHESPOT) | ||||
| if (win->ime_data) { | WM_window_IM_modal_unset(win); | ||||
| ui_textedit_ime_end(win, but); | WM_window_IM_end(win); | ||||
| } | |||||
| #endif | #endif | ||||
| } | } | ||||
| static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data) | static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| /* label and roundbox can overlap real buttons (backdrops...) */ | /* label and roundbox can overlap real buttons (backdrops...) */ | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
| static void ui_do_but_textedit( | static void ui_do_but_textedit( | ||||
| bContext *C, uiBlock *block, uiBut *but, | bContext *C, uiBlock *block, uiBut *but, | ||||
| uiHandleButtonData *data, const wmEvent *event) | uiHandleButtonData *data, const wmEvent *event) | ||||
| { | { | ||||
| int retval = WM_UI_HANDLER_CONTINUE; | int retval = WM_UI_HANDLER_CONTINUE; | ||||
| bool changed = false, inbox = false, update = false; | bool changed = false, inbox = false, update = false; | ||||
| #ifdef WITH_INPUT_IME | #ifdef WITH_IM_ONTHESPOT | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| wmIMEData *ime_data = win->ime_data; | wmIMData *im_data = win->im_data; | ||||
| bool is_ime_composing = ime_data && ime_data->is_ime_composing; | bool is_im_composing = im_data && im_data->is_im_composing; | ||||
| #else | #else | ||||
| bool is_ime_composing = false; | bool is_im_composing = false; | ||||
| #endif | #endif | ||||
| switch (event->type) { | switch (event->type) { | ||||
| case MOUSEMOVE: | case MOUSEMOVE: | ||||
| case MOUSEPAN: | case MOUSEPAN: | ||||
| if (data->searchbox) { | if (data->searchbox) { | ||||
| #ifdef USE_KEYNAV_LIMIT | #ifdef USE_KEYNAV_LIMIT | ||||
| if ((event->type == MOUSEMOVE) && ui_mouse_motion_keynav_test(&data->searchbox_keynav_state, event)) { | if ((event->type == MOUSEMOVE) && ui_mouse_motion_keynav_test(&data->searchbox_keynav_state, event)) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else { | else { | ||||
| ui_searchbox_event(C, data->searchbox, but, event); | ui_searchbox_event(C, data->searchbox, but, event); | ||||
| } | } | ||||
| #else | #else | ||||
| ui_searchbox_event(C, data->searchbox, but, event); | ui_searchbox_event(C, data->searchbox, but, event); | ||||
| #endif | #endif | ||||
| } | } | ||||
| break; | break; | ||||
| case RIGHTMOUSE: | case RIGHTMOUSE: | ||||
| case ESCKEY: | case ESCKEY: | ||||
| if (event->val == KM_PRESS) { | if (event->val == KM_PRESS) { | ||||
| #ifdef WITH_INPUT_IME | #ifdef WITH_IM_ONTHESPOT | ||||
| /* skips button handling since it is not wanted */ | /* skips button handling since it is not wanted */ | ||||
| if (is_ime_composing) { | if (is_im_composing) { | ||||
| break; | break; | ||||
| } | } | ||||
| #endif | #endif | ||||
| data->cancel = true; | data->cancel = true; | ||||
| data->escapecancel = true; | data->escapecancel = true; | ||||
| button_activate_state(C, but, BUTTON_STATE_EXIT); | button_activate_state(C, but, BUTTON_STATE_EXIT); | ||||
| retval = WM_UI_HANDLER_BREAK; | retval = WM_UI_HANDLER_BREAK; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | case LEFTMOUSE: | ||||
| button_activate_state(C, but, BUTTON_STATE_EXIT); | button_activate_state(C, but, BUTTON_STATE_EXIT); | ||||
| retval = WM_UI_HANDLER_BREAK; | retval = WM_UI_HANDLER_BREAK; | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (event->val == KM_PRESS && !is_ime_composing) { | if (event->val == KM_PRESS && !is_im_composing) { | ||||
| switch (event->type) { | switch (event->type) { | ||||
| case VKEY: | case VKEY: | ||||
| case XKEY: | case XKEY: | ||||
| case CKEY: | case CKEY: | ||||
| if (IS_EVENT_MOD(event, ctrl, oskey)) { | if (IS_EVENT_MOD(event, ctrl, oskey)) { | ||||
| if (event->type == VKEY) | if (event->type == VKEY) | ||||
| changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE); | changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE); | ||||
| else if (event->type == CKEY) | else if (event->type == CKEY) | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | #endif | ||||
| button_activate_state(C, but, BUTTON_STATE_EXIT); | button_activate_state(C, but, BUTTON_STATE_EXIT); | ||||
| } | } | ||||
| retval = WM_UI_HANDLER_BREAK; | retval = WM_UI_HANDLER_BREAK; | ||||
| break; | break; | ||||
| } | } | ||||
| if ((event->ascii || event->utf8_buf[0]) && | if ((event->ascii || event->utf8_buf[0]) && | ||||
| (retval == WM_UI_HANDLER_CONTINUE) | (retval == WM_UI_HANDLER_CONTINUE) | ||||
| #ifdef WITH_INPUT_IME | #ifdef WITH_IM_ONTHESPOT | ||||
| && | && | ||||
| !is_ime_composing && | !(is_im_composing || WM_event_is_im_switch(event)) | ||||
| (!WM_event_is_ime_switch(event) || !BLT_lang_is_ime_supported()) | |||||
| #endif | #endif | ||||
| ) | ) | ||||
| { | { | ||||
| char ascii = event->ascii; | char ascii = event->ascii; | ||||
| const char *utf8_buf = event->utf8_buf; | const char *utf8_buf = event->utf8_buf; | ||||
| /* exception that's useful for number buttons, some keyboard | /* exception that's useful for number buttons, some keyboard | ||||
| * numpads have a comma instead of a period */ | * numpads have a comma instead of a period */ | ||||
| Show All 22 Lines | #endif | ||||
| } | } | ||||
| /* textbutton with this flag: do live update (e.g. for search buttons) */ | /* textbutton with this flag: do live update (e.g. for search buttons) */ | ||||
| if (but->flag & UI_BUT_TEXTEDIT_UPDATE) { | if (but->flag & UI_BUT_TEXTEDIT_UPDATE) { | ||||
| update = true; | update = true; | ||||
| } | } | ||||
| } | } | ||||
| #ifdef WITH_INPUT_IME | #ifdef WITH_IM_ONTHESPOT | ||||
| if (event->type == WM_IME_COMPOSITE_START || event->type == WM_IME_COMPOSITE_EVENT) { | if (event->type == WM_IM_COMPOSITE_START || event->type == WM_IM_COMPOSITE_EVENT) { | ||||
| changed = true; | changed = true; | ||||
| if (event->type == WM_IME_COMPOSITE_START && but->selend > but->selsta) { | if (event->type == WM_IM_COMPOSITE_START && but->selend > but->selsta) { | ||||
| ui_textedit_delete_selection(but, data); | ui_textedit_delete_selection(but, data); | ||||
| } | } | ||||
| if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) { | if (event->type == WM_IM_COMPOSITE_EVENT && im_data->result_len) { | ||||
| ui_textedit_insert_buf( | ui_textedit_insert_buf( | ||||
| but, data, | but, data, | ||||
| ime_data->str_result, | im_data->str_result, | ||||
| ime_data->result_len); | im_data->result_len); | ||||
| } | } | ||||
| } | } | ||||
| else if (event->type == WM_IME_COMPOSITE_END) { | else if (event->type == WM_IM_COMPOSITE_END) { | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| #endif | #endif | ||||
| if (changed) { | if (changed) { | ||||
| /* only do live update when but flag request it (UI_BUT_TEXTEDIT_UPDATE). */ | /* only do live update when but flag request it (UI_BUT_TEXTEDIT_UPDATE). */ | ||||
| if (update && data->interactive) { | if (update && data->interactive) { | ||||
| ui_apply_but(C, block, but, data, true); | ui_apply_but(C, block, but, data, true); | ||||
| ▲ Show 20 Lines • Show All 6,776 Lines • Show Last 20 Lines | |||||