00001
00002
00003 #ifdef WIN32
00004
00005 #include "WinGUI.h"
00006 #include "WinGUIostream.h"
00007 #include "WinScene.h"
00008 #include "resource.h"
00009 #include <iostream>
00010 #include <strstream>
00011 #include "gui/SubMenu.h"
00012
00013
00014 HINSTANCE WinGUI::s_instance =0;
00015 WinGUI* WinGUI::s_gui=0;
00016 HWND WinGUI::s_hwnd=0;
00017 WinScene* WinGUI::s_graphics_window=0;
00018 WinScene* WinGUI::s_2d_window=0;
00019 bool WinGUI::s_quitting = false;
00020 WinGUIostream* WinGUI::s_text_window=0;
00021
00022 static char *szAppName = "WinGUI";
00023
00024
00025
00026 namespace gui {
00027 GUI* GUI::createGUI(const char* nameOfApp, const char* title)
00028 {
00029 if (WinGUI::s_gui!=0 && title!=0 ) ::SetWindowText(WinGUI::s_hwnd, title);
00030 if (WinGUI::s_gui==0) WinGUI::s_gui =new WinGUI(nameOfApp, title);
00031 GUI::instance(WinGUI::s_gui);
00032 GUI::s_instance = WinGUI::s_gui;
00033 return WinGUI::s_gui;
00034 }
00035 }
00036 bool GUI::running=false;
00037
00038
00039 WinGUI::WinGUI(const char* nameOfApp, const char* title)
00040 : GUI(title)
00041 , m_menuId(0)
00042 , m_text_window(0)
00043 {
00044
00045 if( s_hwnd==0 )
00046 s_hwnd = CreateWindow(szAppName,
00047 title,
00048 (WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX |
00049 WS_MAXIMIZEBOX | WS_THICKFRAME | WS_SYSMENU),
00050 20, 20,
00051 500, 500,
00052 NULL, NULL,
00053 s_instance,
00054 NULL);
00055 else setTitle(title);
00056
00057
00058 m_menuBar = m_currentMenu = ::CreateMenu ();
00059 }
00060
00061 WinGUI::~WinGUI()
00062 {
00063 CommandList::iterator pcmd = m_owned_commands.begin();
00064 while (pcmd != m_owned_commands.end() )
00065 delete (*pcmd++);
00066 delete m_text_window;
00067 }
00068
00069 WinGUI::Menu*
00070 WinGUI::beginPullDownMenu(const char * name, WinGUI::Menu* parent)
00071 {
00072 m_currentMenu = ::CreatePopupMenu();
00073 ::AppendMenu( parent? (HMENU)parent: m_menuBar, MF_POPUP, (UINT)m_currentMenu, name);
00074 return (Menu*)m_currentMenu;
00075 }
00076
00077 void
00078 WinGUI::restorePullDownMenu(Menu * oldMenu)
00079 {
00080 m_currentMenu = (HMENU)oldMenu;
00081 }
00082
00083 void
00084 WinGUI::endPullDownMenu(){m_currentMenu = m_menuBar;}
00085
00086
00087 void
00088 WinGUI::addToMenu(const char* name, Command* cmd)
00089 {
00090 ::AppendMenu(m_currentMenu, MF_STRING, cmdOffset+(m_menuId++), name);
00091 m_commands.push_back(cmd);
00092 }
00093
00094 class WinGUI::Toggle : public GUI::Toggle
00095 {
00096 friend class WinGUI;
00097 Toggle(HMENU hMenu, UINT uPos, Command* cmd1, Command*cmd2, bool state)
00098 : m_hMenu(hMenu), m_uPos(uPos)
00099 , m_cmd1(cmd1)
00100 , m_cmd2(cmd2)
00101 , m_state(state)
00102 {}
00103 void execute() {
00104 if( m_state){ m_cmd2->execute(); m_state=FALSE;}
00105 else { m_cmd1->execute(); m_state=TRUE; }
00106 ::CheckMenuItem(m_hMenu, m_uPos, m_state? MF_CHECKED : MF_UNCHECKED);
00107 }
00108 bool state()const{return m_state;}
00109
00110 HMENU m_hMenu; UINT m_uPos;
00111 Command *m_cmd1;
00112 Command *m_cmd2;
00113 bool m_state;
00114 };
00115
00116 void WinGUI::menuSeparator()
00117 {
00118 ::AppendMenu(m_currentMenu, MF_SEPARATOR, 0, 0);
00119 }
00120
00121 GUI::Toggle* WinGUI::addToggleToMenu(const char* name, bool state, Command* cmd1, Command* cmd2)
00122 {
00123 UINT uPos = cmdOffset+(m_menuId++);
00124 GUI::Toggle* t = new Toggle(m_currentMenu, uPos, cmd1,cmd2,state);
00125 m_commands.push_back(t);
00126 m_owned_commands.push_back(t);
00127 ::AppendMenu(m_currentMenu, MF_STRING | (state? MF_CHECKED : MF_UNCHECKED ), uPos, name);
00128 return t;
00129 }
00130
00131 void WinGUI::execute(WPARAM cmdindex)
00132 {
00133 m_commands[cmdindex-cmdOffset]->execute();
00134 }
00135
00136 void WinGUI::setTitle(const char* newtitle)
00137 {
00138 ::SetWindowText(s_hwnd, newtitle);
00139 }
00140
00141
00142
00143 void WinGUI::start()
00144 {
00145 static bool first=true;
00146 if( first ) {
00147
00148 ::SetMenu(s_hwnd,m_menuBar);
00149
00150 int cmdShow=SW_SHOWDEFAULT ;
00151 ::ShowWindow(s_hwnd, cmdShow);
00152 first = false;
00153 }
00154 running = true;
00155
00156 }
00157 void CALLBACK MyTimerProc(HWND hwnd, UINT uMsg, UINT idEvnet, DWORD dwTIme)
00158 {
00159 GUI::running = false;
00160 }
00161 void WinGUI::run(int pause_interval)
00162 {
00163 start();
00164 MSG msg;
00165 const UINT uIDEevnt=1;
00166 if(pause_interval==0) return;
00167 if( pause_interval>0 ) ::SetTimer(s_hwnd, uIDEevnt, pause_interval, MyTimerProc);
00168
00169
00170
00171 while( running && ::GetMessage(&msg, NULL, 0, 0)) {
00172 ::TranslateMessage(&msg);
00173 ::DispatchMessage(&msg);
00174 }
00175 if( pause_interval>0) ::KillTimer(s_hwnd, uIDEevnt);
00176
00177 if( !s_quitting ) running = true;
00178
00179 }
00180
00181 void WinGUI::processMessages()
00182 {
00183
00184 MSG msg;
00185
00186 while( ::PeekMessage(&msg, 0,0,0,PM_REMOVE))
00187 {
00188 ::TranslateMessage(&msg);
00189 ::DispatchMessage(&msg);
00190 }
00191 }
00192
00193 void WinGUI::quit(){::PostQuitMessage(0); s_quitting=true; running=false;}
00194
00195
00196
00197 gui::SceneControl*
00198 WinGUI::graphicsWindow(float size, int initial_view)
00199 {
00200 if( s_graphics_window==0)
00201 return s_graphics_window = new WinScene(s_hwnd, size, initial_view);
00202
00203
00204 HWND hwnd = ::CreateWindow(szAppName,
00205 "plots",
00206 ( WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_POPUP | WS_SYSMENU
00207 | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_VISIBLE),
00208 50, 50,
00209 500, 500,
00210 NULL, NULL,
00211 s_instance,
00212 NULL);
00213 return s_2d_window = new WinScene(hwnd, size);
00214
00215 }
00216
00217
00218
00219
00220 std::ostream*
00221 WinGUI::textWindow(const char* name)
00222 {
00223 if( m_text_window==0) {
00224 if( s_text_window ==0 ) s_text_window = new WinGUIostream( name, s_hwnd, s_instance);
00225 m_text_window = s_text_window;
00226 }
00227 return m_text_window;
00228 }
00229
00230
00231
00232
00233 #include <commdlg.h>
00234 char *
00235 WinGUI::askForFileName(const char* startDir , const char* label, const char* filter)
00236 {
00237 static OPENFILENAME ofn;
00238
00239 char szDirName[256];
00240 char szFile[256], szFileTitle[256];
00241 char szFilter[256];
00242
00243 strncpy(szFilter, filter, sizeof(szFilter));
00244 szFile[0] = '\0';
00245
00246
00247 strncpy(szDirName, startDir, sizeof(szDirName));
00248 int lpos=0;
00249 for( int pos = 0; szDirName[pos]!='\0' ; ++pos ) {
00250 if( szDirName[pos]=='\\')lpos=pos;
00251 }
00252 if( lpos) szDirName[lpos]='\0';
00253
00254 UINT cbString = strlen(szFilter);
00255 char chReplace = szFilter[cbString - 1];
00256
00257 for (UINT i = 0; szFilter[i] != '\0'; i++) {
00258 if (szFilter[i] == chReplace)
00259 szFilter[i] = '\0';
00260 }
00261
00262
00263
00264
00265 memset(&ofn, 0, sizeof(OPENFILENAME));
00266
00267 ofn.lStructSize = sizeof(OPENFILENAME);
00268 ofn.hwndOwner = s_hwnd;
00269 ofn.lpstrFilter = szFilter;
00270 ofn.nFilterIndex = 1;
00271
00272 ofn.lpstrTitle= label;
00273 ofn.lpstrFile= szFile;
00274 ofn.nMaxFile = sizeof(szFile);
00275 ofn.lpstrFileTitle = szFileTitle;
00276 ofn.nMaxFileTitle = sizeof(szFileTitle);
00277 ofn.lpstrInitialDir = szDirName;
00278 ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY ;
00279
00280 int result =::GetOpenFileName(&ofn);
00281
00282
00283
00284
00285
00286
00287 return result ? ofn.lpstrFile : 0;
00288
00289 }
00290
00291
00292 static char userAnswer[80];
00293 static const char* defString;
00294 static const char* prmpt;
00295 BOOL APIENTRY AskUserProc(HWND hdlg, UINT wMsg,
00296 WPARAM wParam, LPARAM lParam)
00297 {
00298 HWND textBox = ::GetDlgItem(hdlg,IDC_ASKUSER);
00299 switch( wMsg )
00300 {
00301 case WM_INITDIALOG:
00302
00303 ::SendMessage(textBox, WM_SETTEXT, 0, (LPARAM)defString);
00304
00305
00306 ::SendMessage(textBox,EM_SETSEL,0, -1);
00307
00308 ::SendMessage(hdlg,WM_SETTEXT, 0, (LPARAM)prmpt);
00309 return TRUE;
00310
00311 case WM_COMMAND:
00312 switch (wParam )
00313 {
00314 case IDOK:
00315 ::SendMessage(textBox, WM_GETTEXT, sizeof(userAnswer), (LPARAM)userAnswer);
00316 ::EndDialog(hdlg, TRUE);
00317 return TRUE;
00318 case IDCANCEL:
00319 ::EndDialog(hdlg, FALSE);
00320 return TRUE;
00321 }
00322 return TRUE;
00323 default:
00324 return FALSE;
00325 }
00326 }
00327 char*
00328 WinGUI::askUser(const char* promptString, const char* defaultString)
00329 {
00330 userAnswer[0]='\0';
00331 defString = defaultString;
00332 prmpt = promptString;
00333 int status = ::DialogBox( s_instance,MAKEINTRESOURCE(IDD_ASKUSER), s_hwnd, AskUserProc);
00334 return userAnswer;
00335 }
00336
00337
00338 void
00339 WinGUI::inform(const char* msg)
00340 {
00341 ::MessageBox(s_hwnd, (char*)msg, "Inform", MB_OK);
00342 }
00343
00344 #endif