4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Campbell Barton
26 * ***** END GPL LICENSE BLOCK *****
33 #include "MEM_guardedalloc.h"
35 #include "BLI_blenlib.h"
38 #include "BKE_colortools.h"
39 #include "BKE_context.h"
40 #include "BKE_screen.h"
42 #include "ED_screen.h"
47 #include "RNA_access.h"
52 #include "UI_resources.h"
53 #include "UI_view2d.h"
55 #include "console_intern.h" // own include
57 static void console_update_rect(const bContext *C, ARegion *ar)
59 SpaceConsole *sc= CTX_wm_space_console(C);
60 View2D *v2d= &ar->v2d;
62 UI_view2d_totRect_set(v2d, ar->winx-1, console_text_height(sc, ar, CTX_wm_reports(C)));
65 /* ******************** default callbacks for console space ***************** */
67 static SpaceLink *console_new(const bContext *C)
70 SpaceConsole *sconsole;
72 sconsole= MEM_callocN(sizeof(SpaceConsole), "initconsole");
73 sconsole->spacetype= SPACE_CONSOLE;
75 sconsole->lheight= 14;
76 sconsole->type= CONSOLE_TYPE_PYTHON;
77 sconsole->rpt_mask= CONSOLE_RPT_OP; /* ? - not sure whats a good default here?*/
80 ar= MEM_callocN(sizeof(ARegion), "header for console");
82 BLI_addtail(&sconsole->regionbase, ar);
83 ar->regiontype= RGN_TYPE_HEADER;
84 ar->alignment= RGN_ALIGN_BOTTOM;
88 ar= MEM_callocN(sizeof(ARegion), "main area for text");
90 BLI_addtail(&sconsole->regionbase, ar);
91 ar->regiontype= RGN_TYPE_WINDOW;
94 ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
95 ar->v2d.align |= V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_NEG_Y; /* align bottom left */
96 ar->v2d.keepofs |= V2D_LOCKOFS_X;
97 ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
98 ar->v2d.keeptot= V2D_KEEPTOT_BOUNDS;
99 ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
101 /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
102 //ar->v2d.keepzoom= (V2D_KEEPASPECT|V2D_LIMITZOOM);
104 return (SpaceLink *)sconsole;
107 /* not spacelink itself */
108 static void console_free(SpaceLink *sl)
110 SpaceConsole *sc= (SpaceConsole*) sl;
112 while(sc->scrollback.first)
113 console_scrollback_free(sc, sc->scrollback.first);
115 while(sc->history.first)
116 console_history_free(sc, sc->history.first);
120 /* spacetype; init callback */
121 static void console_init(struct wmWindowManager *wm, ScrArea *sa)
126 static SpaceLink *console_duplicate(SpaceLink *sl)
128 SpaceConsole *sconsolen= MEM_dupallocN(sl);
130 /* clear or remove stuff from old */
132 /* TODO - duplicate?, then we also need to duplicate the py namespace */
133 sconsolen->scrollback.first= sconsolen->scrollback.last= NULL;
134 sconsolen->history.first= sconsolen->history.last= NULL;
136 return (SpaceLink *)sconsolen;
141 /* add handlers, stuff you only do once or on area/region changes */
142 static void console_main_area_init(wmWindowManager *wm, ARegion *ar)
146 UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
149 keymap= WM_keymap_find(wm->defaultconf, "Console", SPACE_CONSOLE, 0);
150 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
153 static void console_main_area_draw(const bContext *C, ARegion *ar)
155 /* draw entirely, view changes should be handled here */
156 SpaceConsole *sc= CTX_wm_space_console(C);
157 View2D *v2d= &ar->v2d;
158 View2DScrollers *scrollers;
160 if((sc->type==CONSOLE_TYPE_PYTHON) && (sc->scrollback.first==NULL))
161 WM_operator_name_call((bContext *)C, "CONSOLE_OT_banner", WM_OP_EXEC_DEFAULT, NULL);
163 /* clear and setup matrix */
164 UI_ThemeClearColor(TH_BACK);
165 glClear(GL_COLOR_BUFFER_BIT);
167 console_update_rect(C, ar);
169 /* worlks best with no view2d matrix set */
170 UI_view2d_view_ortho(C, v2d);
174 console_history_verify(C); /* make sure we have some command line */
175 console_text_main(sc, ar, CTX_wm_reports(C));
177 /* reset view matrix */
178 UI_view2d_view_restore(C);
181 scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_GRID_CLAMP);
182 UI_view2d_scrollers_draw(C, v2d, scrollers);
183 UI_view2d_scrollers_free(scrollers);
186 void console_operatortypes(void)
189 WM_operatortype_append(CONSOLE_OT_move);
190 WM_operatortype_append(CONSOLE_OT_delete);
191 WM_operatortype_append(CONSOLE_OT_insert);
193 /* for use by python only */
194 WM_operatortype_append(CONSOLE_OT_history_append);
195 WM_operatortype_append(CONSOLE_OT_scrollback_append);
197 WM_operatortype_append(CONSOLE_OT_clear);
198 WM_operatortype_append(CONSOLE_OT_history_cycle);
199 WM_operatortype_append(CONSOLE_OT_copy);
200 WM_operatortype_append(CONSOLE_OT_paste);
201 WM_operatortype_append(CONSOLE_OT_select_set);
203 /* console_report.c */
204 WM_operatortype_append(CONSOLE_OT_select_pick);
205 WM_operatortype_append(CONSOLE_OT_select_all_toggle);
206 WM_operatortype_append(CONSOLE_OT_select_border);
208 WM_operatortype_append(CONSOLE_OT_report_replay);
209 WM_operatortype_append(CONSOLE_OT_report_delete);
210 WM_operatortype_append(CONSOLE_OT_report_copy);
213 void console_keymap(struct wmKeyConfig *keyconf)
215 wmKeyMap *keymap= WM_keymap_find(keyconf, "Console", SPACE_CONSOLE, 0);
219 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
220 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END);
223 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
224 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
226 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
227 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
229 kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
230 RNA_string_set(kmi->ptr, "path", "space_data.font_size");
231 RNA_boolean_set(kmi->ptr, "reverse", 0);
233 kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
234 RNA_string_set(kmi->ptr, "path", "space_data.font_size");
235 RNA_boolean_set(kmi->ptr, "reverse", 1);
237 kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
238 RNA_string_set(kmi->ptr, "path", "space_data.font_size");
239 RNA_boolean_set(kmi->ptr, "reverse", 0);
241 kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
242 RNA_string_set(kmi->ptr, "path", "space_data.font_size");
243 RNA_boolean_set(kmi->ptr, "reverse", 1);
245 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
246 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
248 RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", 1);
249 WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0);
252 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
253 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
254 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_LINE);
255 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_LINE);
256 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_PAGE);
257 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_PAGE);
260 //RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
261 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_CHAR);
262 //RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
263 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
264 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
267 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
268 RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
270 #ifndef DISABLE_PYTHON
271 WM_keymap_add_item(keymap, "CONSOLE_OT_execute", RETKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */
272 WM_keymap_add_item(keymap, "CONSOLE_OT_execute", PADENTER, KM_PRESS, 0, 0);
274 //WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", TABKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */
275 WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0); /* python operator - space_text.py */
278 /* report selection */
279 WM_keymap_add_item(keymap, "CONSOLE_OT_select_pick", SELECTMOUSE, KM_PRESS, 0, 0);
280 WM_keymap_add_item(keymap, "CONSOLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
281 WM_keymap_add_item(keymap, "CONSOLE_OT_select_border", BKEY, KM_PRESS, 0, 0);
283 WM_keymap_add_item(keymap, "CONSOLE_OT_report_replay", RKEY, KM_PRESS, 0, 0);
284 WM_keymap_add_item(keymap, "CONSOLE_OT_report_delete", XKEY, KM_PRESS, 0, 0);
285 WM_keymap_add_item(keymap, "CONSOLE_OT_report_delete", DELKEY, KM_PRESS, 0, 0);
286 WM_keymap_add_item(keymap, "CONSOLE_OT_report_copy", CKEY, KM_PRESS, KM_CTRL, 0);
288 WM_keymap_add_item(keymap, "CONSOLE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
289 WM_keymap_add_item(keymap, "CONSOLE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
291 WM_keymap_add_item(keymap, "CONSOLE_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
292 WM_keymap_add_item(keymap, "CONSOLE_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
295 WM_keymap_add_item(keymap, "CONSOLE_OT_select_set", LEFTMOUSE, KM_PRESS, 0, 0);
297 RNA_string_set(WM_keymap_add_item(keymap, "CONSOLE_OT_insert", TABKEY, KM_PRESS, 0, 0)->ptr, "text", " "); /* fake tabs */
298 WM_keymap_add_item(keymap, "CONSOLE_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
301 /****************** header region ******************/
303 /* add handlers, stuff you only do once or on area/region changes */
304 static void console_header_area_init(wmWindowManager *wm, ARegion *ar)
306 ED_region_header_init(ar);
309 static void console_header_area_draw(const bContext *C, ARegion *ar)
311 ED_region_header(C, ar);
314 static void console_main_area_listener(ScrArea *sa, wmNotifier *wmn)
316 SpaceConsole *sc= sa->spacedata.first;
318 /* context changes */
319 switch(wmn->category) {
321 if(wmn->data == ND_SPACE_CONSOLE) { /* generic redraw request */
322 ED_area_tag_redraw(sa);
324 else if(wmn->data == ND_SPACE_CONSOLE_REPORT && sc->type==CONSOLE_TYPE_REPORT) {
325 /* redraw also but only for report view, could do less redraws by checking the type */
326 ED_area_tag_redraw(sa);
332 /* only called once, from space/spacetypes.c */
333 void ED_spacetype_console(void)
335 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype console");
338 st->spaceid= SPACE_CONSOLE;
339 strncpy(st->name, "Console", BKE_ST_MAXNAME);
341 st->new= console_new;
342 st->free= console_free;
343 st->init= console_init;
344 st->duplicate= console_duplicate;
345 st->operatortypes= console_operatortypes;
346 st->keymap= console_keymap;
347 st->listener= console_main_area_listener;
349 /* regions: main window */
350 art= MEM_callocN(sizeof(ARegionType), "spacetype console region");
351 art->regionid = RGN_TYPE_WINDOW;
352 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
354 art->init= console_main_area_init;
355 art->draw= console_main_area_draw;
360 BLI_addhead(&st->regiontypes, art);
362 /* regions: header */
363 art= MEM_callocN(sizeof(ARegionType), "spacetype console region");
364 art->regionid = RGN_TYPE_HEADER;
365 art->prefsizey= HEADERY;
366 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER;
368 art->init= console_header_area_init;
369 art->draw= console_header_area_draw;
371 BLI_addhead(&st->regiontypes, art);
374 BKE_spacetype_register(st);