Console Space Type
[blender.git] / source / blender / editors / space_console / space_console.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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. 
10  *
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.
15  *
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Campbell Barton
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28  
29  #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_space_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_screen_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_arithb.h"
40
41 #include "BKE_colortools.h"
42 #include "BKE_context.h"
43 #include "BKE_screen.h"
44
45 #include "ED_space_api.h"
46 #include "ED_screen.h"
47
48 #include "BIF_gl.h"
49
50
51 #include "RNA_access.h"
52 #include "RNA_define.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "UI_interface.h"
58 #include "UI_resources.h"
59 #include "UI_view2d.h"
60
61 #include "console_intern.h"     // own include
62
63
64 /* ******************** default callbacks for console space ***************** */
65
66 static SpaceLink *console_new(const bContext *C)
67 {
68         ARegion *ar;
69         SpaceConsole *sconsole;
70         
71         sconsole= MEM_callocN(sizeof(SpaceConsole), "initconsole");
72         sconsole->spacetype= SPACE_CONSOLE;
73         
74         sconsole->lheight=      14;
75         sconsole->type=         CONSOLE_TYPE_PYTHON;
76         sconsole->rpt_mask=     CONSOLE_RPT_OP; /* ? - not sure whats a good default here?*/
77         
78         /* header */
79         ar= MEM_callocN(sizeof(ARegion), "header for console");
80         
81         BLI_addtail(&sconsole->regionbase, ar);
82         ar->regiontype= RGN_TYPE_HEADER;
83         ar->alignment= RGN_ALIGN_BOTTOM;
84         
85         
86         /* main area */
87         ar= MEM_callocN(sizeof(ARegion), "main area for text");
88         
89         BLI_addtail(&sconsole->regionbase, ar);
90         ar->regiontype= RGN_TYPE_WINDOW;
91         
92         ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM_O);
93         ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
94         ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
95         ar->v2d.keeptot= V2D_KEEPTOT_STRICT;
96         ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
97         
98         return (SpaceLink *)sconsole;
99 }
100
101 /* not spacelink itself */
102 static void console_free(SpaceLink *sl)
103 {
104         SpaceConsole *sc= (SpaceConsole*) sl;
105         
106         while(sc->scrollback.first)
107                 console_scrollback_free(sc, sc->scrollback.first);
108         
109         while(sc->history.first)
110                 console_history_free(sc, sc->history.first);
111 }
112
113
114 /* spacetype; init callback */
115 static void console_init(struct wmWindowManager *wm, ScrArea *sa)
116 {
117
118 }
119
120 static SpaceLink *console_duplicate(SpaceLink *sl)
121 {
122         SpaceConsole *sconsolen= MEM_dupallocN(sl);
123         
124         /* clear or remove stuff from old */
125         
126         /* TODO - duplicate?, then we also need to duplicate the py namespace */
127         sconsolen->scrollback.first= sconsolen->scrollback.last= NULL;
128         sconsolen->history.first= sconsolen->history.last= NULL;
129         
130         return (SpaceLink *)sconsolen;
131 }
132
133
134
135 /* add handlers, stuff you only do once or on area/region changes */
136 static void console_main_area_init(wmWindowManager *wm, ARegion *ar)
137 {
138         ListBase *keymap;
139         
140         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
141         
142         /* own keymap */
143         keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0);    /* XXX weak? */
144         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
145 }
146
147 static void console_main_area_draw(const bContext *C, ARegion *ar)
148 {
149         /* draw entirely, view changes should be handled here */
150         SpaceConsole *sc= CTX_wm_space_console(C);
151         //View2D *v2d= &ar->v2d;
152         //float col[3];
153         
154         /* clear and setup matrix */
155         //UI_GetThemeColor3fv(TH_BACK, col);
156         //glClearColor(col[0], col[1], col[2], 0.0);
157         glClearColor(0, 0, 0, 1.0);
158         
159         glClear(GL_COLOR_BUFFER_BIT);
160         
161         /* worlks best with no view2d matrix set */
162         /*UI_view2d_view_ortho(C, v2d);*/
163                 
164         /* data... */
165         
166         /* add helper text, why not? */
167         if(sc->scrollback.first==NULL) {
168                 console_scrollback_add_str(C, " * Python Interactive Console *", 0);
169                 console_scrollback_add_str(C, "Command History:  Up/Down Arrow", 0);
170                 console_scrollback_add_str(C, "Cursor:           Left/Right Home/End", 0);
171                 console_scrollback_add_str(C, "Remove:           Backspace/Delete", 0);
172                 console_scrollback_add_str(C, "Execute:          Enter", 0);
173                 console_scrollback_add_str(C, "Autocomplete:     Tab", 0);
174                 console_scrollback_add_str(C, "Ctrl +/-  Wheel:  Zoom", 0);
175                 console_scrollback_add_str(C, "Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.ui", 0);
176         }
177         
178         console_history_verify(C); /* make sure we have some command line */
179         console_text_main(sc, ar, CTX_wm_reports(C));
180         
181         /* reset view matrix */
182         /* UI_view2d_view_restore(C); */
183         
184         /* scrollers */
185         /*
186         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
187         UI_view2d_scrollers_draw(C, v2d, scrollers);
188         UI_view2d_scrollers_free(scrollers);
189         */
190 }
191
192 void console_operatortypes(void)
193 {
194         WM_operatortype_append(CONSOLE_OT_move);
195         WM_operatortype_append(CONSOLE_OT_delete);
196         WM_operatortype_append(CONSOLE_OT_insert);
197         
198         /* for use by python only */
199         WM_operatortype_append(CONSOLE_OT_history_append); 
200         WM_operatortype_append(CONSOLE_OT_scrollback_append);
201         
202         
203         WM_operatortype_append(CONSOLE_OT_clear); 
204         WM_operatortype_append(CONSOLE_OT_history_cycle);
205         WM_operatortype_append(CONSOLE_OT_zoom);
206 }
207
208 void console_keymap(struct wmWindowManager *wm)
209 {
210         ListBase *keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0);
211         
212         /*
213         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
214         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
215         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
216         
217         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
218         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", EKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "type", LINE_END);
219         */
220         
221         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
222         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
223         
224         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
225         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
226         
227         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
228         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_zoom", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
229         
230         
231         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
232         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
233         
234         RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", 1);
235         WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0);
236         
237         /*
238         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
239         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
240         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_LINE);
241         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_LINE);
242         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_PAGE);
243         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_PAGE);
244
245
246         //RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
247         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_CHAR);
248         //RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
249         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
250         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
251         */
252         
253         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
254         RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
255
256 #ifndef DISABLE_PYTHON
257         WM_keymap_add_item(keymap, "CONSOLE_OT_exec", RETKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */
258         WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", TABKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */
259 #endif
260         WM_keymap_add_item(keymap, "CONSOLE_OT_insert", KM_TEXTINPUT, KM_PRESS, KM_ANY, 0); // last!
261 }
262
263 /****************** header region ******************/
264
265 /* add handlers, stuff you only do once or on area/region changes */
266 static void console_header_area_init(wmWindowManager *wm, ARegion *ar)
267 {
268         ED_region_header_init(ar);
269 }
270
271 static void console_header_area_draw(const bContext *C, ARegion *ar)
272 {
273         ED_region_header(C, ar);
274 }
275
276 static void console_main_area_listener(ScrArea *sa, wmNotifier *wmn)
277 {
278         SpaceConsole *sc= sa->spacedata.first;
279
280         /* context changes */
281         switch(wmn->category) {
282                 case NC_CONSOLE:
283                         if(wmn->data == ND_CONSOLE) { /* generic redraw request */
284                                 ED_area_tag_redraw(sa);
285                         }
286                         else if(wmn->data == ND_CONSOLE_REPORT && sc->type==CONSOLE_TYPE_REPORT) {
287                                 /* redraw also but only for report view, could do less redraws by checking the type */
288                                 ED_area_tag_redraw(sa);
289                         }
290                         break;
291         }
292 }
293
294 /* only called once, from space/spacetypes.c */
295 void ED_spacetype_console(void)
296 {
297         SpaceType *sc= MEM_callocN(sizeof(SpaceType), "spacetype console");
298         ARegionType *art;
299         
300         sc->spaceid= SPACE_CONSOLE;
301         
302         sc->new= console_new;
303         sc->free= console_free;
304         sc->init= console_init;
305         sc->duplicate= console_duplicate;
306         sc->operatortypes= console_operatortypes;
307         sc->keymap= console_keymap;
308         sc->listener= console_main_area_listener;
309         
310         /* regions: main window */
311         art= MEM_callocN(sizeof(ARegionType), "spacetype console region");
312         art->regionid = RGN_TYPE_WINDOW;
313         art->init= console_main_area_init;
314         art->draw= console_main_area_draw;
315         
316         
317         
318         BLI_addhead(&sc->regiontypes, art);
319         
320         /* regions: header */
321         art= MEM_callocN(sizeof(ARegionType), "spacetype console region");
322         art->regionid = RGN_TYPE_HEADER;
323         art->minsizey= HEADERY;
324         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
325         
326         art->init= console_header_area_init;
327         art->draw= console_header_area_draw;
328         
329         BLI_addhead(&sc->regiontypes, art);
330         
331         
332         
333         BKE_spacetype_register(sc);
334 }
335
336