static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *event) { SpaceText *st = CTX_wm_space_text(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); int draw = 0, tools = 0, swallow = 0, scroll = 1; Text *text = CTX_data_edit_text(C); int retval = OPERATOR_RUNNING_MODAL; (void)text; if (st->doplugins && texttool_text_is_active(st->text)) { if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST; if (texttool_docs_get()) tools |= TOOL_DOCUMENT; } switch (event->type) { case LEFTMOUSE: if (event->val == KM_PRESS) { if (text_do_suggest_select(st, ar)) swallow = 1; else { if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(); if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0; retval = OPERATOR_FINISHED; } draw = 1; } break; case MIDDLEMOUSE: if (event->val == KM_PRESS) { if (text_do_suggest_select(st, ar)) { confirm_suggestion(st->text); text_update_line_edited(st->text->curl); swallow = 1; } else { if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(); if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0; retval = OPERATOR_FINISHED; } draw = 1; } break; case ESCKEY: if (event->val == KM_PRESS) { draw = swallow = 1; if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(); else if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0; else draw = swallow = 0; retval = OPERATOR_CANCELLED; } break; case RETKEY: case PADENTER: if (event->val == KM_PRESS) { if (tools & TOOL_SUGG_LIST) { confirm_suggestion(st->text); text_update_line_edited(st->text->curl); swallow = 1; draw = 1; } if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1; retval = OPERATOR_FINISHED; } break; case LEFTARROWKEY: case BACKSPACEKEY: if (event->val == KM_PRESS) { if (tools & TOOL_SUGG_LIST) { if (event->ctrl) { texttool_suggest_clear(); retval = OPERATOR_CANCELLED; } else { /* Work out which char we are about to delete/pass */ if (st->text->curl && st->text->curc > 0) { char ch = st->text->curl->line[st->text->curc - 1]; if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) { get_suggest_prefix(st->text, -1); text_pop_suggest_list(); } else { texttool_suggest_clear(); retval = OPERATOR_CANCELLED; } } else { texttool_suggest_clear(); retval = OPERATOR_CANCELLED; } } } if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0; } break; case RIGHTARROWKEY: if (event->val == KM_PRESS) { if (tools & TOOL_SUGG_LIST) { if (event->ctrl) { texttool_suggest_clear(); retval = OPERATOR_CANCELLED; } else { /* Work out which char we are about to pass */ if (st->text->curl && st->text->curc < st->text->curl->len) { char ch = st->text->curl->line[st->text->curc + 1]; if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) { get_suggest_prefix(st->text, 1); text_pop_suggest_list(); } else { texttool_suggest_clear(); retval = OPERATOR_CANCELLED; } } else { texttool_suggest_clear(); retval = OPERATOR_CANCELLED; } } } if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0; } break; case PAGEDOWNKEY: scroll = SUGG_LIST_SIZE - 1; /* fall-through */ case WHEELDOWNMOUSE: case DOWNARROWKEY: if (event->val == KM_PRESS) { if (tools & TOOL_DOCUMENT) { doc_scroll++; swallow = 1; draw = 1; } else if (tools & TOOL_SUGG_LIST) { SuggItem *sel = texttool_suggest_selected(); if (!sel) { texttool_suggest_select(texttool_suggest_first()); } else { while (sel && scroll--) { if (sel != texttool_suggest_last() && sel->next) { texttool_suggest_select(sel->next); sel = sel->next; } else { texttool_suggest_select(texttool_suggest_first()); sel = texttool_suggest_first(); } } } text_pop_suggest_list(); swallow = 1; draw = 1; } } break; case PAGEUPKEY: scroll = SUGG_LIST_SIZE - 1; /* fall-through */ case WHEELUPMOUSE: case UPARROWKEY: if (event->val == KM_PRESS) { if (tools & TOOL_DOCUMENT) { if (doc_scroll > 0) doc_scroll--; swallow = 1; draw = 1; } else if (tools & TOOL_SUGG_LIST) { SuggItem *sel = texttool_suggest_selected(); while (sel && scroll--) { if (sel != texttool_suggest_first() && sel->prev) { texttool_suggest_select(sel->prev); sel = sel->prev; } else { texttool_suggest_select(texttool_suggest_last()); sel = texttool_suggest_last(); } } text_pop_suggest_list(); swallow = 1; draw = 1; } } break; case RIGHTSHIFTKEY: case LEFTSHIFTKEY: break; #if 0 default: if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(), draw = 1; if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1; #endif } if (draw) { ED_area_tag_redraw(sa); } // if (swallow) { // retval = OPERATOR_RUNNING_MODAL; // } if (texttool_suggest_first()) { if (retval != OPERATOR_RUNNING_MODAL) { text_autocomplete_free(C, op); } return retval; } else { text_autocomplete_free(C, op); return OPERATOR_FINISHED; } }
static void draw_suggestion_list(SpaceText *st, ARegion *ar) { SuggItem *item, *first, *last, *sel; char str[SUGG_LIST_WIDTH * BLI_UTF8_MAX + 1]; int offl, offc, vcurl, vcurc; int w, boxw = 0, boxh, i, x, y, *top; const int lheight = st->lheight_dpi + TXT_LINE_SPACING; const int margin_x = 2; if (!st->text) return; if (!texttool_text_is_active(st->text)) return; first = texttool_suggest_first(); last = texttool_suggest_last(); if (!first || !last) return; text_pop_suggest_list(); sel = texttool_suggest_selected(); top = texttool_suggest_top(); wrap_offset(st, ar, st->text->curl, st->text->curc, &offl, &offc); vcurl = txt_get_span(st->text->lines.first, st->text->curl) - st->top + offl; vcurc = text_get_char_pos(st, st->text->curl->line, st->text->curc) - st->left + offc; x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET; x += vcurc * st->cwidth - 4; y = ar->winy - (vcurl + 1) * lheight - 2; /* offset back so the start of the text lines up with the suggestions, * not essential but makes suggestions easier to follow */ x -= st->cwidth * (st->text->curc - text_find_identifier_start(st->text->curl->line, st->text->curc)); boxw = SUGG_LIST_WIDTH * st->cwidth + 20; boxh = SUGG_LIST_SIZE * lheight + 8; if (x + boxw > ar->winx) x = MAX2(0, ar->winx - boxw); /* not needed but stands out nicer */ uiDrawBoxShadow(220, x, y - boxh, x + boxw, y); UI_ThemeColor(TH_SHADE1); glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1); UI_ThemeColorShade(TH_BACK, 16); glRecti(x, y, x + boxw, y - boxh); /* Set the top 'item' of the visible list */ for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ; for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) { int len = txt_utf8_forward_columns(item->name, SUGG_LIST_WIDTH, NULL) - item->name; y -= lheight; BLI_strncpy(str, item->name, len + 1); w = st->cwidth * text_get_char_pos(st, str, len); if (item == sel) { UI_ThemeColor(TH_SHADE2); glRecti(x + margin_x, y - 3, x + margin_x + w, y + lheight - 3); } format_draw_color(item->type); text_draw(st, str, 0, 0, x + margin_x, y - 1, NULL); if (item == last) break; } }
static void draw_suggestion_list(SpaceText *st, ARegion *ar) { SuggItem *item, *first, *last, *sel; TextLine *tmp; char str[SUGG_LIST_WIDTH+1]; int w, boxw=0, boxh, i, l, x, y, b, *top; if(!st || !st->text) return; if(!texttool_text_is_active(st->text)) return; first = texttool_suggest_first(); last = texttool_suggest_last(); if(!first || !last) return; text_pop_suggest_list(); sel = texttool_suggest_selected(); top = texttool_suggest_top(); /* Count the visible lines to the cursor */ for(tmp=st->text->curl, l=-st->top; tmp; tmp=tmp->prev, l++); if(l<0) return; if(st->showlinenrs) { x = st->cwidth*(st->text->curc-st->left) + TXT_OFFSET + TEXTXLOC - 4; } else { x = st->cwidth*(st->text->curc-st->left) + TXT_OFFSET - 4; } y = ar->winy - st->lheight*l - 2; boxw = SUGG_LIST_WIDTH*st->cwidth + 20; boxh = SUGG_LIST_SIZE*st->lheight + 8; UI_ThemeColor(TH_SHADE1); glRecti(x-1, y+1, x+boxw+1, y-boxh-1); UI_ThemeColor(TH_BACK); glRecti(x, y, x+boxw, y-boxh); /* Set the top 'item' of the visible list */ for(i=0, item=first; i<*top && item->next; i++, item=item->next); for(i=0; i<SUGG_LIST_SIZE && item; i++, item=item->next) { y -= st->lheight; strncpy(str, item->name, SUGG_LIST_WIDTH); str[SUGG_LIST_WIDTH] = '\0'; w = text_font_width(st, str); if(item == sel) { UI_ThemeColor(TH_SHADE2); glRecti(x+16, y-3, x+16+w, y+st->lheight-3); } b=1; /* b=1 color block, text is default. b=0 no block, color text */ switch (item->type) { case 'k': UI_ThemeColor(TH_SYNTAX_B); b=0; break; case 'm': UI_ThemeColor(TH_TEXT); break; case 'f': UI_ThemeColor(TH_SYNTAX_L); break; case 'v': UI_ThemeColor(TH_SYNTAX_N); break; case '?': UI_ThemeColor(TH_TEXT); b=0; break; } if(b) { glRecti(x+8, y+2, x+11, y+5); UI_ThemeColor(TH_TEXT); } text_draw(st, str, 0, 0, 1, x+16, y-1, NULL); if(item == last) break; } }