]> git.saurik.com Git - wxWidgets.git/blame - utils/emulator/src/emulator.cpp
Adapted notebook sample to demonstrate wxToolbook
[wxWidgets.git] / utils / emulator / src / emulator.cpp
CommitLineData
3373d6bf
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: emulator.cpp
be5a51fb 3// Purpose: Emulator wxWidgets sample
3373d6bf
JS
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
3373d6bf
JS
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers (this file is usually all you
be5a51fb 28// need because it includes almost all "standard" wxWidgets headers)
3373d6bf
JS
29#ifndef WX_PRECOMP
30 #include "wx/wx.h"
31#endif
32
d1b327e1
JS
33#include "wx/confbase.h"
34#include "wx/fileconf.h"
35#include "wx/cmdline.h"
723c433f 36#include "wx/image.h"
9f55ceab 37#include "wx/file.h"
d1b327e1 38
abe89c8a 39#ifdef __WXX11__
3373d6bf
JS
40#include "wx/x11/reparent.h"
41#endif
42
0470b382
JS
43#include "emulator.h"
44
3373d6bf
JS
45// ----------------------------------------------------------------------------
46// resources
47// ----------------------------------------------------------------------------
48
49// the application icon (under Windows and OS/2 it is in resources)
50#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
d1b327e1 51 #include "emulator.xpm"
3373d6bf
JS
52#endif
53
54// ----------------------------------------------------------------------------
be5a51fb 55// event tables and other macros for wxWidgets
3373d6bf
JS
56// ----------------------------------------------------------------------------
57
be5a51fb 58// the event tables connect the wxWidgets events with the functions (event
3373d6bf
JS
59// handlers) which process them. It can be also done at run-time, but for the
60// simple menu events like this the static method is much simpler.
61BEGIN_EVENT_TABLE(wxEmulatorFrame, wxFrame)
62 EVT_MENU(Emulator_Quit, wxEmulatorFrame::OnQuit)
63 EVT_MENU(Emulator_About, wxEmulatorFrame::OnAbout)
d27294ac 64 EVT_CLOSE(wxEmulatorFrame::OnCloseWindow)
3373d6bf
JS
65END_EVENT_TABLE()
66
be5a51fb 67// Create a new application object: this macro will allow wxWidgets to create
3373d6bf
JS
68// the application object during program execution (it's better than using a
69// static object for many reasons) and also declares the accessor function
70// wxGetApp() which will return the reference of the right type (i.e. wxEmulatorApp and
71// not wxApp)
72IMPLEMENT_APP(wxEmulatorApp)
73
d1b327e1
JS
74static const wxCmdLineEntryDesc sg_cmdLineDesc[] =
75{
eda6fa91 76 { wxCMD_LINE_OPTION, _T("u"), _T("use-display"), _T("display number to use (default 100)"), (wxCmdLineParamType)0, 0 },
d1b327e1 77
eda6fa91
WS
78 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("displays help on the command line parameters"), (wxCmdLineParamType)0, 0 },
79 { wxCMD_LINE_SWITCH, _T("v"), _T("version"), _T("print version"), (wxCmdLineParamType)0, 0 },
d1b327e1 80
dc9b3bf7 81 { wxCMD_LINE_PARAM, NULL, NULL, _T("config file 1"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
d1b327e1 82
eda6fa91 83 { wxCMD_LINE_NONE, NULL, NULL, NULL, (wxCmdLineParamType)0, 0 }
d1b327e1
JS
84};
85
86
3373d6bf
JS
87// ============================================================================
88// implementation
89// ============================================================================
90
91// ----------------------------------------------------------------------------
92// the application class
93// ----------------------------------------------------------------------------
94
95wxEmulatorApp::wxEmulatorApp()
96{
97 m_xnestWindow = NULL;
98 m_containerWindow = NULL;
d1b327e1 99 m_displayNumber = wxT("100");
d27294ac
JS
100 m_xnestPID = 0;
101
3373d6bf
JS
102}
103
104// 'Main program' equivalent: the program execution "starts" here
105bool wxEmulatorApp::OnInit()
106{
453bacf4 107#if wxUSE_LOG
d27294ac 108 wxLog::SetTimestamp(NULL);
453bacf4 109#endif // wxUSE_LOG
3373d6bf
JS
110 wxInitAllImageHandlers();
111
d1b327e1
JS
112 wxString currentDir = wxGetCwd();
113
114 // Use argv to get current app directory
115 m_appDir = wxFindAppPath(argv[0], currentDir, wxT("WXEMUDIR"));
abe89c8a 116
d1b327e1
JS
117 // If the development version, go up a directory.
118#ifdef __WXMSW__
dc9b3bf7
JS
119 if ((m_appDir.Right(5).CmpNoCase(_T("DEBUG")) == 0) ||
120 (m_appDir.Right(11).CmpNoCase(_T("DEBUGSTABLE")) == 0) ||
121 (m_appDir.Right(7).CmpNoCase(_T("RELEASE")) == 0) ||
122 (m_appDir.Right(13).CmpNoCase(_T("RELEASESTABLE")) == 0)
d1b327e1
JS
123 )
124 m_appDir = wxPathOnly(m_appDir);
125#endif
126
127 // Parse the command-line parameters and options
128 wxCmdLineParser parser(sg_cmdLineDesc, argc, argv);
129 int res;
130 {
131 wxLogNull log;
132 res = parser.Parse();
133 }
134 if (res == -1 || res > 0 || parser.Found(wxT("h")))
135 {
136#ifdef __X__
137 wxLog::SetActiveTarget(new wxLogStderr);
138#endif
139 parser.Usage();
abe89c8a 140 return false;
d1b327e1
JS
141 }
142 if (parser.Found(wxT("v")))
143 {
144#ifdef __X__
145 wxLog::SetActiveTarget(new wxLogStderr);
146#endif
147 wxString msg;
be5a51fb 148 msg.Printf(wxT("wxWidgets PDA Emulator (c) Julian Smart, 2002 Version %.2f, %s"), wxEMULATOR_VERSION, __DATE__);
d1b327e1 149 wxLogMessage(msg);
abe89c8a 150 return false;
d1b327e1
JS
151 }
152 if (parser.Found(wxT("u"), & m_displayNumber))
153 {
154 // Should only be number, so strip out anything before
155 // and including a : character
156 if (m_displayNumber.Find(wxT(':')) != -1)
157 {
158 m_displayNumber = m_displayNumber.AfterFirst(wxT(':'));
159 }
160 }
161 if (parser.GetParamCount() == 0)
162 {
163 m_emulatorInfo.m_emulatorFilename = wxT("default.wxe");
164 }
165 else if (parser.GetParamCount() > 0)
166 {
167 m_emulatorInfo.m_emulatorFilename = parser.GetParam(0);
168 }
3373d6bf
JS
169
170 // Load the emulation info
d1b327e1 171 if (!LoadEmulator(m_appDir))
3373d6bf 172 {
d1b327e1 173 //wxMessageBox(wxT("Sorry, could not load this emulator. Please check bitmaps are valid."));
abe89c8a 174 return false;
3373d6bf 175 }
abe89c8a 176
d1b327e1
JS
177 // create the main application window
178 wxEmulatorFrame *frame = new wxEmulatorFrame(_T("wxEmulator"),
179 wxPoint(50, 50), wxSize(450, 340));
abe89c8a 180
d96cdd4a 181#if wxUSE_STATUSBAR
d1b327e1
JS
182 frame->SetStatusText(m_emulatorInfo.m_emulatorTitle, 0);
183
184 wxString sizeStr;
185 sizeStr.Printf(wxT("Screen: %dx%d"), (int) m_emulatorInfo.m_emulatorScreenSize.x,
186 (int) m_emulatorInfo.m_emulatorScreenSize.y);
187 frame->SetStatusText(sizeStr, 1);
d96cdd4a 188#endif // wxUSE_STATUSBAR
d1b327e1 189
abe89c8a 190 m_containerWindow = new wxEmulatorContainer(frame, wxID_ANY);
d1b327e1
JS
191
192 frame->SetClientSize(m_emulatorInfo.m_emulatorDeviceSize.x,
193 m_emulatorInfo.m_emulatorDeviceSize.y);
abe89c8a 194
3373d6bf
JS
195 // and show it (the frames, unlike simple controls, are not shown when
196 // created initially)
abe89c8a
DS
197 frame->Show(true);
198
199#ifdef __WXX11__
3373d6bf
JS
200 m_xnestWindow = new wxAdoptedWindow;
201
202 wxString cmd;
d27294ac 203 cmd.Printf(wxT("Xnest :%s -geometry %dx%d"),
d1b327e1
JS
204 m_displayNumber.c_str(),
205 (int) m_emulatorInfo.m_emulatorScreenSize.x,
206 (int) m_emulatorInfo.m_emulatorScreenSize.y);
3373d6bf 207
d27294ac
JS
208 // Asynchronously executes Xnest
209 m_xnestPID = wxExecute(cmd);
210 if (0 == m_xnestPID)
3373d6bf
JS
211 {
212 frame->Destroy();
213 wxMessageBox(wxT("Sorry, could not run Xnest. Please check your PATH."));
abe89c8a 214 return false;
3373d6bf 215 }
abe89c8a 216
3373d6bf
JS
217 wxReparenter reparenter;
218 if (!reparenter.WaitAndReparent(m_containerWindow, m_xnestWindow, wxT("Xnest")))
219 {
220 wxMessageBox(wxT("Sorry, could not reparent Xnest.."));
221 frame->Destroy();
abe89c8a 222 return false;
3373d6bf 223 }
0470b382 224
3373d6bf 225#endif
d1b327e1 226 m_containerWindow->DoResize();
3373d6bf
JS
227
228 // success: wxApp::OnRun() will be called which will enter the main message
abe89c8a 229 // loop and the application will run. If we returned false here, the
3373d6bf 230 // application would exit immediately.
abe89c8a 231 return true;
3373d6bf
JS
232}
233
d1b327e1
JS
234// Prepend the current program directory to the name
235wxString wxEmulatorApp::GetFullAppPath(const wxString& filename) const
3373d6bf 236{
d1b327e1
JS
237 wxString path(m_appDir);
238 if (path.Last() != '\\' && path.Last() != '/' && filename[0] != '\\' && filename[0] != '/')
239#ifdef __X__
240 path += '/';
241#else
242 path += '\\';
243#endif
244 path += filename;
abe89c8a 245
d1b327e1
JS
246 return path;
247}
3373d6bf 248
3373d6bf 249
d1b327e1
JS
250// Load the specified emulator.
251// For now, hard-wired. TODO: make this configurable
252bool wxEmulatorApp::LoadEmulator(const wxString& appDir)
253{
254 // Load config file and bitmaps
255 return m_emulatorInfo.Load(appDir);
3373d6bf
JS
256}
257
258// ----------------------------------------------------------------------------
259// main frame
260// ----------------------------------------------------------------------------
261
262// frame constructor
abe89c8a
DS
263wxEmulatorFrame::wxEmulatorFrame(const wxString& title,
264 const wxPoint& pos, const wxSize& size)
265 : wxFrame(NULL, wxID_ANY, title, pos, size)
3373d6bf
JS
266{
267 // set the frame icon
d1b327e1 268 SetIcon(wxICON(emulator));
3373d6bf
JS
269
270#if wxUSE_MENUS
271 // create a menu bar
272 wxMenu *menuFile = new wxMenu;
273
274 // the "About" item should be in the help menu
275 wxMenu *helpMenu = new wxMenu;
276 helpMenu->Append(Emulator_About, _T("&About...\tF1"), _T("Show about dialog"));
277
278 menuFile->Append(Emulator_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
279
280 // now append the freshly created menu to the menu bar...
281 wxMenuBar *menuBar = new wxMenuBar();
282 menuBar->Append(menuFile, _T("&File"));
283 menuBar->Append(helpMenu, _T("&Help"));
284
285 // ... and attach this menu bar to the frame
286 SetMenuBar(menuBar);
287#endif // wxUSE_MENUS
288
289#if wxUSE_STATUSBAR
290 // create a status bar just for fun (by default with 1 pane only)
291 CreateStatusBar(2);
3373d6bf
JS
292#endif // wxUSE_STATUSBAR
293}
294
295
296// event handlers
297
298void wxEmulatorFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
299{
abe89c8a
DS
300 // true is to force the frame to close
301 Close(true);
3373d6bf
JS
302}
303
304void wxEmulatorFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
305{
306 wxString msg;
307 msg.Printf( _T("wxEmulator is an environment for testing embedded X11 apps.\n"));
308
309 wxMessageBox(msg, _T("About wxEmulator"), wxOK | wxICON_INFORMATION, this);
310}
311
dc9b3bf7 312void wxEmulatorFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
d27294ac
JS
313{
314#ifdef __WXX11__
315 if (wxGetApp().m_xnestWindow)
316 {
317 wxGetApp().m_xnestWindow->SetHandle((WXWindow) NULL);
318 }
319#endif
320 this->Destroy();
321 if (wxGetApp().m_xnestPID > 0)
322 {
323 wxKill(wxGetApp().m_xnestPID);
324 wxGetApp().m_xnestPID = 0;
325 }
326}
327
3373d6bf
JS
328IMPLEMENT_CLASS(wxEmulatorContainer, wxWindow)
329
330BEGIN_EVENT_TABLE(wxEmulatorContainer, wxWindow)
331 EVT_SIZE(wxEmulatorContainer::OnSize)
332 EVT_PAINT(wxEmulatorContainer::OnPaint)
333 EVT_ERASE_BACKGROUND(wxEmulatorContainer::OnEraseBackground)
334END_EVENT_TABLE()
335
336wxEmulatorContainer::wxEmulatorContainer(wxWindow* parent, wxWindowID id):
337 wxWindow(parent, id, wxDefaultPosition, wxDefaultSize)
338{
339}
340
dc9b3bf7 341void wxEmulatorContainer::OnSize(wxSizeEvent& WXUNUSED(event))
0470b382
JS
342{
343 DoResize();
344}
345
346void wxEmulatorContainer::DoResize()
3373d6bf
JS
347{
348 wxSize sz = GetClientSize();
d27294ac
JS
349 if (wxGetApp().m_xnestWindow
350#ifdef __WXX11__
351 && wxGetApp().m_xnestWindow->GetMainWindow()
352#endif
353 )
3373d6bf 354 {
d1b327e1
JS
355 int deviceWidth = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.x;
356 int deviceHeight = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.y;
abe89c8a 357
d1b327e1
JS
358 int x = wxMax(0, (int) ((sz.x - deviceWidth)/2.0));
359 int y = wxMax(0, (int) ((sz.y - deviceHeight)/2.0));
abe89c8a 360
3373d6bf
JS
361 x += wxGetApp().m_emulatorInfo.m_emulatorScreenPosition.x;
362 y += wxGetApp().m_emulatorInfo.m_emulatorScreenPosition.y;
abe89c8a 363
3373d6bf
JS
364 wxGetApp().m_xnestWindow->Move(x, y);
365 }
366 Refresh();
367}
368
dc9b3bf7 369void wxEmulatorContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
3373d6bf
JS
370{
371 wxPaintDC dc(this);
abe89c8a 372
3373d6bf
JS
373 wxSize sz = GetClientSize();
374 if (wxGetApp().m_emulatorInfo.m_emulatorBackgroundBitmap.Ok())
375 {
d1b327e1
JS
376 int deviceWidth = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.x;
377 int deviceHeight = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.y;
abe89c8a 378
d1b327e1
JS
379 int x = wxMax(0, (int) ((sz.x - deviceWidth)/2.0));
380 int y = wxMax(0, (int) ((sz.y - deviceHeight)/2.0));
abe89c8a 381
3373d6bf
JS
382 dc.DrawBitmap(wxGetApp().m_emulatorInfo.m_emulatorBackgroundBitmap, x, y);
383 }
384}
385
386void wxEmulatorContainer::OnEraseBackground(wxEraseEvent& event)
387{
abe89c8a
DS
388 wxDC* dc wxDUMMY_INITIALIZE(NULL);
389
3373d6bf
JS
390 if (event.GetDC())
391 {
392 dc = event.GetDC();
393 }
394 else
395 {
396 dc = new wxClientDC(this);
397 }
abe89c8a 398
3373d6bf
JS
399 dc->SetBackground(wxBrush(wxGetApp().m_emulatorInfo.m_emulatorBackgroundColour, wxSOLID));
400 dc->Clear();
abe89c8a 401
3373d6bf
JS
402 if (!event.GetDC())
403 delete dc;
404}
405
406// Information about the emulator decorations
407
408void wxEmulatorInfo::Copy(const wxEmulatorInfo& info)
409{
d1b327e1 410 m_emulatorFilename = info.m_emulatorFilename;
3373d6bf
JS
411 m_emulatorTitle = info.m_emulatorTitle;
412 m_emulatorDescription = info.m_emulatorDescription;
413 m_emulatorScreenPosition = info.m_emulatorScreenPosition;
414 m_emulatorScreenSize = info.m_emulatorScreenSize;
415 m_emulatorBackgroundBitmap = info.m_emulatorBackgroundBitmap;
416 m_emulatorBackgroundBitmapName = info.m_emulatorBackgroundBitmapName;
417 m_emulatorBackgroundColour = info.m_emulatorBackgroundColour;
d1b327e1 418 m_emulatorDeviceSize = info.m_emulatorDeviceSize;
3373d6bf
JS
419}
420
421// Initialisation
422void wxEmulatorInfo::Init()
423{
d1b327e1
JS
424 m_emulatorDeviceSize = wxSize(260, 340);
425 m_emulatorScreenSize = wxSize(240, 320);
3373d6bf
JS
426}
427
428// Loads bitmaps
d1b327e1 429bool wxEmulatorInfo::Load(const wxString& appDir)
3373d6bf 430{
d1b327e1
JS
431 // Try to find absolute path
432 wxString absoluteConfigPath = m_emulatorFilename;
abe89c8a 433 if ( !::wxIsAbsolutePath(absoluteConfigPath) )
d1b327e1
JS
434 {
435 wxString currDir = wxGetCwd();
436 absoluteConfigPath = currDir + wxString(wxFILE_SEP_PATH) + m_emulatorFilename;
abe89c8a 437 if ( !wxFile::Exists(absoluteConfigPath) )
d1b327e1 438 {
abe89c8a
DS
439 absoluteConfigPath = appDir + wxString(wxFILE_SEP_PATH)
440 + m_emulatorFilename;
d1b327e1
JS
441 }
442 }
abe89c8a
DS
443
444 if ( !wxFile::Exists(absoluteConfigPath) )
d1b327e1
JS
445 {
446 wxString str;
abe89c8a
DS
447 str.Printf( wxT("Could not find config file %s"),
448 absoluteConfigPath.c_str() );
449
d1b327e1 450 wxMessageBox(str);
abe89c8a 451 return false;
d1b327e1 452 }
3373d6bf 453
d1b327e1
JS
454 wxString rootPath = wxPathOnly(absoluteConfigPath);
455
456 {
be5a51fb 457 wxFileConfig config(wxT("wxEmulator"), wxT("wxWidgets"),
d1b327e1
JS
458 absoluteConfigPath, wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
459
460 config.Read(wxT("/General/title"), & m_emulatorTitle);
461 config.Read(wxT("/General/description"), & m_emulatorDescription);
462 config.Read(wxT("/General/backgroundBitmap"), & m_emulatorBackgroundBitmapName);
463
464 wxString colString;
465 if (config.Read(wxT("/General/backgroundColour"), & colString) ||
466 config.Read(wxT("/General/backgroundColor"), & colString)
467 )
468 {
469 m_emulatorBackgroundColour = wxHexStringToColour(colString);
470 }
471
472 int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0;
473 config.Read(wxT("/General/screenX"), & x);
474 config.Read(wxT("/General/screenY"), & y);
475 config.Read(wxT("/General/screenWidth"), & w);
476 config.Read(wxT("/General/screenHeight"), & h);
477 if (config.Read(wxT("/General/deviceWidth"), & dw) && config.Read(wxT("/General/deviceHeight"), & dh))
478 {
479 m_emulatorDeviceSize = wxSize(dw, dh);
480 }
481
482 m_emulatorScreenPosition = wxPoint(x, y);
483 m_emulatorScreenSize = wxSize(w, h);
484 }
abe89c8a 485
eda6fa91 486 if (!m_emulatorBackgroundBitmapName.empty())
d1b327e1
JS
487 {
488 wxString absoluteBackgroundBitmapName = rootPath + wxString(wxFILE_SEP_PATH) + m_emulatorBackgroundBitmapName;
abe89c8a 489 if ( !wxFile::Exists(absoluteBackgroundBitmapName) )
d1b327e1
JS
490 {
491 wxString str;
abe89c8a
DS
492 str.Printf( wxT("Could not find bitmap %s"),
493 absoluteBackgroundBitmapName.c_str() );
d1b327e1 494 wxMessageBox(str);
abe89c8a 495 return false;
d1b327e1 496 }
abe89c8a 497
723c433f
GD
498 wxBitmapType type = wxDetermineImageType(m_emulatorBackgroundBitmapName);
499 if (type == wxBITMAP_TYPE_INVALID)
abe89c8a
DS
500 return false;
501
d1b327e1
JS
502 if (!m_emulatorBackgroundBitmap.LoadFile(m_emulatorBackgroundBitmapName, type))
503 {
504 wxString str;
abe89c8a
DS
505 str.Printf( wxT("Could not load bitmap file %s"),
506 m_emulatorBackgroundBitmapName.c_str() );
d1b327e1 507 wxMessageBox(str);
abe89c8a 508 return false;
d1b327e1 509 }
abe89c8a 510
d1b327e1
JS
511 m_emulatorDeviceSize = wxSize(m_emulatorBackgroundBitmap.GetWidth(),
512 m_emulatorBackgroundBitmap.GetHeight());
513 }
abe89c8a 514 return true;
3373d6bf
JS
515}
516
517// Returns the image type, or -1, determined from the extension.
723c433f 518wxBitmapType wxDetermineImageType(const wxString& filename)
3373d6bf
JS
519{
520 wxString path, name, ext;
521
522 wxSplitPath(filename, & path, & name, & ext);
523
524 ext.MakeLower();
dc9b3bf7 525 if (ext == _T("jpg") || ext == _T("jpeg"))
3373d6bf 526 return wxBITMAP_TYPE_JPEG;
dc9b3bf7 527 if (ext == _T("gif"))
3373d6bf 528 return wxBITMAP_TYPE_GIF;
dc9b3bf7 529 if (ext == _T("bmp"))
3373d6bf 530 return wxBITMAP_TYPE_BMP;
dc9b3bf7 531 if (ext == _T("png"))
3373d6bf 532 return wxBITMAP_TYPE_PNG;
dc9b3bf7 533 if (ext == _T("pcx"))
3373d6bf 534 return wxBITMAP_TYPE_PCX;
dc9b3bf7 535 if (ext == _T("tif") || ext == _T("tiff"))
3373d6bf 536 return wxBITMAP_TYPE_TIF;
abe89c8a 537
723c433f 538 return wxBITMAP_TYPE_INVALID;
3373d6bf
JS
539}
540
d1b327e1
JS
541// Convert a colour to a 6-digit hex string
542wxString wxColourToHexString(const wxColour& col)
543{
544 wxString hex;
545
546 hex += wxDecToHex(col.Red());
547 hex += wxDecToHex(col.Green());
548 hex += wxDecToHex(col.Blue());
549
550 return hex;
551}
552
553// Convert 6-digit hex string to a colour
554wxColour wxHexStringToColour(const wxString& hex)
555{
254a2129
WS
556 unsigned char r = (unsigned char)wxHexToDec(hex.Mid(0, 2));
557 unsigned char g = (unsigned char)wxHexToDec(hex.Mid(2, 2));
558 unsigned char b = (unsigned char)wxHexToDec(hex.Mid(4, 2));
d1b327e1
JS
559
560 return wxColour(r, g, b);
561}
562
563// Find the absolute path where this application has been run from.
564// argv0 is wxTheApp->argv[0]
565// cwd is the current working directory (at startup)
566// appVariableName is the name of a variable containing the directory for this app, e.g.
567// MYAPPDIR. This is checked first.
568
569wxString wxFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
570{
571 wxString str;
572
573 // Try appVariableName
eda6fa91 574 if (!appVariableName.empty())
d1b327e1
JS
575 {
576 str = wxGetenv(appVariableName);
eda6fa91 577 if (!str.empty())
d1b327e1
JS
578 return str;
579 }
580
581 if (wxIsAbsolutePath(argv0))
582 return wxPathOnly(argv0);
583 else
584 {
585 // Is it a relative path?
586 wxString currentDir(cwd);
083f7497 587 if (!wxEndsWithPathSeparator(currentDir))
d1b327e1
JS
588 currentDir += wxFILE_SEP_PATH;
589
590 str = currentDir + argv0;
abe89c8a 591 if ( wxFile::Exists(str) )
d1b327e1
JS
592 return wxPathOnly(str);
593 }
594
595 // OK, it's neither an absolute path nor a relative path.
596 // Search PATH.
597
598 wxPathList pathList;
599 pathList.AddEnvList(wxT("PATH"));
600 str = pathList.FindAbsoluteValidPath(argv0);
eda6fa91 601 if (!str.empty())
d1b327e1
JS
602 return wxPathOnly(str);
603
604 // Failed
605 return wxEmptyString;
606}
3373d6bf 607