Blender  V2.59
space_info.c
Go to the documentation of this file.
00001 /*
00002  * $Id: space_info.c 35854 2011-03-28 18:51:27Z ton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2008 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  * 
00024  * Contributor(s): Blender Foundation
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include <string.h>
00035 #include <stdio.h>
00036 
00037 #include "MEM_guardedalloc.h"
00038 
00039 #include "BLI_blenlib.h"
00040 #include "BLI_math.h"
00041 #include "BLI_rand.h"
00042 #include "BLI_utildefines.h"
00043 
00044 #include "BKE_context.h"
00045 #include "BKE_global.h"
00046 #include "BKE_screen.h"
00047 
00048 #include "ED_space_api.h"
00049 #include "ED_screen.h"
00050 
00051 #include "BIF_gl.h"
00052 
00053 #include "WM_api.h"
00054 #include "WM_types.h"
00055 
00056 #include "UI_resources.h"
00057 #include "UI_interface.h"
00058 #include "UI_view2d.h"
00059 
00060 #include "info_intern.h"        // own include
00061 
00062 /* ******************** default callbacks for info space ***************** */
00063 
00064 static SpaceLink *info_new(const bContext *UNUSED(C))
00065 {
00066         ARegion *ar;
00067         SpaceInfo *sinfo;
00068         
00069         sinfo= MEM_callocN(sizeof(SpaceInfo), "initinfo");
00070         sinfo->spacetype= SPACE_INFO;
00071 
00072         sinfo->rpt_mask= INFO_RPT_OP;
00073 
00074         /* header */
00075         ar= MEM_callocN(sizeof(ARegion), "header for info");
00076         
00077         BLI_addtail(&sinfo->regionbase, ar);
00078         ar->regiontype= RGN_TYPE_HEADER;
00079         ar->alignment= RGN_ALIGN_BOTTOM;
00080         
00081         /* main area */
00082         ar= MEM_callocN(sizeof(ARegion), "main area for info");
00083         
00084         BLI_addtail(&sinfo->regionbase, ar);
00085         ar->regiontype= RGN_TYPE_WINDOW;
00086         
00087         /* keep in sync with console */
00088         ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
00089         ar->v2d.align |= V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_NEG_Y; /* align bottom left */
00090         ar->v2d.keepofs |= V2D_LOCKOFS_X;
00091         ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
00092         ar->v2d.keeptot= V2D_KEEPTOT_BOUNDS;
00093         ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
00094 
00095         /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
00096         //ar->v2d.keepzoom= (V2D_KEEPASPECT|V2D_LIMITZOOM);
00097         
00098         return (SpaceLink *)sinfo;
00099 }
00100 
00101 /* not spacelink itself */
00102 static void info_free(SpaceLink *UNUSED(sl))
00103 {       
00104 //      SpaceInfo *sinfo= (SpaceInfo*) sl;
00105         
00106 }
00107 
00108 
00109 /* spacetype; init callback */
00110 static void info_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
00111 {
00112 
00113 }
00114 
00115 static SpaceLink *info_duplicate(SpaceLink *sl)
00116 {
00117         SpaceInfo *sinfon= MEM_dupallocN(sl);
00118         
00119         /* clear or remove stuff from old */
00120         
00121         return (SpaceLink *)sinfon;
00122 }
00123 
00124 
00125 
00126 /* add handlers, stuff you only do once or on area/region changes */
00127 static void info_main_area_init(wmWindowManager *wm, ARegion *ar)
00128 {
00129         wmKeyMap *keymap;
00130 
00131         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
00132 
00133         /* own keymap */
00134         keymap= WM_keymap_find(wm->defaultconf, "Info", SPACE_INFO, 0);
00135         WM_event_add_keymap_handler(&ar->handlers, keymap);
00136 }
00137 
00138 static void info_textview_update_rect(const bContext *C, ARegion *ar)
00139 {
00140         SpaceInfo *sinfo= CTX_wm_space_info(C);
00141         View2D *v2d= &ar->v2d;
00142 
00143         UI_view2d_totRect_set(v2d, ar->winx-1, info_textview_height(sinfo, ar, CTX_wm_reports(C)));
00144 }
00145 
00146 static void info_main_area_draw(const bContext *C, ARegion *ar)
00147 {
00148         /* draw entirely, view changes should be handled here */
00149         SpaceInfo *sinfo= CTX_wm_space_info(C);
00150         View2D *v2d= &ar->v2d;
00151         View2DScrollers *scrollers;
00152 
00153         /* clear and setup matrix */
00154         UI_ThemeClearColor(TH_BACK);
00155         glClear(GL_COLOR_BUFFER_BIT);
00156 
00157         /* quick way to avoid drawing if not bug enough */
00158         if(ar->winy < 16)
00159                 return;
00160                 
00161         info_textview_update_rect(C, ar);
00162 
00163         /* worlks best with no view2d matrix set */
00164         UI_view2d_view_ortho(v2d);
00165 
00166         info_textview_main(sinfo, ar, CTX_wm_reports(C));
00167 
00168         /* reset view matrix */
00169         UI_view2d_view_restore(C);
00170         
00171         /* scrollers */
00172         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_GRID_CLAMP);
00173         UI_view2d_scrollers_draw(C, v2d, scrollers);
00174         UI_view2d_scrollers_free(scrollers);
00175 }
00176 
00177 static void info_operatortypes(void)
00178 {
00179         WM_operatortype_append(FILE_OT_pack_all);
00180         WM_operatortype_append(FILE_OT_unpack_all);
00181         WM_operatortype_append(FILE_OT_make_paths_relative);
00182         WM_operatortype_append(FILE_OT_make_paths_absolute);
00183         WM_operatortype_append(FILE_OT_report_missing_files);
00184         WM_operatortype_append(FILE_OT_find_missing_files);
00185         WM_operatortype_append(INFO_OT_reports_display_update);
00186 
00187         /* info_report.c */
00188         WM_operatortype_append(INFO_OT_select_pick);
00189         WM_operatortype_append(INFO_OT_select_all_toggle);
00190         WM_operatortype_append(INFO_OT_select_border);
00191 
00192         WM_operatortype_append(INFO_OT_report_replay);
00193         WM_operatortype_append(INFO_OT_report_delete);
00194         WM_operatortype_append(INFO_OT_report_copy);
00195 }
00196 
00197 static void info_keymap(struct wmKeyConfig *keyconf)
00198 {
00199         wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0);
00200         
00201         WM_keymap_verify_item(keymap, "INFO_OT_reports_display_update", TIMERREPORT, KM_ANY, KM_ANY, 0);
00202 
00203         /* info space */
00204         keymap= WM_keymap_find(keyconf, "Info", SPACE_INFO, 0);
00205         
00206         
00207         /* report selection */
00208         WM_keymap_add_item(keymap, "INFO_OT_select_pick", SELECTMOUSE, KM_PRESS, 0, 0);
00209         WM_keymap_add_item(keymap, "INFO_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
00210         WM_keymap_add_item(keymap, "INFO_OT_select_border", BKEY, KM_PRESS, 0, 0);
00211 
00212         WM_keymap_add_item(keymap, "INFO_OT_report_replay", RKEY, KM_PRESS, 0, 0);
00213         WM_keymap_add_item(keymap, "INFO_OT_report_delete", XKEY, KM_PRESS, 0, 0);
00214         WM_keymap_add_item(keymap, "INFO_OT_report_delete", DELKEY, KM_PRESS, 0, 0);
00215         WM_keymap_add_item(keymap, "INFO_OT_report_copy", CKEY, KM_PRESS, KM_CTRL, 0);
00216 }
00217 
00218 /* add handlers, stuff you only do once or on area/region changes */
00219 static void info_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
00220 {
00221         ED_region_header_init(ar);
00222 }
00223 
00224 static void info_header_area_draw(const bContext *C, ARegion *ar)
00225 {
00226         ED_region_header(C, ar);
00227 }
00228 
00229 static void info_main_area_listener(ARegion *ar, wmNotifier *wmn)
00230 {
00231         // SpaceInfo *sinfo= sa->spacedata.first;
00232 
00233         /* context changes */
00234         switch(wmn->category) {
00235                 case NC_SPACE:
00236                         if(wmn->data == ND_SPACE_INFO_REPORT) {
00237                                 /* redraw also but only for report view, could do less redraws by checking the type */
00238                                 ED_region_tag_redraw(ar);
00239                         }
00240                         break;
00241         }
00242 }
00243 
00244 static void info_header_listener(ARegion *ar, wmNotifier *wmn)
00245 {
00246         /* context changes */
00247         switch(wmn->category) {
00248                 case NC_SCREEN:
00249                         if(ELEM(wmn->data, ND_SCREENCAST, ND_ANIMPLAY))
00250                                 ED_region_tag_redraw(ar);
00251                         break;
00252                 case NC_WM:     
00253                         if(wmn->data == ND_JOB)
00254                                 ED_region_tag_redraw(ar);
00255                         break;
00256                 case NC_SCENE:
00257                         if(wmn->data==ND_RENDER_RESULT)
00258                                 ED_region_tag_redraw(ar);
00259                         break;
00260                 case NC_SPACE:  
00261                         if(wmn->data == ND_SPACE_INFO)
00262                                 ED_region_tag_redraw(ar);
00263                         break;
00264                 case NC_ID:
00265                         if(wmn->action == NA_RENAME)
00266                                 ED_region_tag_redraw(ar);
00267         }
00268         
00269 }
00270 
00271 static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
00272 {
00273         struct RecentFile *recent;
00274         uiLayout *layout= menu->layout;
00275         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
00276         if (G.recent_files.first) {
00277                 for(recent = G.recent_files.first; (recent); recent = recent->next) {
00278                         uiItemStringO(layout, BLI_path_basename(recent->filepath), ICON_FILE_BLEND, "WM_OT_open_mainfile", "filepath", recent->filepath);
00279                 }
00280         } else {
00281                 uiItemL(layout, "No Recent Files", ICON_NONE);
00282         }
00283 }
00284 
00285 static void recent_files_menu_register(void)
00286 {
00287         MenuType *mt;
00288 
00289         mt= MEM_callocN(sizeof(MenuType), "spacetype info menu recent files");
00290         strcpy(mt->idname, "INFO_MT_file_open_recent");
00291         strcpy(mt->label, "Open Recent...");
00292         mt->draw= recent_files_menu_draw;
00293         WM_menutype_add(mt);
00294 }
00295 
00296 /* only called once, from space/spacetypes.c */
00297 void ED_spacetype_info(void)
00298 {
00299         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype info");
00300         ARegionType *art;
00301         
00302         st->spaceid= SPACE_INFO;
00303         strncpy(st->name, "Info", BKE_ST_MAXNAME);
00304         
00305         st->new= info_new;
00306         st->free= info_free;
00307         st->init= info_init;
00308         st->duplicate= info_duplicate;
00309         st->operatortypes= info_operatortypes;
00310         st->keymap= info_keymap;
00311         
00312         /* regions: main window */
00313         art= MEM_callocN(sizeof(ARegionType), "spacetype info region");
00314         art->regionid = RGN_TYPE_WINDOW;
00315         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
00316 
00317         art->init= info_main_area_init;
00318         art->draw= info_main_area_draw;
00319         art->listener= info_main_area_listener;
00320 
00321         BLI_addhead(&st->regiontypes, art);
00322         
00323         /* regions: header */
00324         art= MEM_callocN(sizeof(ARegionType), "spacetype info region");
00325         art->regionid = RGN_TYPE_HEADER;
00326         art->prefsizey= HEADERY;
00327         
00328         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
00329         art->listener= info_header_listener;
00330         art->init= info_header_area_init;
00331         art->draw= info_header_area_draw;
00332         
00333         BLI_addhead(&st->regiontypes, art);
00334         
00335         recent_files_menu_register();
00336 
00337         BKE_spacetype_register(st);
00338 }