diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-12-27 23:22:06 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-12-27 23:22:06 +0300 |
commit | 532b5e7bba1d229600eb0aa48684692cd630cfa6 (patch) | |
tree | d21fc2c6d3636de0bcd2834573d8640c7755fae7 /source/blender/editors/space_console | |
parent | 280a1d09f6cafa5bd9b117b5b39bf90b2d21bdf0 (diff) |
WIP console text selection, modal selection operator and selection drawing.
word wrap and clipboard are not working yet.
Diffstat (limited to 'source/blender/editors/space_console')
4 files changed, 274 insertions, 65 deletions
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 4f225bb8fcb..ab1fc8a5fca 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -123,63 +123,120 @@ static void console_report_color(unsigned char *fg, unsigned char *bg, Report *r } } +} +typedef struct ConsoleDrawContext { + int cwidth; + int lheight; + int console_width; + int winx; + int ymin, ymax; + int *xy; // [2] + int *sel; // [2] + int *pos_pick; + int *mval; // [2] + int draw; +} ConsoleDrawContext; + +static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int console_width, int lheight) +{ + if(sel[0] < str_len && sel[1] > 0) { + int sta = MAX2(sel[0], 0); + int end = MIN2(sel[1], str_len); + { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_halftone); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4ub(255, 255, 255, 96); + } + glRecti(xy[0]+(cwidth*sta), xy[1]-2 + lheight, xy[0]+(cwidth*end), xy[1]-2); + { + glDisable(GL_POLYGON_STIPPLE); + glDisable( GL_BLEND ); + } + } - + sel[0] -= str_len; + sel[1] -= str_len; } /* return 0 if the last line is off the screen * should be able to use this for any string type */ -static int console_draw_string( char *str, int str_len, - int console_width, int lheight, - unsigned char *fg, unsigned char *bg, - int winx, - int ymin, int ymax, - int *x, int *y, int draw) -{ - int rct_ofs= lheight/4; - int tot_lines = (str_len/console_width)+1; /* total number of lines for wrapping */ - int y_next = (str_len > console_width) ? (*y)+lheight*tot_lines : (*y)+lheight; + +static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len, unsigned char *fg, unsigned char *bg) +{ + int rct_ofs= cdc->lheight/4; + int tot_lines = (str_len/cdc->console_width)+1; /* total number of lines for wrapping */ + int y_next = (str_len > cdc->console_width) ? cdc->xy[1]+cdc->lheight*tot_lines : cdc->xy[1]+cdc->lheight; /* just advance the height */ - if(draw==0) { - *y= y_next; + if(cdc->draw==0) { + if(cdc->pos_pick) { + if((cdc->mval[1] != INT_MAX) && cdc->xy[1] <= cdc->mval[1]) { + if((cdc->xy[1]+cdc->lheight >= cdc->mval[1])) { + int ofs = (int)floor(((float)cdc->mval[0] / (float)cdc->cwidth)); + *cdc->pos_pick += MIN2(ofs, str_len); + } else + *cdc->pos_pick += str_len; + } + + } + + cdc->xy[1]= y_next; return 1; } - else if (y_next-lheight < ymin) { + else if (y_next-cdc->lheight < cdc->ymin) { /* have not reached the drawable area so don't break */ - *y= y_next; + cdc->xy[1]= y_next; return 1; } - if(str_len > console_width) { /* wrap? */ - char *line_stride= str + ((tot_lines-1) * console_width); /* advance to the last line and draw it first */ + if(str_len > cdc->console_width) { /* wrap? */ + char *line_stride= str + ((tot_lines-1) * cdc->console_width); /* advance to the last line and draw it first */ char eol; /* baclup the end of wrapping */ if(bg) { glColor3ub(bg[0], bg[1], bg[2]); - glRecti(0, *y-rct_ofs, winx, (*y+(lheight*tot_lines))+rct_ofs); + glRecti(0, cdc->xy[1]-rct_ofs, cdc->winx, (cdc->xy[1]+(cdc->lheight*tot_lines))+rct_ofs); } glColor3ub(fg[0], fg[1], fg[2]); /* last part needs no clipping */ - BLF_position(*x, *y, 0); (*y) += lheight; + BLF_position(cdc->xy[0], cdc->xy[1], 0); BLF_draw(line_stride); - line_stride -= console_width; + + if(cdc->sel[0] != cdc->sel[1]) { + cdc->sel[0] += str_len - (cdc->console_width % str_len); + cdc->sel[1] += str_len - (cdc->console_width % str_len); + console_draw_sel(cdc->sel, cdc->xy, cdc->console_width % str_len, cdc->cwidth, cdc->console_width, cdc->lheight); + glColor3ub(fg[0], fg[1], fg[2]); + } + + cdc->xy[1] += cdc->lheight; + + line_stride -= cdc->console_width; - for(; line_stride >= str; line_stride -= console_width) { - eol = line_stride[console_width]; - line_stride[console_width]= '\0'; + for(; line_stride >= str; line_stride -= cdc->console_width) { + eol = line_stride[cdc->console_width]; + line_stride[cdc->console_width]= '\0'; - BLF_position(*x, *y, 0); (*y) += lheight; + BLF_position(cdc->xy[0], cdc->xy[1], 0); BLF_draw(line_stride); - line_stride[console_width] = eol; /* restore */ + if(cdc->sel[0] != cdc->sel[1]) { + console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->console_width, cdc->lheight); + glColor3ub(fg[0], fg[1], fg[2]); + } + + cdc->xy[1] += cdc->lheight; + + line_stride[cdc->console_width] = eol; /* restore */ /* check if were out of view bounds */ - if(*y > ymax) + if(cdc->xy[1] > cdc->ymax) return 0; } } @@ -187,15 +244,20 @@ static int console_draw_string( char *str, int str_len, if(bg) { glColor3ub(bg[0], bg[1], bg[2]); - glRecti(0, *y-rct_ofs, winx, *y+lheight-rct_ofs); + glRecti(0, cdc->xy[1]-rct_ofs, cdc->winx, cdc->xy[1]+cdc->lheight-rct_ofs); } glColor3ub(fg[0], fg[1], fg[2]); - BLF_position(*x, *y, 0); (*y) += lheight; + BLF_position(cdc->xy[0], cdc->xy[1], 0); BLF_draw(str); - if(*y > ymax) + if(cdc->sel[0] != cdc->sel[1]) + console_draw_sel(cdc->sel, cdc->xy, str_len, cdc->cwidth, cdc->console_width, cdc->lheight); + + cdc->xy[1] += cdc->lheight; + + if(cdc->xy[1] > cdc->ymax) return 0; } @@ -205,32 +267,54 @@ static int console_draw_string( char *str, int str_len, #define CONSOLE_DRAW_MARGIN 4 #define CONSOLE_DRAW_SCROLL 16 -static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports, int draw, int mouse_y, void **mouse_pick) +static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports, int draw, int mval[2], void **mouse_pick, int *pos_pick) { View2D *v2d= &ar->v2d; ConsoleLine *cl= sc->history.last; + ConsoleDrawContext cdc; int x_orig=CONSOLE_DRAW_MARGIN, y_orig=CONSOLE_DRAW_MARGIN; - int x,y, y_prev; + int xy[2], y_prev; int cwidth; int console_width; /* number of characters that fit into the width of the console (fixed width) */ + int sel[2]= {-1, -1}; /* defaults disabled */ unsigned char fg[3]; - + console_font_begin(sc); cwidth = BLF_fixed_width(); console_width= (ar->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN*2) )/cwidth; if (console_width < 8) console_width= 8; - x= x_orig; y= y_orig; + xy[0]= x_orig; xy[1]= y_orig; - if(mouse_y != INT_MAX) - mouse_y += (v2d->cur.ymin+CONSOLE_DRAW_MARGIN); - + if(mval[1] != INT_MAX) + mval[1] += (v2d->cur.ymin + CONSOLE_DRAW_MARGIN); + + if(pos_pick) + *pos_pick = 0; + + /* constants for the sequencer context */ + cdc.cwidth= cwidth; + cdc.lheight= sc->lheight; + cdc.console_width= console_width; + cdc.winx= ar->winx-(CONSOLE_DRAW_MARGIN+CONSOLE_DRAW_SCROLL); + cdc.ymin= v2d->cur.ymin; + cdc.ymax= v2d->cur.ymax; + cdc.xy= xy; + cdc.sel= sel; + cdc.pos_pick= pos_pick; + cdc.mval= mval; + cdc.draw= draw; if(sc->type==CONSOLE_TYPE_PYTHON) { int prompt_len; + + if(sc->sel_start != sc->sel_end) { + sel[0]= sc->sel_start; + sel[1]= sc->sel_end; + } /* text */ if(draw) { @@ -240,42 +324,36 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion * /* command line */ if(prompt_len) { - BLF_position(x, y, 0); x += cwidth * prompt_len; + BLF_position(xy[0], xy[1], 0); xy[0] += cwidth * prompt_len; BLF_draw(sc->prompt); } - BLF_position(x, y, 0); + BLF_position(xy[0], xy[1], 0); BLF_draw(cl->line); /* cursor */ console_line_color(fg, CONSOLE_LINE_ERROR); /* lazy */ glColor3ub(fg[0], fg[1], fg[2]); - glRecti(x+(cwidth*cl->cursor) -1, y-2, x+(cwidth*cl->cursor) +1, y+sc->lheight-2); + glRecti(xy[0]+(cwidth*cl->cursor) -1, xy[1]-2, xy[0]+(cwidth*cl->cursor) +1, xy[1]+sc->lheight-2); - x= x_orig; /* remove prompt offset */ + xy[0]= x_orig; /* remove prompt offset */ } - y += sc->lheight; + xy[1] += sc->lheight; for(cl= sc->scrollback.last; cl; cl= cl->prev) { - y_prev= y; + y_prev= xy[1]; if(draw) console_line_color(fg, cl->type); - if(!console_draw_string( cl->line, cl->len, - console_width, sc->lheight, - fg, NULL, - ar->winx-(CONSOLE_DRAW_MARGIN+CONSOLE_DRAW_SCROLL), - v2d->cur.ymin, v2d->cur.ymax, - &x, &y, draw)) - { + if(!console_draw_string(&cdc, cl->line, cl->len, fg, NULL)) { /* when drawing, if we pass v2d->cur.ymax, then quit */ if(draw) { break; /* past the y limits */ } } - if((mouse_y != INT_MAX) && (mouse_y >= y_prev && mouse_y <= y)) { + if((mval[1] != INT_MAX) && (mval[1] >= y_prev && mval[1] <= xy[1])) { *mouse_pick= (void *)cl; break; } @@ -298,24 +376,18 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion * for(report=reports->list.last; report; report=report->prev) { if(report->type & report_mask) { - y_prev= y; + y_prev= xy[1]; if(draw) console_report_color(fg, bg, report, bool); - if(!console_draw_string( report->message, report->len, - console_width, sc->lheight, - fg, bg, - ar->winx-(CONSOLE_DRAW_MARGIN+CONSOLE_DRAW_SCROLL), - v2d->cur.ymin, v2d->cur.ymax, - &x, &y, draw)) - { + if(!console_draw_string(&cdc, report->message, report->len, fg, bg)) { /* when drawing, if we pass v2d->cur.ymax, then quit */ if(draw) { break; /* past the y limits */ } } - if((mouse_y != INT_MAX) && (mouse_y >= y_prev && mouse_y <= y)) { + if((mval[1] != INT_MAX) && (mval[1] >= y_prev && mval[1] <= xy[1])) { *mouse_pick= (void *)report; break; } @@ -324,25 +396,37 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion * } } } - y += sc->lheight*2; + xy[1] += sc->lheight*2; - return y-y_orig; + return xy[1]-y_orig; } void console_text_main(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports) { - console_text_main__internal(sc, ar, reports, 1, INT_MAX, NULL); + int mval[2] = {INT_MAX, INT_MAX}; + console_text_main__internal(sc, ar, reports, 1, mval, NULL, NULL); } int console_text_height(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports) { - return console_text_main__internal(sc, ar, reports, 0, INT_MAX, NULL); + int mval[2] = {INT_MAX, INT_MAX}; + return console_text_main__internal(sc, ar, reports, 0, mval, NULL, NULL); } void *console_text_pick(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports, int mouse_y) { + int mval[2] = {0, mouse_y}; void *mouse_pick= NULL; - console_text_main__internal(sc, ar, reports, 0, mouse_y, &mouse_pick); + console_text_main__internal(sc, ar, reports, 0, mval, &mouse_pick, NULL); return (void *)mouse_pick; } + +// XXX - breaks with line wrap +int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports, int mval[2]) +{ + int pos_pick= 0; + void *mouse_pick= NULL; + console_text_main__internal(sc, ar, reports, 0, mval, &mouse_pick, &pos_pick); + return pos_pick; +} diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h index 889ed2dae81..92ab3eb3d0c 100644 --- a/source/blender/editors/space_console/console_intern.h +++ b/source/blender/editors/space_console/console_intern.h @@ -39,6 +39,7 @@ struct bContext; void console_text_main(struct SpaceConsole *sc, struct ARegion *ar, struct ReportList *reports); int console_text_height(struct SpaceConsole *sc, struct ARegion *ar, struct ReportList *reports); /* needed to calculate the scrollbar */ void *console_text_pick(struct SpaceConsole *sc, struct ARegion *ar, struct ReportList *reports, int mouse_y); /* needed for selection */ +int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports, int mval[2]); /* console_ops.c */ void console_history_free(SpaceConsole *sc, ConsoleLine *cl); @@ -63,6 +64,8 @@ void CONSOLE_OT_history_cycle(struct wmOperatorType *ot); void CONSOLE_OT_copy(struct wmOperatorType *ot); void CONSOLE_OT_paste(struct wmOperatorType *ot); void CONSOLE_OT_zoom(struct wmOperatorType *ot); +void CONSOLE_OT_select_set(struct wmOperatorType *ot); + /* console_report.c */ diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 89c058ad7f3..e615ae8f140 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -675,6 +675,7 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot) static int copy_exec(bContext *C, wmOperator *op) { SpaceConsole *sc= CTX_wm_space_console(C); + int buf_len; DynStr *buf_dyn= BLI_dynstr_new(); char *buf_str; @@ -687,8 +688,16 @@ static int copy_exec(bContext *C, wmOperator *op) } buf_str= BLI_dynstr_get_cstring(buf_dyn); + buf_len= BLI_dynstr_get_len(buf_dyn); BLI_dynstr_free(buf_dyn); + /* hack for selection */ +#if 0 + if(sc->sel_start != sc->sel_end) { + buf_str[buf_len - sc->sel_start]= '\0'; + WM_clipboard_text_set(buf_str+(buf_len - sc->sel_end), 0); + } +#endif WM_clipboard_text_set(buf_str, 0); MEM_freeN(buf_str); @@ -772,3 +781,115 @@ void CONSOLE_OT_zoom(wmOperatorType *ot) /* properties */ RNA_def_int(ot->srna, "delta", 0, 0, INT_MAX, "Delta", "Scale the view font.", 0, 1000); } + +typedef struct SetConsoleCursor { + int sel_old[2]; + int sel_init; +} SetConsoleCursor; + +static void set_cursor_to_pos(SpaceConsole *sc, ARegion *ar, SetConsoleCursor *scu, int mval[2], int sel) +{ + int pos; + pos= console_char_pick(sc, ar, NULL, mval); + + if(scu->sel_init == INT_MAX) { + scu->sel_init= pos; + sc->sel_start = sc->sel_end = pos; + return; + } + + if (pos < scu->sel_init) { + sc->sel_start = pos; + sc->sel_end = scu->sel_init; + } + else if (pos > sc->sel_start) { + sc->sel_start = scu->sel_init; + sc->sel_end = pos; + } + else { + sc->sel_start = sc->sel_end = pos; + } +} + +static void console_modal_select_apply(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + ARegion *ar= CTX_wm_region(C); + SetConsoleCursor *scu= op->customdata; + int mval[2] = {event->mval[0], event->mval[1]}; + + set_cursor_to_pos(sc, ar, scu, mval, TRUE); + ED_area_tag_redraw(CTX_wm_area(C)); +} + +static void set_cursor_exit(bContext *C, wmOperator *op) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + SetConsoleCursor *scu= op->customdata; + + /* + if(txt_has_sel(text)) { + buffer = txt_sel_to_buf(text); + WM_clipboard_text_set(buffer, 1); + MEM_freeN(buffer); + }*/ + + MEM_freeN(scu); +} + +static int console_modal_select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + ARegion *ar= CTX_wm_region(C); + SetConsoleCursor *scu; + + op->customdata= MEM_callocN(sizeof(SetConsoleCursor), "SetConsoleCursor"); + scu= op->customdata; + + scu->sel_old[0]= sc->sel_start; + scu->sel_old[1]= sc->sel_end; + + scu->sel_init = INT_MAX; + + WM_event_add_modal_handler(C, op); + + console_modal_select_apply(C, op, event); + + return OPERATOR_RUNNING_MODAL; +} + +static int console_modal_select(bContext *C, wmOperator *op, wmEvent *event) +{ + switch(event->type) { + case LEFTMOUSE: + case MIDDLEMOUSE: + case RIGHTMOUSE: + set_cursor_exit(C, op); + return OPERATOR_FINISHED; + case MOUSEMOVE: + console_modal_select_apply(C, op, event); + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int console_modal_select_cancel(bContext *C, wmOperator *op) +{ + set_cursor_exit(C, op); + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_select_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Selection"; + ot->idname= "CONSOLE_OT_select_set"; + ot->description= "Set the console selection."; + + /* api callbacks */ + ot->invoke= console_modal_select_invoke; + ot->modal= console_modal_select; + ot->cancel= console_modal_select_cancel; + ot->poll= console_poll; +} diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 7d23421c5cf..f4058f4eefb 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -208,7 +208,7 @@ void console_operatortypes(void) WM_operatortype_append(CONSOLE_OT_copy); WM_operatortype_append(CONSOLE_OT_paste); WM_operatortype_append(CONSOLE_OT_zoom); - + WM_operatortype_append(CONSOLE_OT_select_set); /* console_report.c */ WM_operatortype_append(CONSOLE_OT_select_pick); @@ -287,6 +287,7 @@ void console_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CONSOLE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "CONSOLE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_select_set", LEFTMOUSE, KM_PRESS, 0, 0); RNA_string_set(WM_keymap_add_item(keymap, "CONSOLE_OT_insert", TABKEY, KM_PRESS, 0, 0)->ptr, "text", " "); /* fake tabs */ WM_keymap_add_item(keymap, "CONSOLE_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last! |