diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/SConscript | 1 | ||||
-rw-r--r-- | source/blender/editors/include/ED_space_api.h | 1 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_api/spacetypes.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_console/SConscript | 13 | ||||
-rw-r--r-- | source/blender/editors/space_console/console_draw.c | 214 | ||||
-rw-r--r-- | source/blender/editors/space_console/console_intern.h | 75 | ||||
-rw-r--r-- | source/blender/editors/space_console/console_ops.c | 570 | ||||
-rw-r--r-- | source/blender/editors/space_console/space_console.c | 336 |
9 files changed, 1212 insertions, 0 deletions
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index 9baaf7ae7a5..d7bb567e3eb 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -30,6 +30,7 @@ SConscript(['datafiles/SConscript', 'space_text/SConscript', 'space_sequencer/SConscript', 'space_logic/SConscript', + 'space_console/SConscript', 'transform/SConscript', 'screen/SConscript', 'sculpt_paint/SConscript', diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h index f2b46369d13..efaf0f56f92 100644 --- a/source/blender/editors/include/ED_space_api.h +++ b/source/blender/editors/include/ED_space_api.h @@ -51,6 +51,7 @@ void ED_spacetype_script(void); void ED_spacetype_text(void); void ED_spacetype_sequencer(void); void ED_spacetype_logic(void); +void ED_spacetype_console(void); /* calls for instancing and freeing spacetype static data called in WM_init_exit */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index addda6e02ee..9617a1fbea2 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1059,6 +1059,7 @@ static char *windowtype_pup(void) "|%l" //293 "|Scripts Window %x14"//313 + "|Console %x18" ); } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index c8df9bb9741..5a55c5fb717 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -75,6 +75,7 @@ void ED_spacetypes_init(void) ED_spacetype_text(); ED_spacetype_sequencer(); ED_spacetype_logic(); + ED_spacetype_console(); // ... /* register operator types for screen and all spaces */ diff --git a/source/blender/editors/space_console/SConscript b/source/blender/editors/space_console/SConscript new file mode 100644 index 00000000000..a29c17f6937 --- /dev/null +++ b/source/blender/editors/space_console/SConscript @@ -0,0 +1,13 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') +defs = [] +incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' +incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' +incs += ' ../../python ../../makesrna ../../blenfont' + +if not env['WITH_BF_PYTHON']: + defs.append('DISABLE_PYTHON') + +env.BlenderLib ( 'bf_editors_space_console', sources, Split(incs), defs, libtype=['core'], priority=[95] ) diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c new file mode 100644 index 00000000000..042c84041d0 --- /dev/null +++ b/source/blender/editors/space_console/console_draw.c @@ -0,0 +1,214 @@ +/** + * $Id: text_draw.c 21558 2009-07-13 11:41:24Z campbellbarton $ + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +#include "MEM_guardedalloc.h" + +#include "BLF_api.h" + +#include "BLI_blenlib.h" + +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_global.h" +#include "BKE_main.h" +// #include "BKE_suggestions.h" +#include "BKE_text.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "ED_datafiles.h" +#include "UI_interface.h" +#include "UI_resources.h" + +//#include "console_intern.h" + +static void console_font_begin(SpaceConsole *sc) +{ + static int mono= -1; // XXX needs proper storage + + if(mono == -1) + mono= BLF_load_mem("monospace", (unsigned char*)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); + + BLF_set(mono); + BLF_aspect(1.0); + + BLF_size(sc->lheight, 72); +} + +static void console_line_color(int type) +{ + switch(type){ + case CONSOLE_LINE_OUTPUT: + glColor4ub(96, 128, 255, 255); + break; + case CONSOLE_LINE_INPUT: + glColor4ub(255, 255, 255, 255); + break; + case CONSOLE_LINE_INFO: + glColor4ub(0, 170, 0, 255); + break; + case CONSOLE_LINE_ERROR: + glColor4ub(220, 96, 96, 255); + break; + } +} + +static void console_report_color(int type) +{ + if(type & RPT_ERROR_ALL) return glColor4ub(220, 0, 0, 255); + if(type & RPT_WARNING_ALL) return glColor4ub(220, 96, 96, 255); + if(type & RPT_OPERATOR_ALL) return glColor4ub(96, 128, 255, 255); + if(type & RPT_INFO_ALL) return glColor4ub(0, 170, 0, 255); + if(type & RPT_DEBUG_ALL) return glColor4ub(196, 196, 196, 255); + return glColor4ub(196, 196, 196, 255); /* unknown */ +} + + +/* 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, int ymax, int *x, int *y) +{ + if(str_len > console_width) { /* wrap? */ + int tot_lines = (str_len/console_width)+1; /* total number of lines for wrapping */ + char *line_stride= str + ((tot_lines-1) * console_width); /* advance to the last line and draw it first */ + char eol; /* baclup the end of wrapping */ + + /* last part needs no clipping */ + BLF_position(*x, *y, 0); (*y) += lheight; + BLF_draw(line_stride); + line_stride -= console_width; + + for(; line_stride >= str; line_stride -= console_width) { + eol = line_stride[console_width]; + line_stride[console_width]= '\0'; + + BLF_position(*x, *y, 0); (*y) += lheight; + BLF_draw(line_stride); + + line_stride[console_width] = eol; /* restore */ + + /* check if were out of view bounds */ + if(*y > ymax) + return 0; + } + } + else { /* simple, no wrap */ + BLF_position(*x, *y, 0); (*y) += lheight; + BLF_draw(str); + + if(*y > ymax) + return 0; + } + + return 1; +} + +#define CONSOLE_DRAW_MARGIN 8 + +void console_text_main(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports) +{ + ConsoleLine *cl= sc->history.last; + + int x_orig=CONSOLE_DRAW_MARGIN, y_orig=CONSOLE_DRAW_MARGIN; + int x,y; + int cwidth; + int console_width; /* number of characters that fit into the width of the console (fixed width) */ + + + console_font_begin(sc); + cwidth = BLF_fixed_width(); + + console_width= (ar->winx - CONSOLE_DRAW_MARGIN*2)/cwidth; + if (console_width < 8) console_width= 8; + + x= x_orig; y= y_orig; + + if(sc->type==CONSOLE_TYPE_PYTHON) { + int prompt_len= strlen(sc->prompt); + + /* text */ + console_line_color(CONSOLE_LINE_INPUT); + + /* command line */ + if(prompt_len) { + BLF_position(x, y, 0); x += cwidth * prompt_len; + BLF_draw(sc->prompt); + } + BLF_position(x, y, 0); + BLF_draw(cl->line); + + /* cursor */ + console_line_color(CONSOLE_LINE_ERROR); /* lazy */ + glRecti(x+(cwidth*cl->cursor) -1, y-2, x+(cwidth*cl->cursor) +1, y+sc->lheight-2); + + x= x_orig; /* remove prompt offset */ + + y += sc->lheight; + + for(cl= sc->scrollback.last; cl; cl= cl->prev) { + console_line_color(cl->type); + + if(!console_draw_string(cl->line, cl->len, console_width, sc->lheight, ar->winy + sc->lheight, &x, &y)) + break; /* past the y limits */ + + } + } + else { + Report *report; + int report_mask= 0; + + /* convert our display toggles into a flag compatible with BKE_report flags */ + if(sc->rpt_mask & CONSOLE_RPT_DEBUG) report_mask |= RPT_DEBUG_ALL; + if(sc->rpt_mask & CONSOLE_RPT_INFO) report_mask |= RPT_INFO_ALL; + if(sc->rpt_mask & CONSOLE_RPT_OP) report_mask |= RPT_OPERATOR_ALL; + if(sc->rpt_mask & CONSOLE_RPT_WARN) report_mask |= RPT_WARNING_ALL; + if(sc->rpt_mask & CONSOLE_RPT_ERR) report_mask |= RPT_ERROR_ALL; + + for(report=reports->list.last; report; report=report->prev) { + + if(report->type & report_mask) { + console_report_color(report->type); + if(!console_draw_string(report->message, strlen(report->message), console_width, sc->lheight, ar->winy + sc->lheight, &x, &y)) + break; /* past the y limits */ + } + + } + } + +} diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h new file mode 100644 index 00000000000..55474844d87 --- /dev/null +++ b/source/blender/editors/space_console/console_intern.h @@ -0,0 +1,75 @@ +/** + * $Id: + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef ED_CONSOLE_INTERN_H +#define ED_CONSOLE_INTERN_H + +/* internal exports only */ + +struct ConsoleLine; +struct wmOperatorType; +struct ReportList; + +/* TODO, make into a pref */ +#define CONSOLE_SCROLLBACK_LIMIT 128 + +/* console_draw.c */ +void console_text_main(struct SpaceConsole *sc, struct ARegion *ar, struct ReportList *reports); + +/* console_ops.c */ +void console_history_free(SpaceConsole *sc, ConsoleLine *cl); +void console_scrollback_free(SpaceConsole *sc, ConsoleLine *cl); +ConsoleLine *console_history_add_str(const bContext *C, char *str, int own); +ConsoleLine *console_scrollback_add_str(const bContext *C, char *str, int own); + +ConsoleLine *console_history_verify(const bContext *C); + + +void CONSOLE_OT_move(wmOperatorType *ot); +void CONSOLE_OT_delete(wmOperatorType *ot); +void CONSOLE_OT_insert(wmOperatorType *ot); + +void CONSOLE_OT_history_append(wmOperatorType *ot); +void CONSOLE_OT_scrollback_append(wmOperatorType *ot); + +void CONSOLE_OT_clear(wmOperatorType *ot); +void CONSOLE_OT_history_cycle(wmOperatorType *ot); +void CONSOLE_OT_zoom(wmOperatorType *ot); + +enum { LINE_BEGIN, LINE_END, PREV_CHAR, NEXT_CHAR, PREV_WORD, NEXT_WORD }; +enum { DEL_ALL, DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL }; + +/* defined in DNA_space_types.h */ +static EnumPropertyItem console_line_type_items[] = { + {CONSOLE_LINE_OUTPUT, "OUTPUT", 0, "Output", ""}, + {CONSOLE_LINE_INPUT, "INPUT", 0, "Input", ""}, + {CONSOLE_LINE_INFO, "INFO", 0, "Information", ""}, + {CONSOLE_LINE_ERROR, "ERROR", 0, "Error", ""}, + {0, NULL, 0, NULL, NULL}}; + +#endif /* ED_CONSOLE_INTERN_H */ + diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c new file mode 100644 index 00000000000..cb883d2d450 --- /dev/null +++ b/source/blender/editors/space_console/console_ops.c @@ -0,0 +1,570 @@ +/** + * $Id: text_ops.c 21549 2009-07-12 12:47:34Z campbellbarton $ + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> /* ispunct */ +#include <sys/stat.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_windowmanager_types.h" + +#include "BLI_blenlib.h" +#include "PIL_time.h" + +#include "BKE_utildefines.h" +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_report.h" +// #include "BKE_suggestions.h" +//#include "BKE_text.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "console_intern.h" + +void console_history_free(SpaceConsole *sc, ConsoleLine *cl) +{ + BLI_remlink(&sc->history, cl); + MEM_freeN(cl->line); + MEM_freeN(cl); +} +void console_scrollback_free(SpaceConsole *sc, ConsoleLine *cl) +{ + BLI_remlink(&sc->scrollback, cl); + MEM_freeN(cl->line); + MEM_freeN(cl); +} + +void console_scrollback_limit(SpaceConsole *sc) +{ + int tot; + for(tot= BLI_countlist(&sc->scrollback); tot > CONSOLE_SCROLLBACK_LIMIT; tot--) + console_scrollback_free(sc, sc->scrollback.first); +} + +/* return 0 if no change made, clamps the range */ +static int console_line_cursor_set(ConsoleLine *cl, int cursor) +{ + int cursor_new; + + if(cursor < 0) cursor_new= 0; + else if(cursor > cl->len) cursor_new= cl->len; + else cursor_new= cursor; + + if(cursor_new == cl->cursor) + return 0; + + cl->cursor= cursor_new; + return 1; +} + +static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from) +{ + ConsoleLine *ci= MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add"); + + if(from) { + ci->line= BLI_strdup(from->line); + ci->len= strlen(ci->line); + ci->len_alloc= ci->len; + + ci->cursor= from->cursor; + ci->type= from->type; + } else { + ci->line= MEM_callocN(64, "console-in-line"); + ci->len_alloc= 64; + ci->len= 0; + } + + BLI_addtail(lb, ci); + return ci; +} + +static ConsoleLine *console_history_add(const bContext *C, ConsoleLine *from) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + + return console_lb_add__internal(&sc->history, from); +} + +static ConsoleLine *console_scrollback_add(const bContext *C, ConsoleLine *from) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + + return console_lb_add__internal(&sc->scrollback, from); +} + +static ConsoleLine *console_lb_add_str__internal(ListBase *lb, const bContext *C, char *str, int own) +{ + ConsoleLine *ci= MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add"); + if(own) ci->line= str; + else ci->line= BLI_strdup(str); + + ci->len = ci->len_alloc = strlen(str); + + BLI_addtail(lb, ci); + return ci; +} +ConsoleLine *console_history_add_str(const bContext *C, char *str, int own) +{ + return console_lb_add_str__internal(&CTX_wm_space_console(C)->history, C, str, own); +} +ConsoleLine *console_scrollback_add_str(const bContext *C, char *str, int own) +{ + return console_lb_add_str__internal(&CTX_wm_space_console(C)->scrollback, C, str, own); +} + +ConsoleLine *console_history_verify(const bContext *C) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + ConsoleLine *ci= sc->history.last; + if(ci==NULL) + ci= console_history_add(C, NULL); + + return ci; +} + + +static void console_line_verify_length(ConsoleLine *ci, int len) +{ + /* resize the buffer if needed */ + if(len > ci->len_alloc) { + int new_len= len * 2; /* new length */ + char *new_line= MEM_callocN(new_len, "console line"); + memcpy(new_line, ci->line, ci->len); + MEM_freeN(ci->line); + + ci->line= new_line; + ci->len_alloc= new_len; + } +} + +static int console_line_insert(ConsoleLine *ci, char *str) +{ + int len = strlen(str); + + if(len==0) + return 0; + + console_line_verify_length(ci, len + ci->len); + + memmove(ci->line+ci->cursor+len, ci->line+ci->cursor, (ci->len - ci->cursor)+1); + memcpy(ci->line+ci->cursor, str, len); + + ci->len += len; + ci->cursor += len; + + return len; +} + +static int console_edit_poll(const bContext *C) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + + if(!sc || sc->type != CONSOLE_TYPE_PYTHON) + return 0; + + return 1; +} + +/* static funcs for text editing */ + + +/* similar to the text editor, with some not used. keep compatible */ +static EnumPropertyItem move_type_items[]= { + {LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""}, + {LINE_END, "LINE_END", 0, "Line End", ""}, + {PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""}, + {NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""}, + {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""}, + {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""}, + {0, NULL, 0, NULL, NULL}}; + +static int move_exec(const bContext *C, wmOperator *op) +{ + ConsoleLine *ci= console_history_verify(C); + + int type= RNA_enum_get(op->ptr, "type"); + int done= 0; + + switch(type) { + case LINE_BEGIN: + done= console_line_cursor_set(ci, 0); + break; + case LINE_END: + done= console_line_cursor_set(ci, INT_MAX); + break; + case PREV_CHAR: + done= console_line_cursor_set(ci, ci->cursor-1); + break; + case NEXT_CHAR: + done= console_line_cursor_set(ci, ci->cursor+1); + break; + } + + if(done) { + ED_area_tag_redraw(CTX_wm_area(C)); + } + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_move(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Move Cursor"; + ot->idname= "CONSOLE_OT_move"; + + /* api callbacks */ + ot->exec= move_exec; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_enum(ot->srna, "type", move_type_items, LINE_BEGIN, "Type", "Where to move cursor to."); +} + + +static int insert_exec(const bContext *C, wmOperator *op) +{ + ConsoleLine *ci= console_history_verify(C); + char *str= RNA_string_get_alloc(op->ptr, "text", NULL, 0); + + int len= console_line_insert(ci, str); + + MEM_freeN(str); + + if(len==0) + return OPERATOR_CANCELLED; + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +static int insert_invoke(const bContext *C, wmOperator *op, wmEvent *event) +{ + char str[2] = {event->ascii, '\0'}; + RNA_string_set(op->ptr, "text", str); + return insert_exec(C, op); +} + +void CONSOLE_OT_insert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Insert"; + ot->idname= "CONSOLE_OT_insert"; + + /* api callbacks */ + ot->exec= insert_exec; + ot->invoke= insert_invoke; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_string(ot->srna, "text", "", 0, "Text", "Text to insert at the cursor position."); +} + + +static EnumPropertyItem delete_type_items[]= { + {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""}, + {DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""}, +// {DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""}, +// {DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""}, + {0, NULL, 0, NULL, NULL}}; + +static int delete_exec(const bContext *C, wmOperator *op) +{ + + ConsoleLine *ci= console_history_verify(C); + + + int done = 0; + + int type= RNA_enum_get(op->ptr, "type"); + + if(ci->len==0) { + return OPERATOR_CANCELLED; + } + + switch(type) { + case DEL_NEXT_CHAR: + if(ci->cursor < ci->len) { + memmove(ci->line + ci->cursor, ci->line + ci->cursor+1, (ci->len - ci->cursor)+1); + ci->len--; + done= 1; + } + break; + case DEL_PREV_CHAR: + if(ci->cursor > 0) { + ci->cursor--; /* same as above */ + memmove(ci->line + ci->cursor, ci->line + ci->cursor+1, (ci->len - ci->cursor)+1); + ci->len--; + done= 1; + } + break; + } + + if(!done) + return OPERATOR_CANCELLED; + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + + +void CONSOLE_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete"; + ot->idname= "CONSOLE_OT_delete"; + + /* api callbacks */ + ot->exec= delete_exec; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_enum(ot->srna, "type", delete_type_items, DEL_NEXT_CHAR, "Type", "Which part of the text to delete."); +} + + +/* the python exec operator uses this */ +static int clear_exec(const bContext *C, wmOperator *op) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + + short scrollback= RNA_boolean_get(op->ptr, "scrollback"); + short history= RNA_boolean_get(op->ptr, "history"); + + /*ConsoleLine *ci= */ console_history_verify(C); + + if(scrollback) { /* last item in mistory */ + while(sc->scrollback.first) + console_scrollback_free(sc, sc->scrollback.first); + } + + if(history) { + while(sc->history.first) + console_history_free(sc, sc->history.first); + } + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear"; + ot->idname= "CONSOLE_OT_clear"; + + /* api callbacks */ + ot->exec= clear_exec; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_boolean(ot->srna, "scrollback", 1, "Scrollback", "Clear the scrollback history"); + RNA_def_boolean(ot->srna, "history", 0, "History", "Clear the command history"); +} + + + +/* the python exec operator uses this */ +static int history_cycle_exec(const bContext *C, wmOperator *op) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + ConsoleLine *ci= console_history_verify(C); /* TODO - stupid, just prevernts crashes when no command line */ + + short reverse= RNA_boolean_get(op->ptr, "reverse"); /* assumes down, reverse is up */ + + if(reverse) { /* last item in mistory */ + ci= sc->history.last; + BLI_remlink(&sc->history, ci); + BLI_addhead(&sc->history, ci); + } + else { + ci= sc->history.first; + BLI_remlink(&sc->history, ci); + BLI_addtail(&sc->history, ci); + } + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_history_cycle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "History Cycle"; + ot->idname= "CONSOLE_OT_history_cycle"; + + /* api callbacks */ + ot->exec= history_cycle_exec; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_boolean(ot->srna, "reverse", 0, "Reverse", "reverse cycle history"); +} + + +/* the python exec operator uses this */ +static int history_append_exec(const bContext *C, wmOperator *op) +{ + ConsoleLine *ci= console_history_verify(C); + + + char *str= RNA_string_get_alloc(op->ptr, "text", NULL, 0); /* own this text in the new line, dont free */ + int cursor= RNA_int_get(op->ptr, "current_character"); + + ci= console_history_add_str(C, str, 1); /* own the string */ + console_line_cursor_set(ci, cursor); + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_history_append(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "History Append"; + ot->idname= "CONSOLE_OT_history_append"; + + /* api callbacks */ + ot->exec= history_append_exec; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_string(ot->srna, "text", "", 0, "Text", "Text to insert at the cursor position."); + RNA_def_int(ot->srna, "current_character", 0, 0, INT_MAX, "Cursor", "The index of the cursor.", 0, 10000); +} + + +/* the python exec operator uses this */ +static int scrollback_append_exec(const bContext *C, wmOperator *op) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + ConsoleLine *ci= console_history_verify(C); + + char *str= RNA_string_get_alloc(op->ptr, "text", NULL, 0); /* own this text in the new line, dont free */ + int type= RNA_enum_get(op->ptr, "type"); + + ci= console_scrollback_add_str(C, str, 1); /* own the string */ + ci->type= type; + + console_scrollback_limit(sc); + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_scrollback_append(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Scrollback Append"; + ot->idname= "CONSOLE_OT_scrollback_append"; + + /* api callbacks */ + ot->exec= scrollback_append_exec; + ot->poll= console_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_string(ot->srna, "text", "", 0, "Text", "Text to insert at the cursor position."); + RNA_def_enum(ot->srna, "type", console_line_type_items, CONSOLE_LINE_OUTPUT, "Type", "Console output type."); +} + +static int zoom_exec(const bContext *C, wmOperator *op) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + + int delta= RNA_int_get(op->ptr, "delta"); + + sc->lheight += delta; + CLAMP(sc->lheight, 8, 32); + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + + +void CONSOLE_OT_zoom(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Console Zoom"; + ot->idname= "CONSOLE_OT_zoom"; + + /* api callbacks */ + ot->exec= zoom_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER; + + /* properties */ + RNA_def_int(ot->srna, "delta", 0, 0, INT_MAX, "Delta", "Scale the view font.", 0, 1000); +} + diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c new file mode 100644 index 00000000000..ee80fe3d2d9 --- /dev/null +++ b/source/blender/editors/space_console/space_console.c @@ -0,0 +1,336 @@ +/** + * $Id: + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + + #include <string.h> +#include <stdio.h> + +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "ED_space_api.h" +#include "ED_screen.h" + +#include "BIF_gl.h" + + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "console_intern.h" // own include + + +/* ******************** default callbacks for console space ***************** */ + +static SpaceLink *console_new(const bContext *C) +{ + ARegion *ar; + SpaceConsole *sconsole; + + sconsole= MEM_callocN(sizeof(SpaceConsole), "initconsole"); + sconsole->spacetype= SPACE_CONSOLE; + + sconsole->lheight= 14; + sconsole->type= CONSOLE_TYPE_PYTHON; + sconsole->rpt_mask= CONSOLE_RPT_OP; /* ? - not sure whats a good default here?*/ + + /* header */ + ar= MEM_callocN(sizeof(ARegion), "header for console"); + + BLI_addtail(&sconsole->regionbase, ar); + ar->regiontype= RGN_TYPE_HEADER; + ar->alignment= RGN_ALIGN_BOTTOM; + + + /* main area */ + ar= MEM_callocN(sizeof(ARegion), "main area for text"); + + BLI_addtail(&sconsole->regionbase, ar); + ar->regiontype= RGN_TYPE_WINDOW; + + ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM_O); + ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y); + ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT); + ar->v2d.keeptot= V2D_KEEPTOT_STRICT; + ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f; + + return (SpaceLink *)sconsole; +} + +/* not spacelink itself */ +static void console_free(SpaceLink *sl) +{ + SpaceConsole *sc= (SpaceConsole*) sl; + + while(sc->scrollback.first) + console_scrollback_free(sc, sc->scrollback.first); + + while(sc->history.first) + console_history_free(sc, sc->history.first); +} + + +/* spacetype; init callback */ +static void console_init(struct wmWindowManager *wm, ScrArea *sa) +{ + +} + +static SpaceLink *console_duplicate(SpaceLink *sl) +{ + SpaceConsole *sconsolen= MEM_dupallocN(sl); + + /* clear or remove stuff from old */ + + /* TODO - duplicate?, then we also need to duplicate the py namespace */ + sconsolen->scrollback.first= sconsolen->scrollback.last= NULL; + sconsolen->history.first= sconsolen->history.last= NULL; + + return (SpaceLink *)sconsolen; +} + + + +/* add handlers, stuff you only do once or on area/region changes */ +static void console_main_area_init(wmWindowManager *wm, ARegion *ar) +{ + ListBase *keymap; + + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); + + /* own keymap */ + keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0); /* XXX weak? */ + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); +} + +static void console_main_area_draw(const bContext *C, ARegion *ar) +{ + /* draw entirely, view changes should be handled here */ + SpaceConsole *sc= CTX_wm_space_console(C); + //View2D *v2d= &ar->v2d; + //float col[3]; + + /* clear and setup matrix */ + //UI_GetThemeColor3fv(TH_BACK, col); + //glClearColor(col[0], col[1], col[2], 0.0); + glClearColor(0, 0, 0, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + + /* worlks best with no view2d matrix set */ + /*UI_view2d_view_ortho(C, v2d);*/ + + /* data... */ + + /* add helper text, why not? */ + if(sc->scrollback.first==NULL) { + console_scrollback_add_str(C, " * Python Interactive Console *", 0); + console_scrollback_add_str(C, "Command History: Up/Down Arrow", 0); + console_scrollback_add_str(C, "Cursor: Left/Right Home/End", 0); + console_scrollback_add_str(C, "Remove: Backspace/Delete", 0); + console_scrollback_add_str(C, "Execute: Enter", 0); + console_scrollback_add_str(C, "Autocomplete: Tab", 0); + console_scrollback_add_str(C, "Ctrl +/- Wheel: Zoom", 0); + console_scrollback_add_str(C, "Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.ui", 0); + } + + console_history_verify(C); /* make sure we have some command line */ + console_text_main(sc, ar, CTX_wm_reports(C)); + + /* reset view matrix */ + /* UI_view2d_view_restore(C); */ + + /* scrollers */ + /* + scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + UI_view2d_scrollers_draw(C, v2d, scrollers); + UI_view2d_scrollers_free(scrollers); + */ +} + +void console_operatortypes(void) +{ + WM_operatortype_append(CONSOLE_OT_move); + WM_operatortype_append(CONSOLE_OT_delete); + WM_operatortype_append(CONSOLE_OT_insert); + + /* for use by python only */ + WM_operatortype_append(CONSOLE_OT_history_append); + WM_operatortype_append(CONSOLE_OT_scrollback_append); + + + WM_operatortype_append(CONSOLE_OT_clear); + WM_operatortype_append(CONSOLE_OT_history_cycle); + WM_operatortype_append(CONSOLE_OT_zoom); +} + +void console_keymap(struct wmWindowManager *wm) +{ + ListBase *keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0); + + /* + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", EKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "type", LINE_END); + */ + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1); + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1); + + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR); + + RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", 1); + WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0); + + /* + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_LINE); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_LINE); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_PAGE); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_PAGE); + + + //RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_CHAR); + //RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD); + */ + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR); + +#ifndef DISABLE_PYTHON + WM_keymap_add_item(keymap, "CONSOLE_OT_exec", RETKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */ + WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", TABKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */ +#endif + WM_keymap_add_item(keymap, "CONSOLE_OT_insert", KM_TEXTINPUT, KM_PRESS, KM_ANY, 0); // last! +} + +/****************** header region ******************/ + +/* add handlers, stuff you only do once or on area/region changes */ +static void console_header_area_init(wmWindowManager *wm, ARegion *ar) +{ + ED_region_header_init(ar); +} + +static void console_header_area_draw(const bContext *C, ARegion *ar) +{ + ED_region_header(C, ar); +} + +static void console_main_area_listener(ScrArea *sa, wmNotifier *wmn) +{ + SpaceConsole *sc= sa->spacedata.first; + + /* context changes */ + switch(wmn->category) { + case NC_CONSOLE: + if(wmn->data == ND_CONSOLE) { /* generic redraw request */ + ED_area_tag_redraw(sa); + } + else if(wmn->data == ND_CONSOLE_REPORT && sc->type==CONSOLE_TYPE_REPORT) { + /* redraw also but only for report view, could do less redraws by checking the type */ + ED_area_tag_redraw(sa); + } + break; + } +} + +/* only called once, from space/spacetypes.c */ +void ED_spacetype_console(void) +{ + SpaceType *sc= MEM_callocN(sizeof(SpaceType), "spacetype console"); + ARegionType *art; + + sc->spaceid= SPACE_CONSOLE; + + sc->new= console_new; + sc->free= console_free; + sc->init= console_init; + sc->duplicate= console_duplicate; + sc->operatortypes= console_operatortypes; + sc->keymap= console_keymap; + sc->listener= console_main_area_listener; + + /* regions: main window */ + art= MEM_callocN(sizeof(ARegionType), "spacetype console region"); + art->regionid = RGN_TYPE_WINDOW; + art->init= console_main_area_init; + art->draw= console_main_area_draw; + + + + BLI_addhead(&sc->regiontypes, art); + + /* regions: header */ + art= MEM_callocN(sizeof(ARegionType), "spacetype console region"); + art->regionid = RGN_TYPE_HEADER; + art->minsizey= HEADERY; + art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; + + art->init= console_header_area_init; + art->draw= console_header_area_draw; + + BLI_addhead(&sc->regiontypes, art); + + + + BKE_spacetype_register(sc); +} + + |