]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/camera/funchandlers.cpp
4134a889eda465366e89e360b87173420e267b3a
[xonotic/netradiant.git] / contrib / camera / funchandlers.cpp
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 /*
23    Camera plugin for GtkRadiant
24    Copyright (C) 2002 Splash Damage Ltd.
25  */
26
27 #include "camera.h"
28
29 extern GtkWidget *g_pEditModeAddRadioButton;
30
31 char* Q_realpath( const char *path, char *resolved_path, size_t size ){
32 #if defined( POSIX )
33         return realpath( path, resolved_path );
34 #elif defined( WIN32 )
35         return _fullpath( resolved_path, path, size );
36 #else
37 #error "unsupported platform"
38 #endif
39 }
40
41 static void DoNewCamera( idCameraPosition::positionType type ){
42         CCamera *cam = AllocCam();
43
44         if ( cam ) {
45                 char buf[128];
46                 sprintf( buf, "camera%i", cam->GetCamNum() );
47
48                 cam->GetCam()->startNewCamera( type );
49                 cam->GetCam()->setName( buf );
50                 cam->GetCam()->buildCamera();
51
52                 sprintf( buf, "Unsaved Camera %i", cam->GetCamNum() );
53                 cam->SetFileName( buf, false );
54
55                 SetCurrentCam( cam );
56                 RefreshCamListCombo();
57
58                 // Go to editmode Add
59                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_pEditModeAddRadioButton ), TRUE );
60
61                 // Show the camera inspector
62                 DoCameraInspector();
63
64                 // Start edit mode (if not initiated by DoCameraInspector)
65                 if ( !g_bEditOn ) {
66                         DoStartEdit( GetCurrentCam() );
67                 }
68         }
69         else {
70                 g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "No free cameras available.", "Create Camera Error", eMB_OK );
71         }
72 }
73
74 void DoNewFixedCamera(){
75         DoNewCamera( idCameraPosition::FIXED );
76 }
77
78 void DoNewInterpolatedCamera(){
79         DoNewCamera( idCameraPosition::INTERPOLATED );
80 }
81
82 void DoNewSplineCamera(){
83         DoNewCamera( idCameraPosition::SPLINE );
84 }
85
86 void DoCameraInspector(){
87         gtk_widget_show( g_pCameraInspectorWnd );
88 }
89
90 void DoPreviewCamera(){
91         if ( GetCurrentCam() ) {
92                 g_iPreviewRunning = 1;
93                 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
94         }
95 }
96
97 void DoLoadCamera(){
98         char basepath[PATH_MAX];
99
100         if ( firstCam && firstCam->HasBeenSaved() ) {
101                 ExtractFilePath( firstCam->GetFileName(), basepath );
102         }
103         else{
104                 strcpy( basepath, g_FuncTable.m_pfnGetGamePath() );
105         }
106
107         const gchar *filename = g_FuncTable.m_pfnFileDialog( (GtkWidget *)g_pRadiantWnd, TRUE, "Open Camera File", basepath, "camera" );
108
109         if ( filename ) {
110                 CCamera *cam = AllocCam();
111                 char fullpathtofile[PATH_MAX];
112
113                 if ( cam ) {
114                         Q_realpath( filename, fullpathtofile, PATH_MAX );
115
116                         // see if this camera file was already loaded
117                         CCamera *checkCam = firstCam->GetNext(); // not the first one as we just allocated it
118                         while ( checkCam ) {
119                                 if ( !strcmp( fullpathtofile, checkCam->GetFileName() ) ) {
120                                         char error[PATH_MAX + 64];
121                                         FreeCam( cam );
122                                         sprintf( error, "Camera file \'%s\' is already loaded", fullpathtofile );
123                                         g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Load error", eMB_OK );
124                                         //g_free( filename );
125                                         return;
126                                 }
127                                 checkCam = checkCam->GetNext();
128                         }
129
130                         if ( loadCamera( cam->GetCamNum(), fullpathtofile ) ) {
131                                 cam->GetCam()->buildCamera();
132                                 cam->SetFileName( filename, true );
133                                 SetCurrentCam( cam );
134                                 RefreshCamListCombo();
135                                 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
136                         }
137                         else {
138                                 char error[PATH_MAX + 64];
139                                 FreeCam( cam );
140                                 sprintf( error, "An error occured during the loading of \'%s\'", fullpathtofile );
141                                 g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Load error", eMB_OK );
142                         }
143
144                         //g_free( filename );
145                 }
146                 else {
147                         g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "No free camera slots available", "Load error", eMB_OK );
148                 }
149         }
150 }
151
152 void DoSaveCamera() {
153         char basepath[PATH_MAX];
154
155         if ( !GetCurrentCam() ) {
156                 return;
157         }
158
159         if ( GetCurrentCam()->GetFileName()[0] ) {
160                 ExtractFilePath( GetCurrentCam()->GetFileName(), basepath );
161         }
162         else{
163                 strcpy( basepath, g_FuncTable.m_pfnGetGamePath() );
164         }
165
166         const gchar *filename = g_FuncTable.m_pfnFileDialog( g_pRadiantWnd, FALSE, "Save Camera File", basepath, "camera" );
167
168         if ( filename ) {
169                 char fullpathtofile[PATH_MAX + 8];
170
171                 Q_realpath( filename, fullpathtofile, PATH_MAX );
172
173                 // File dialog from windows (and maybe the gtk one from radiant) doesn't handle default extensions properly.
174                 // Add extension and check again if file exists
175                 if ( strcmp( fullpathtofile + ( strlen( fullpathtofile ) - 7 ), ".camera" ) ) {
176                         strcat( fullpathtofile, ".camera" );
177
178                         if ( FileExists( fullpathtofile ) ) {
179                                 if ( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "File already exists.\nOverwrite?", "Save Camera File", eMB_YESNO ) == eIDNO ) {
180                                         return;
181                                 }
182                         }
183                 }
184
185                 // see if this camera file was already loaded
186                 CCamera *checkCam = firstCam;
187                 while ( checkCam ) {
188                         if ( checkCam == GetCurrentCam() ) {
189                                 checkCam = checkCam->GetNext();
190                                 if ( !checkCam ) { // we only have one camera file opened so no need to check further
191                                         break;
192                                 }
193                         }
194                         else if ( !strcmp( fullpathtofile, checkCam->GetFileName() ) ) {
195                                 char error[PATH_MAX + 64];
196                                 sprintf( error, "Camera file \'%s\' is currently loaded by NetRadiant.\nPlease select a different filename.", fullpathtofile );
197                                 g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Save error", eMB_OK );
198                                 return;
199                         }
200                         checkCam = checkCam->GetNext();
201                 }
202
203                 // FIXME: check for existing directory
204
205                 GetCurrentCam()->GetCam()->save( fullpathtofile );
206                 GetCurrentCam()->SetFileName( fullpathtofile, true );
207                 RefreshCamListCombo();
208         }
209 }
210
211 void DoUnloadCamera() {
212         if ( !GetCurrentCam() ) {
213                 return;
214         }
215
216         if ( !GetCurrentCam()->HasBeenSaved() ) {
217                 char buf[PATH_MAX + 64];
218                 sprintf( buf, "Do you want to save the changes for camera '%s'?", GetCurrentCam()->GetCam()->getName() );
219                 if ( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, buf, "Warning", eMB_YESNO ) == eIDYES ) {
220                         DoSaveCamera();
221                 }
222         }
223         else if ( GetCurrentCam()->HasBeenSaved() == 2 ) {
224                 char buf[PATH_MAX + 64];
225                 sprintf( buf, "Do you want to save the changes made to camera file '%s'?", GetCurrentCam()->GetFileName() );
226                 if ( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, buf, "Warning", eMB_YESNO ) == eIDYES ) {
227                         DoSaveCamera();
228                 }
229         }
230
231         if ( g_pCurrentEditCam ) {
232                 DoStopEdit();
233                 g_pCurrentEditCam = NULL;
234         }
235
236         FreeCam( GetCurrentCam() );
237         SetCurrentCam( NULL );
238         RefreshCamListCombo();
239 }
240
241 CCamera *g_pCurrentEditCam = NULL;
242
243 void DoStartEdit( CCamera *cam ) {
244         if ( g_pCurrentEditCam ) {
245                 DoStopEdit();
246                 g_pCurrentEditCam = NULL;
247         }
248
249         if ( cam ) {
250                 g_bEditOn = true;
251
252                 if ( !Listener ) {
253                         Listener = new CListener;
254                 }
255
256                 cam->GetCam()->startEdit( g_iActiveTarget < 0 ? true : false );
257
258                 g_pCurrentEditCam = cam;
259
260                 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
261         }
262 }
263
264 void DoStopEdit( void ) {
265         g_bEditOn = false;
266
267         if ( Listener ) {
268                 delete Listener;
269                 Listener = NULL;
270         }
271
272         if ( g_pCurrentEditCam ) {
273                 // stop editing on the current cam
274                 g_pCurrentEditCam->GetCam()->stopEdit();
275                 g_pCurrentEditCam = NULL;
276
277                 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
278         }
279 }