]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/camera/funchandlers.cpp
fafae2a61516f031dd252f61b3c8b2785ba9cabc
[xonotic/netradiant.git] / contrib / camera / funchandlers.cpp
1 /*
2 Copyright (C) 1999-2007 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 {
33 #if defined  (__linux__) || defined (__APPLE__)
34         return realpath(path, resolved_path);
35 #else
36         return _fullpath(resolved_path, path, size);    
37 #endif
38 }
39
40 static void DoNewCamera( idCameraPosition::positionType type )
41 {
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         } else {
68       g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "No free cameras available.", "Create Camera Error", MB_OK, NULL );
69         }
70 }
71
72 void DoNewFixedCamera()
73 {
74         DoNewCamera( idCameraPosition::FIXED );
75 }
76
77 void DoNewInterpolatedCamera()
78 {
79         DoNewCamera( idCameraPosition::INTERPOLATED );
80 }
81
82 void DoNewSplineCamera()
83 {
84         DoNewCamera( idCameraPosition::SPLINE );
85 }
86
87 void DoCameraInspector()
88 {
89   gtk_widget_show( g_pCameraInspectorWnd );
90 }
91
92 void DoPreviewCamera()
93 {
94         if( GetCurrentCam() ) {
95                 g_iPreviewRunning = 1;
96                 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
97         }
98 }
99
100 void DoLoadCamera()
101 {
102   char basepath[PATH_MAX];
103
104         if( firstCam && firstCam->HasBeenSaved() )
105     CAMERA_ExtractFilePath( firstCam->GetFileName(), basepath );
106   else
107     strcpy( basepath, g_FuncTable.m_pfnGetGamePath() );
108
109   const gchar *filename = g_FuncTable.m_pfnFileDialog( (GtkWidget *)g_pRadiantWnd, TRUE, "Open Camera File", basepath, "camera");
110
111   if( filename )
112         {
113     CCamera *cam = AllocCam();
114     char fullpathtofile[PATH_MAX];
115
116     if( cam ) {
117                         Q_realpath(filename, fullpathtofile, PATH_MAX);
118
119       // see if this camera file was already loaded
120       CCamera *checkCam = firstCam->GetNext();  // not the first one as we just allocated it
121       while( checkCam ) {
122         if( !strcmp( fullpathtofile, checkCam->GetFileName() ) ) {
123           char error[PATH_MAX+64];
124           FreeCam( cam );
125           sprintf( error, "Camera file \'%s\' is already loaded", fullpathtofile );
126           g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Load error", MB_OK, NULL );
127           //g_free( filename );
128           return;
129         }
130         checkCam = checkCam->GetNext();
131       }
132
133                         if( loadCamera( cam->GetCamNum(), fullpathtofile ) ) {
134                                 cam->GetCam()->buildCamera();
135         cam->SetFileName( filename, true );
136         SetCurrentCam( cam );
137         RefreshCamListCombo();
138         g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
139       } else {
140         char error[PATH_MAX+64];
141         FreeCam( cam );
142         sprintf( error, "An error occured during the loading of \'%s\'", fullpathtofile );
143         g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Load error", MB_OK, NULL );
144       }
145
146       //g_free( filename );
147     } else {
148                 g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "No free camera slots available", "Load error", MB_OK, NULL );
149           }
150         }
151 }
152
153 void DoSaveCamera() {
154   char basepath[PATH_MAX];
155
156   if( !GetCurrentCam() )
157     return;
158
159   if( GetCurrentCam()->GetFileName()[0] )
160     CAMERA_ExtractFilePath( GetCurrentCam()->GetFileName(), basepath );
161   else
162     strcpy( basepath, g_FuncTable.m_pfnGetGamePath() );
163
164   const gchar *filename = g_FuncTable.m_pfnFileDialog( (void *)g_pRadiantWnd, FALSE, "Save Camera File", basepath, "camera");
165
166   if( filename ) {
167     char fullpathtofile[PATH_MAX + 8];
168
169     Q_realpath(filename, fullpathtofile, PATH_MAX);
170
171                 // File dialog from windows (and maybe the gtk one from radiant) doesn't handle default extensions properly.
172                 // Add extension and check again if file exists
173                 if( strcmp( fullpathtofile + (strlen(fullpathtofile) - 7), ".camera" ) ) {
174                         strcat( fullpathtofile, ".camera" );
175
176                         if( FileExists( fullpathtofile ) ) {
177                                 if ( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "File already exists.\nOverwrite?", "Save Camera File", MB_YESNO, NULL ) == IDNO ) {
178                                         return;
179                                 }
180                         }
181                 }
182
183           // see if this camera file was already loaded
184     CCamera *checkCam = firstCam;
185     while( checkCam ) {
186       if( checkCam == GetCurrentCam() ) {
187         checkCam = checkCam->GetNext();
188                                 if( !checkCam ) // we only have one camera file opened so no need to check further
189                                         break;
190       } else if( !strcmp( fullpathtofile, checkCam->GetFileName() ) ) {
191         char error[PATH_MAX+64];
192         sprintf( error, "Camera file \'%s\' is currently loaded by GtkRadiant.\nPlease select a different filename.", fullpathtofile );
193                 g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Save error", MB_OK, NULL );
194         return;
195       }
196       checkCam = checkCam->GetNext();
197     }
198
199     // FIXME: check for existing directory
200
201     GetCurrentCam()->GetCam()->save( fullpathtofile );
202                 GetCurrentCam()->SetFileName( fullpathtofile, true );
203                 RefreshCamListCombo();
204   }
205 }
206
207 void DoUnloadCamera() {
208   if( !GetCurrentCam() )
209     return;
210
211         if( !GetCurrentCam()->HasBeenSaved() ) {
212                 char buf[PATH_MAX+64];
213                 sprintf( buf, "Do you want to save the changes for camera '%s'?", GetCurrentCam()->GetCam()->getName() );
214                 if ( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, buf, "Warning", MB_YESNO, NULL ) == IDYES ) {
215                         DoSaveCamera();
216                 }
217         } else if( GetCurrentCam()->HasBeenSaved() == 2 ) {
218                 char buf[PATH_MAX+64];
219                 sprintf( buf, "Do you want to save the changes made to camera file '%s'?", GetCurrentCam()->GetFileName() );
220                 if( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, buf, "Warning", MB_YESNO, NULL ) == IDYES ) {
221                         DoSaveCamera();
222                 }
223         }
224
225   if( g_pCurrentEditCam ) {
226     DoStopEdit();
227     g_pCurrentEditCam = NULL;
228   }
229
230         FreeCam( GetCurrentCam() );
231         SetCurrentCam( NULL );
232         RefreshCamListCombo();
233 }
234
235 CCamera *g_pCurrentEditCam = NULL;
236
237 void DoStartEdit( CCamera *cam ) {
238   if( g_pCurrentEditCam ) {
239     DoStopEdit();
240     g_pCurrentEditCam = NULL;
241   }
242
243   if( cam ) {
244     g_bEditOn = true;
245
246     if( !Listener )
247       Listener = new CListener;
248
249     cam->GetCam()->startEdit( g_iActiveTarget < 0 ? true : false );
250
251     g_pCurrentEditCam = cam;
252
253     g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
254   }
255 }
256
257 void DoStopEdit( void ) {
258   g_bEditOn = false;
259
260   if( Listener ) {
261       delete Listener;
262       Listener = NULL;
263   }
264
265   if( g_pCurrentEditCam ) {
266     // stop editing on the current cam
267     g_pCurrentEditCam->GetCam()->stopEdit();
268     g_pCurrentEditCam = NULL;
269
270     g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
271   }
272 }