winmain.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:138k
- // winmain.cpp
- //
- // Copyright (C) 2001-2007, Chris Laurel <claurel@shatters.net>
- //
- // Windows front end for Celestia.
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // as published by the Free Software Foundation; either version 2
- // of the License, or (at your option) any later version.
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <algorithm>
- #include <set>
- #include <cstdlib>
- #include <cctype>
- #include <cstring>
- #include <cassert>
- #include <process.h>
- #include <time.h>
- #include <windows.h>
- #include <commctrl.h>
- #include <mmsystem.h>
- #include <celmath/vecmath.h>
- #include <celmath/quaternion.h>
- #include <celmath/mathlib.h>
- #include <celutil/debug.h>
- #include <celutil/util.h>
- #include <celutil/winutil.h>
- #include <celutil/filetype.h>
- #include <celengine/celestia.h>
- #include <celengine/astro.h>
- #include <celengine/cmdparser.h>
- #include <celengine/axisarrow.h>
- #include <celengine/planetgrid.h>
- #include "../celengine/gl.h"
- #include "../celengine/glext.h"
- #include "celestiacore.h"
- #include "imagecapture.h"
- #include "avicapture.h"
- #include "url.h"
- #include "winstarbrowser.h"
- #include "winssbrowser.h"
- #include "wintourguide.h"
- #include "wingotodlg.h"
- #include "winviewoptsdlg.h"
- #include "winlocations.h"
- #include "winbookmarks.h"
- #include "wineclipses.h"
- #include "winhyperlinks.h"
- #include "wintime.h"
- #include "winsplash.h"
- #include "odmenu.h"
- #include "scriptmenu.h"
- #include "res/resource.h"
- #include "wglext.h"
- #include <locale.h>
- using namespace std;
- typedef pair<int,string> IntStrPair;
- typedef vector<IntStrPair> IntStrPairVec;
- char AppName[] = "Celestia";
- static CelestiaCore* appCore = NULL;
- // Display modes for full screen operation
- static vector<DEVMODE>* displayModes = NULL;
- // Display mode indices
- static int currentScreenMode = 0;
- static int newScreenMode = 0;
- // The last fullscreen mode set; saved and restored from the registry
- static int lastFullScreenMode = 0;
- // A fullscreen mode guaranteed to work
- static int fallbackFullScreenMode = 0;
- static RECT windowRect;
- static HGLRC glContext;
- static HDC deviceContext;
- static bool bReady = false;
- static LPTSTR CelestiaRegKey = "Software\Shatters.net\Celestia";
- HINSTANCE appInstance;
- HMODULE hRes;
- HWND mainWindow = 0;
- static SolarSystemBrowser* solarSystemBrowser = NULL;
- static StarBrowser* starBrowser = NULL;
- static TourGuide* tourGuide = NULL;
- static GotoObjectDialog* gotoObjectDlg = NULL;
- static ViewOptionsDialog* viewOptionsDlg = NULL;
- static EclipseFinderDialog* eclipseFinder = NULL;
- static LocationsDialog* locationsDlg = NULL;
- static SplashWindow* s_splash = NULL;
- static HMENU menuBar = 0;
- ODMenu odAppMenu;
- static HACCEL acceleratorTable = 0;
- static bool hideMenuBar = false;
- // Joystick info
- static bool useJoystick = false;
- static bool joystickAvailable = false;
- static JOYCAPS joystickCaps;
- static HCURSOR hDefaultCursor = 0;
- bool cursorVisible = true;
- static POINT saveCursorPos;
- static POINT lastMouseMove;
- class WinCursorHandler;
- WinCursorHandler* cursorHandler = NULL;
- static int MovieSizes[8][2] = {
- { 160, 120 },
- { 320, 240 },
- { 640, 480 },
- { 720, 480 },
- { 720, 576 },
- { 1024, 768 },
- { 1280, 720 },
- { 1920, 1080 }
- };
- static float MovieFramerates[5] = { 15.0f, 24.0f, 25.0f, 29.97f, 30.0f };
- static int movieSize = 1;
- static int movieFramerate = 1;
- astro::Date newTime(0.0);
- #define REFMARKS 1
- #define INFINITE_MOUSE
- static int lastX = 0;
- static int lastY = 0;
- static bool ignoreNextMoveEvent = false;
- static const WPARAM ID_GOTO_URL = 62000;
- HWND hBookmarkTree;
- char bookmarkName[33];
- static const string ScriptsDirectory = "scripts";
- static vector<ScriptMenuItem>* ScriptMenuItems = NULL;
- static LRESULT CALLBACK MainWindowProc(HWND hWnd,
- UINT uMsg,
- WPARAM wParam, LPARAM lParam);
- #define MENU_CHOOSE_PLANET 32000
- #define MENU_CHOOSE_SURFACE 31000
- struct AppPreferences
- {
- int winWidth;
- int winHeight;
- int winX;
- int winY;
- int renderFlags;
- int labelMode;
- int orbitMask;
- float visualMagnitude;
- float ambientLight;
- float galaxyLightGain;
- int showLocalTime;
- int dateFormat;
- int hudDetail;
- int fullScreenMode;
- uint32 lastVersion;
- string altSurfaceName;
- uint32 textureResolution;
- Renderer::StarStyle starStyle;
- GLContext::GLRenderPath renderPath;
- bool renderPathSet;
- };
- void ChangeDisplayMode()
- {
- DEVMODE device_mode;
- memset(&device_mode, 0, sizeof(DEVMODE));
- device_mode.dmSize = sizeof(DEVMODE);
- device_mode.dmPelsWidth = 800;
- device_mode.dmPelsHeight = 600;
- device_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- ChangeDisplaySettings(&device_mode, CDS_FULLSCREEN);
- }
- void RestoreDisplayMode()
- {
- ChangeDisplaySettings(0, 0);
- }
- //
- // A very minimal IDropTarget interface implementation
- //
- class CelestiaDropTarget : public IDropTarget
- {
- public:
- CelestiaDropTarget();
- ~CelestiaDropTarget();
- STDMETHOD (QueryInterface)(REFIID idd, void** ppvObject);
- STDMETHOD_ (ULONG, AddRef) (void);
- STDMETHOD_ (ULONG, Release) (void);
- // IDropTarget methods
- STDMETHOD (DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
- STDMETHOD (DragOver) (DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
- STDMETHOD (DragLeave)(void);
- STDMETHOD (Drop) (LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
- private:
- ULONG refCount;
- };
- static CelestiaDropTarget* dropTarget = NULL;
- CelestiaDropTarget::CelestiaDropTarget() :
- refCount(0)
- {
- }
- CelestiaDropTarget::~CelestiaDropTarget()
- {
- }
- HRESULT CelestiaDropTarget::QueryInterface(REFIID iid, void** ppvObject)
- {
- if (iid == IID_IUnknown || iid == IID_IDropTarget)
- {
- *ppvObject = this;
- AddRef();
- return ResultFromScode(S_OK);
- }
- else
- {
- *ppvObject = NULL;
- return ResultFromScode(E_NOINTERFACE);
- }
- }
- ULONG CelestiaDropTarget::AddRef(void)
- {
- return ++refCount;
- }
- ULONG CelestiaDropTarget::Release(void)
- {
- if (--refCount == 0)
- {
- delete this;
- return 0;
- }
- return refCount;
- }
- STDMETHODIMP
- CelestiaDropTarget::DragEnter(IDataObject* pDataObject,
- DWORD grfKeyState,
- POINTL pt,
- DWORD* pdwEffect)
- {
- return S_OK;
- }
- STDMETHODIMP
- CelestiaDropTarget::DragOver(DWORD grfKeyState,
- POINTL pt,
- DWORD* pdwEffect)
- {
- return S_OK;
- }
- STDMETHODIMP
- CelestiaDropTarget::DragLeave(void)
- {
- return S_OK;
- }
- STDMETHODIMP
- CelestiaDropTarget::Drop(IDataObject* pDataObject,
- DWORD grfKeyState,
- POINTL pt,
- DWORD* pdwEffect)
- {
- IEnumFORMATETC* enumFormat = NULL;
- HRESULT hr = pDataObject->EnumFormatEtc(DATADIR_GET, &enumFormat);
- if (FAILED(hr) || enumFormat == NULL)
- return E_FAIL;
- FORMATETC format;
- ULONG nFetched;
- while (enumFormat->Next(1, &format, &nFetched) == S_OK)
- {
- char buf[512];
- if (GetClipboardFormatName(format.cfFormat, buf, 511) != 0 &&
- !strcmp(buf, "UniformResourceLocator"))
- {
- STGMEDIUM medium;
- if (pDataObject->GetData(&format, &medium) == S_OK)
- {
- if (medium.tymed == TYMED_HGLOBAL && medium.hGlobal != 0)
- {
- char* s = (char*) GlobalLock(medium.hGlobal);
- appCore->goToUrl(s);
- GlobalUnlock(medium.hGlobal);
- break;
- }
- }
- }
- }
- enumFormat->Release();
- return E_FAIL;
- }
- // Cursor handler callback class for Windows. We pass an instance to
- // the app core which the calls the setCursorShape method to change
- // the cursor icon.
- class WinCursorHandler : public CelestiaCore::CursorHandler
- {
- public:
- WinCursorHandler(HCURSOR _defaultCursor);
- virtual ~WinCursorHandler();
- virtual void setCursorShape(CelestiaCore::CursorShape);
- virtual CelestiaCore::CursorShape getCursorShape() const;
- private:
- CelestiaCore::CursorShape shape;
- HCURSOR defaultCursor;
- HCURSOR sizeVertical;
- HCURSOR sizeHorizontal;
- };
- WinCursorHandler::WinCursorHandler(HCURSOR _defaultCursor) :
- shape(CelestiaCore::ArrowCursor),
- defaultCursor(_defaultCursor)
- {
- sizeVertical = LoadCursor(NULL, IDC_SIZENS);
- sizeHorizontal = LoadCursor(NULL, IDC_SIZEWE);
- }
- WinCursorHandler::~WinCursorHandler()
- {
- }
- void WinCursorHandler::setCursorShape(CelestiaCore::CursorShape _shape)
- {
- shape = _shape;
- switch (shape)
- {
- case CelestiaCore::SizeVerCursor:
- SetCursor(sizeVertical);
- break;
- case CelestiaCore::SizeHorCursor:
- SetCursor(sizeHorizontal);
- break;
- default:
- SetCursor(defaultCursor);
- break;
- }
- }
- CelestiaCore::CursorShape WinCursorHandler::getCursorShape() const
- {
- return shape;
- }
- // end WinCursorHandler methods
- static void ShowUniversalTime(CelestiaCore* appCore)
- {
- appCore->setTimeZoneBias(0);
- appCore->setTimeZoneName("UTC");
- }
- static void ShowLocalTime(CelestiaCore* appCore)
- {
- TIME_ZONE_INFORMATION tzi;
- DWORD dst = GetTimeZoneInformation(&tzi);
- if (dst != TIME_ZONE_ID_INVALID)
- {
- LONG dstBias = 0;
- WCHAR* tzName = NULL;
- if (dst == TIME_ZONE_ID_STANDARD)
- {
- dstBias = tzi.StandardBias;
- tzName = tzi.StandardName;
- }
- else if (dst == TIME_ZONE_ID_DAYLIGHT)
- {
- dstBias = tzi.DaylightBias;
- tzName = tzi.DaylightName;
- }
- appCore->setTimeZoneName(" ");
- appCore->setTimeZoneBias((tzi.Bias + dstBias) * -60);
- }
- }
- static bool BeginMovieCapture(const std::string& filename,
- int width, int height,
- float framerate)
- {
- MovieCapture* movieCapture = new AVICapture();
- bool success = movieCapture->start(filename, width, height, framerate);
- if (success)
- appCore->initMovieCapture(movieCapture);
- else
- delete movieCapture;
- return success;
- }
- static bool CopyStateURLToClipboard()
- {
- BOOL b;
- b = OpenClipboard(mainWindow);
- if (!b)
- return false;
- CelestiaState appState;
- appState.captureState(appCore);
-
- Url url(appState, Url::CurrentVersion);
- string urlString = url.getAsString();
- char* s = const_cast<char*>(urlString.c_str());
- HGLOBAL clipboardDataHandle = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,
- strlen(s) + 1);
- char* clipboardData = (char*) GlobalLock(clipboardDataHandle);
- if (clipboardData != NULL)
- {
- strcpy(clipboardData, s);
- GlobalUnlock(clipboardDataHandle);
- EmptyClipboard();
- HANDLE h = SetClipboardData(CF_TEXT, clipboardDataHandle);
- CloseClipboard();
- return h != NULL;
- }
- else
- {
- CloseClipboard();
- return false;
- }
- }
- static bool ToggleMenuItem(HMENU menu, int id)
- {
- MENUITEMINFO menuInfo;
- menuInfo.cbSize = sizeof(MENUITEMINFO);
- menuInfo.fMask = MIIM_STATE;
- if (GetMenuItemInfo(menu, id, FALSE, &menuInfo))
- {
- bool isChecked = ((menuInfo.fState & MFS_CHECKED) != 0);
- CheckMenuItem(menu, id, isChecked ? MF_UNCHECKED : MF_CHECKED);
- return !isChecked;
- }
- return false;
- }
- bool LoadItemTextFromFile(HWND hWnd,
- int item,
- char* filename)
- {
- // ifstream textFile(filename, ios::in | ios::binary);
- ifstream textFile(filename, ios::in);
- string s;
- if (!textFile.good())
- {
- SetDlgItemText(hWnd, item, "License file missing!rrnSee http://www.gnu.org/copyleft/gpl.html");
- return true;
- }
- char c;
- while (textFile.get(c))
- {
- if (c == 'n')
- s += "rrn";
- else
- s += c;
- }
- SetDlgItemText(hWnd, item, UTF8ToCurrentCP(s).c_str());
- return true;
- }
- BOOL APIENTRY AboutProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- MakeHyperlinkFromStaticCtrl(hDlg, IDC_CELESTIALINK);
- return(TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDC_CELESTIALINK)
- {
- char urlBuf[256];
- HWND hCtrl = GetDlgItem(hDlg, IDC_CELESTIALINK);
- if (hCtrl)
- {
- if (GetWindowText(hCtrl, urlBuf, sizeof(urlBuf)) > 0)
- {
- ShellExecute(hDlg, "open", urlBuf, NULL, NULL, SW_SHOWNORMAL);
- return TRUE;
- }
- }
- }
- break;
- }
- return FALSE;
- }
- BOOL APIENTRY ControlsHelpProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- LoadItemTextFromFile(hDlg, IDC_TEXT_CONTROLSHELP, const_cast<char*>(LocaleFilename("controls.txt").c_str()));
- return(TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
- BOOL APIENTRY LicenseProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- LoadItemTextFromFile(hDlg, IDC_LICENSE_TEXT, const_cast<char*>(LocaleFilename("COPYING").c_str()));
- return(TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
- BOOL APIENTRY GLInfoProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- {
- const char* vendor = (char*) glGetString(GL_VENDOR);
- const char* render = (char*) glGetString(GL_RENDERER);
- const char* version = (char*) glGetString(GL_VERSION);
- const char* ext = (char*) glGetString(GL_EXTENSIONS);
- string s;
- s += UTF8ToCurrentCP(_("Vendor: "));
- if (vendor != NULL)
- s += vendor;
- s += "rrn";
- s += UTF8ToCurrentCP(_("Renderer: "));
- if (render != NULL)
- s += render;
- s += "rrn";
- s += UTF8ToCurrentCP(_("Version: "));
- if (version != NULL)
- s += version;
- s += "rrn";
- if (ExtensionSupported("GL_ARB_shading_language_100"))
- {
- const char* versionString = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
- if (versionString != NULL)
- {
- s += UTF8ToCurrentCP(_("GLSL version: "));
- s += versionString;
- s += "rrn";
- }
- }
- char buf[1024];
- GLint simTextures = 1;
- if (ExtensionSupported("GL_ARB_multitexture"))
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &simTextures);
- sprintf(buf, "%s%drrn",
- UTF8ToCurrentCP(_("Max simultaneous textures: ")).c_str(),
- simTextures);
- s += buf;
- GLint maxTextureSize = 0;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
- sprintf(buf, "%s%drrn",
- UTF8ToCurrentCP(_("Max texture size: ")).c_str(),
- maxTextureSize);
- s += buf;
- if (ExtensionSupported("GL_EXT_texture_cube_map"))
- {
- GLint maxCubeMapSize = 0;
- glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &maxCubeMapSize);
- sprintf(buf, "%s%drrn",
- UTF8ToCurrentCP(_("Max cube map size: ")).c_str(),
- maxTextureSize);
- s += buf;
- }
- GLfloat pointSizeRange[2];
- glGetFloatv(GL_POINT_SIZE_RANGE, pointSizeRange);
- sprintf(buf, "%s%f - %frrn",
- UTF8ToCurrentCP(_("Point size range: ")).c_str(),
- pointSizeRange[0], pointSizeRange[1]);
- s += buf;
- s += "rrn";
- s += UTF8ToCurrentCP(_("Supported Extensions:")).c_str();
- s += "rrn";
- if (ext != NULL)
- {
- string extString(ext);
- int pos = extString.find(' ', 0);
- while (pos != string::npos)
- {
- extString.replace(pos, 1, "rrn");
- pos = extString.find(' ', pos);
- }
- s += extString;
- }
- SetDlgItemText(hDlg, IDC_GLINFO_TEXT, s.c_str());
- }
- return(TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
- UINT CALLBACK ChooseMovieParamsProc(HWND hDlg, UINT message,
- WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- {
- char buf[100];
- HWND hwnd = GetDlgItem(hDlg, IDC_COMBO_MOVIE_SIZE);
- int nSizes = sizeof MovieSizes / sizeof MovieSizes[0];
- int i;
- for (i = 0; i < nSizes; i++)
- {
- sprintf(buf, "%d x %d", MovieSizes[i][0], MovieSizes[i][1]);
- SendMessage(hwnd, CB_INSERTSTRING, -1,
- reinterpret_cast<LPARAM>(buf));
- }
- SendMessage(hwnd, CB_SETCURSEL, movieSize, 0);
- hwnd = GetDlgItem(hDlg, IDC_COMBO_MOVIE_FRAMERATE);
- int nFramerates = sizeof MovieFramerates / sizeof MovieFramerates[0];
- for (i = 0; i < nFramerates; i++)
- {
- sprintf(buf, "%.2f", MovieFramerates[i]);
- SendMessage(hwnd, CB_INSERTSTRING, -1,
- reinterpret_cast<LPARAM>(buf));
- }
- SendMessage(hwnd, CB_SETCURSEL, movieFramerate, 0);
- }
- return TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDC_COMBO_MOVIE_SIZE)
- {
- if (HIWORD(wParam) == CBN_SELCHANGE)
- {
- HWND hwnd = reinterpret_cast<HWND>(lParam);
- int item = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
- if (item != CB_ERR)
- movieSize = item;
- }
- return TRUE;
- }
- else if (LOWORD(wParam) == IDC_COMBO_MOVIE_FRAMERATE)
- {
- if (HIWORD(wParam) == CBN_SELCHANGE)
- {
- HWND hwnd = reinterpret_cast<HWND>(lParam);
- int item = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
- if (item != CB_ERR)
- movieFramerate = item;
- }
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL APIENTRY FindObjectProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return(TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK)
- {
- char buf[1024], out[1024];
- wchar_t wbuff[1024];
- int len = GetDlgItemText(hDlg, IDC_FINDOBJECT_EDIT, buf, sizeof(buf));
- if (len > 0)
- {
- int wlen = MultiByteToWideChar(CP_ACP, 0, buf, -1, wbuff, sizeof(wbuff));
- WideCharToMultiByte(CP_UTF8, 0, wbuff, wlen, out, sizeof(out), NULL, NULL);
- Selection sel = appCore->getSimulation()->findObject(string(out), true);
- if (!sel.empty())
- appCore->getSimulation()->setSelection(sel);
- }
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return FALSE;
- }
- break;
- }
- return FALSE;
- }
- BOOL APIENTRY AddBookmarkFolderProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- {
- // Center dialog directly over parent
- HWND hParent = GetParent(hDlg);
- CenterWindow(hParent, hDlg);
- // Limit text of folder name to 32 chars
- HWND hEdit = GetDlgItem(hDlg, IDC_BOOKMARKFOLDER);
- SendMessage(hEdit, EM_LIMITTEXT, 32, 0);
- // Set initial button states
- HWND hOK = GetDlgItem(hDlg, IDOK);
- HWND hCancel = GetDlgItem(hDlg, IDCANCEL);
- EnableWindow(hOK, FALSE);
- RemoveButtonDefaultStyle(hOK);
- AddButtonDefaultStyle(hCancel);
- }
- return TRUE;
- case WM_COMMAND:
- {
- if (HIWORD(wParam) == EN_CHANGE)
- {
- HWND hOK = GetDlgItem(hDlg, IDOK);
- HWND hCancel = GetDlgItem(hDlg, IDCANCEL);
- if (hOK && hCancel)
- {
- // If edit control contains text, enable OK button
- char name[33];
- GetWindowText((HWND)lParam, name, sizeof(name));
- if (name[0])
- {
- // Remove Cancel button default style
- RemoveButtonDefaultStyle(hCancel);
- // Enable OK button
- EnableWindow(hOK, TRUE);
- // Make OK button default
- AddButtonDefaultStyle(hOK);
- }
- else
- {
- // Disable OK button
- EnableWindow(hOK, FALSE);
- // Remove OK button default style
- RemoveButtonDefaultStyle(hOK);
- // Make Cancel button default
- AddButtonDefaultStyle(hCancel);
- }
- }
- }
- }
- if (LOWORD(wParam) == IDOK)
- {
- // Get text entered in Folder Name Edit box
- char name[33];
- HWND hEdit = GetDlgItem(hDlg, IDC_BOOKMARKFOLDER);
- if (hEdit)
- {
- if (GetWindowText(hEdit, name, sizeof(name)))
- {
- // Create new folder in parent dialog tree control.
- AddNewBookmarkFolderInTree(hBookmarkTree, appCore, name);
- }
- }
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return FALSE;
- }
- }
- return FALSE;
- }
- BOOL APIENTRY AddBookmarkProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- {
- RECT dlgRect, treeRect;
- HWND hCtrl;
- if (GetWindowRect(hDlg, &dlgRect))
- {
- if (hCtrl = GetDlgItem(hDlg, IDC_BOOKMARK_FOLDERTREE))
- {
- if (GetWindowRect(hCtrl, &treeRect))
- {
- int width = dlgRect.right - dlgRect.left;
- int height = treeRect.top - dlgRect.top;
- SetWindowPos(hDlg, HWND_TOP, 0, 0, width, height,
- SWP_NOMOVE | SWP_NOZORDER);
- }
- HTREEITEM hParent;
- if (hParent = PopulateBookmarkFolders(hCtrl, appCore, appInstance))
- {
- //Expand bookmarks item
- TreeView_Expand(hCtrl, hParent, TVE_EXPAND);
- }
- }
- }
- //Set initial button states
- HWND hOK = GetDlgItem(hDlg, IDOK);
- HWND hCancel = GetDlgItem(hDlg, IDCANCEL);
- EnableWindow(hOK, FALSE);
- RemoveButtonDefaultStyle(hOK);
- AddButtonDefaultStyle(hCancel);
- // Set bookmark text to selection text
- if (hCtrl = GetDlgItem(hDlg, IDC_BOOKMARK_EDIT))
- {
- //If this is a body, set the text.
- Selection sel = appCore->getSimulation()->getSelection();
- switch (sel.getType())
- {
- case Selection::Type_Body:
- {
- string name = UTF8ToCurrentCP(sel.body()->getName(true));
- SetWindowText(hCtrl, (char*)name.c_str());
- }
- break;
- default:
- break;
- }
- }
- return(TRUE);
- }
- case WM_COMMAND:
- {
- if (HIWORD(wParam) == EN_CHANGE)
- {
- HWND hOK = GetDlgItem(hDlg, IDOK);
- HWND hCancel = GetDlgItem(hDlg, IDCANCEL);
- if (hOK && hCancel)
- {
- //If edit control contains text, enable OK button
- char name[33];
- GetWindowText((HWND)lParam, name, sizeof(name));
- if (name[0])
- {
- //Remove Cancel button default style
- RemoveButtonDefaultStyle(hCancel);
- //Enable OK button
- EnableWindow(hOK, TRUE);
- //Make OK button default
- AddButtonDefaultStyle(hOK);
- }
- else
- {
- //Disable OK button
- EnableWindow(hOK, FALSE);
- //Remove OK button default style
- RemoveButtonDefaultStyle(hOK);
- //Make Cancel button default
- AddButtonDefaultStyle(hCancel);
- }
- }
- }
- if (LOWORD(wParam) == IDOK)
- {
- char name[33];
- int len = GetDlgItemText(hDlg, IDC_BOOKMARK_EDIT, name, sizeof(name));
- if (len > 0)
- {
- HWND hTree;
- if(hTree = GetDlgItem(hDlg, IDC_BOOKMARK_FOLDERTREE))
- {
- InsertBookmarkInFavorites(hTree, name, appCore);
- appCore->writeFavoritesFile();
- // Rebuild bookmarks menu.
- BuildFavoritesMenu(menuBar, appCore, appInstance, &odAppMenu);
- }
- }
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return FALSE;
- }
- else if (LOWORD(wParam) == IDC_BOOKMARK_CREATEIN)
- {
- HWND button;
- RECT dlgRect, treeRect;
- HWND hTree;
- char text[16];
- if (GetWindowRect(hDlg, &dlgRect))
- {
- if (hTree = GetDlgItem(hDlg, IDC_BOOKMARK_FOLDERTREE))
- {
- if (GetWindowRect(hTree, &treeRect))
- {
- if (button = GetDlgItem(hDlg, IDC_BOOKMARK_CREATEIN))
- {
- if (GetWindowText(button, text, sizeof(text)))
- {
- int width = dlgRect.right - dlgRect.left;
- if (strstr(text, ">>"))
- {
- //Increase size of dialog
- int height = treeRect.bottom - dlgRect.top + 12;
- SetWindowPos(hDlg, HWND_TOP, 0, 0, width, height,
- SWP_NOMOVE | SWP_NOZORDER);
- //Change text in button
- strcpy(text + strlen(text) - 2, "<<");
- SetWindowText(button, text);
- }
- else
- {
- //Decrease size of dialog
- int height = treeRect.top - dlgRect.top;
- SetWindowPos(hDlg, HWND_TOP, 0, 0, width, height,
- SWP_NOMOVE | SWP_NOZORDER);
- //Change text in button
- strcpy(text + strlen(text) - 2, ">>");
- SetWindowText(button, text);
- }
- }
- }
- }
- }
- }
- }
- else if (LOWORD(wParam) == IDC_BOOKMARK_NEWFOLDER)
- {
- if(hBookmarkTree = GetDlgItem(hDlg, IDC_BOOKMARK_FOLDERTREE))
- {
- DialogBox(hRes, MAKEINTRESOURCE(IDD_ADDBOOKMARK_FOLDER),
- hDlg, AddBookmarkFolderProc);
- }
- }
- break;
- }
- }
- return FALSE;
- }
- BOOL APIENTRY RenameBookmarkProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- {
- //Center dialog directly over parent
- HWND hParent = GetParent(hDlg);
- CenterWindow(hParent, hDlg);
- //Limit text of folder name to 32 chars
- HWND hEdit = GetDlgItem(hDlg, IDC_NEWBOOKMARK);
- SendMessage(hEdit, EM_LIMITTEXT, 32, 0);
- //Set text in edit control to current bookmark name
- SetWindowText(hEdit, bookmarkName);
- return(TRUE);
- }
- case WM_COMMAND:
- {
- if (HIWORD(wParam) == EN_CHANGE)
- {
- HWND hOK = GetDlgItem(hDlg, IDOK);
- HWND hCancel = GetDlgItem(hDlg, IDCANCEL);
- if (hOK && hCancel)
- {
- //If edit control contains text, enable OK button
- char name[33];
- GetWindowText((HWND)lParam, name, sizeof(name));
- if (name[0])
- {
- //Remove Cancel button default style
- RemoveButtonDefaultStyle(hCancel);
- //Enable OK button
- EnableWindow(hOK, TRUE);
- //Make OK button default
- AddButtonDefaultStyle(hOK);
- }
- else
- {
- //Disable OK button
- EnableWindow(hOK, FALSE);
- //Remove OK button default style
- RemoveButtonDefaultStyle(hOK);
- //Make Cancel button default
- AddButtonDefaultStyle(hCancel);
- }
- }
- }
- if (LOWORD(wParam) == IDOK)
- {
- //Get text entered in Folder Name Edit box
- char name[33];
- HWND hEdit = GetDlgItem(hDlg, IDC_NEWBOOKMARK);
- if (hEdit)
- {
- if (GetWindowText(hEdit, name, sizeof(name)))
- RenameBookmarkInFavorites(hBookmarkTree, name, appCore);
- }
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return FALSE;
- }
- }
- }
- return FALSE;
- }
- BOOL APIENTRY OrganizeBookmarksProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- static UINT_PTR dragDropTimer;
- switch (message)
- {
- case WM_INITDIALOG:
- {
- HWND hCtrl;
- if (hCtrl = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- HTREEITEM hParent;
- if (hParent = PopulateBookmarksTree(hCtrl, appCore, hRes))
- {
- // Expand bookmarks item
- TreeView_Expand(hCtrl, hParent, TVE_EXPAND);
- }
- }
- if (hCtrl = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARKS_DELETE))
- EnableWindow(hCtrl, FALSE);
- if (hCtrl = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARKS_RENAME))
- EnableWindow(hCtrl, FALSE);
- return(TRUE);
- }
- case WM_COMMAND:
- {
- if (LOWORD(wParam) == IDOK)
- {
- #if 0
- HWND hTree;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- SyncTreeFoldersWithFavoriteFolders(hTree, appCore);
- #endif
- // Write any change to bookmarks
- appCore->writeFavoritesFile();
- // Rebuild bookmarks menu
- BuildFavoritesMenu(menuBar, appCore, hRes, &odAppMenu);
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- //Refresh from file
- appCore->readFavoritesFile();
- EndDialog(hDlg, 0);
- return FALSE;
- }
- else if (LOWORD(wParam) == IDC_ORGANIZE_BOOKMARKS_NEWFOLDER)
- {
- if (hBookmarkTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- DialogBox(hRes, MAKEINTRESOURCE(IDD_ADDBOOKMARK_FOLDER), hDlg, AddBookmarkFolderProc);
- }
- }
- else if (LOWORD(wParam) == IDC_ORGANIZE_BOOKMARKS_RENAME)
- {
- if (hBookmarkTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- HTREEITEM hItem;
- TVITEM tvItem;
- if (hItem = TreeView_GetSelection(hBookmarkTree))
- {
- tvItem.hItem = hItem;
- tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
- tvItem.pszText = bookmarkName;
- tvItem.cchTextMax = sizeof(bookmarkName);
- if (TreeView_GetItem(hBookmarkTree, &tvItem))
- {
- DialogBox(hRes,
- MAKEINTRESOURCE(IDD_RENAME_BOOKMARK),
- hDlg, RenameBookmarkProc);
- }
- }
- }
- }
- else if (LOWORD(wParam) == IDC_ORGANIZE_BOOKMARKS_DELETE)
- {
- HWND hTree;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- DeleteBookmarkFromFavorites(hTree, appCore);
- }
- break;
- }
- case WM_NOTIFY:
- {
- if (((LPNMHDR)lParam)->code == TVN_SELCHANGED)
- {
- HWND hTree;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- //Enable buttons as necessary
- HTREEITEM hItem;
- if (hItem = TreeView_GetSelection(hTree))
- {
- HWND hDelete, hRename;
- hDelete = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARKS_DELETE);
- hRename = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARKS_RENAME);
- if (hDelete && hRename)
- {
- if (TreeView_GetParent(hTree, hItem))
- {
- EnableWindow(hDelete, TRUE);
- EnableWindow(hRename, TRUE);
- }
- else
- {
- EnableWindow(hDelete, FALSE);
- EnableWindow(hRename, FALSE);
- }
- }
- }
- }
- }
- else if(((LPNMHDR)lParam)->code == TVN_BEGINDRAG)
- {
- //Do not allow folders to be dragged
- HWND hTree;
- TVITEM tvItem;
- LPNMTREEVIEW nm = (LPNMTREEVIEW)lParam;
- HTREEITEM hItem = nm->itemNew.hItem;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- tvItem.hItem = hItem;
- tvItem.mask = TVIF_PARAM | TVIF_HANDLE;
- if (TreeView_GetItem(hTree, &tvItem))
- {
- if(tvItem.lParam != 1)
- {
- //Start a timer to handle auto-scrolling
- dragDropTimer = SetTimer(hDlg, 1, 100, NULL);
- OrganizeBookmarksOnBeginDrag(hTree, (LPNMTREEVIEW)lParam);
- }
- }
- }
- }
- }
- break;
- case WM_MOUSEMOVE:
- {
- if(isOrganizeBookmarksDragDropActive())
- {
- HWND hTree;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- OrganizeBookmarksOnMouseMove(hTree, GET_X_LPARAM(lParam),
- GET_Y_LPARAM(lParam));
- }
- }
- }
- break;
- case WM_LBUTTONUP:
- {
- if(isOrganizeBookmarksDragDropActive())
- {
- HWND hTree;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- //Kill the auto-scroll timer
- KillTimer(hDlg, dragDropTimer);
- OrganizeBookmarksOnLButtonUp(hTree);
- MoveBookmarkInFavorites(hTree, appCore);
- }
- }
- }
- break;
- case WM_TIMER:
- {
- if(isOrganizeBookmarksDragDropActive())
- {
- if(wParam == 1)
- {
- //Handle
- HWND hTree;
- if (hTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE))
- {
- DragDropAutoScroll(hTree);
- }
- }
- }
- }
- break;
- }
- return FALSE;
- }
- int selectedScreenMode = 0;
- BOOL APIENTRY SelectDisplayModeProc(HWND hDlg,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- {
- char buf[100];
- HWND hwnd = GetDlgItem(hDlg, IDC_COMBO_RESOLUTION);
- // Add windowed mode as the first item on the menu
- bind_textdomain_codeset("celestia", CurrentCP());
- SendMessage(hwnd, CB_INSERTSTRING, -1,
- reinterpret_cast<LPARAM>(_("Windowed Mode")));
- bind_textdomain_codeset("celestia", "UTF8");
- for (vector<DEVMODE>::const_iterator iter= displayModes->begin();
- iter != displayModes->end(); iter++)
- {
- sprintf(buf, "%d x %d x %d",
- iter->dmPelsWidth, iter->dmPelsHeight,
- iter->dmBitsPerPel);
- SendMessage(hwnd, CB_INSERTSTRING, -1,
- reinterpret_cast<LPARAM>(buf));
- }
- SendMessage(hwnd, CB_SETCURSEL, currentScreenMode, 0);
- }
- return TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK)
- {
- newScreenMode = selectedScreenMode;
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, 0);
- return TRUE;
- }
- else if (LOWORD(wParam) == IDC_COMBO_RESOLUTION)
- {
- if (HIWORD(wParam) == CBN_SELCHANGE)
- {
- HWND hwnd = reinterpret_cast<HWND>(lParam);
- int item = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
- if (item != CB_ERR)
- selectedScreenMode = item;
- }
- return TRUE;
- }
- }
- return FALSE;
- }
- HMENU CreateMenuBar()
- {
- return LoadMenu(hRes, MAKEINTRESOURCE(IDR_MAIN_MENU));
- }
- static void setMenuItemCheck(int menuItem, bool checked)
- {
- CheckMenuItem(menuBar, menuItem, checked ? MF_CHECKED : MF_UNCHECKED);
- }
- struct IntStrPairComparePredicate
- {
- IntStrPairComparePredicate() : dummy(0)
- {
- }
- bool operator()(const IntStrPair pair1, const IntStrPair pair2) const
- {
- return (pair1.second.compare(pair2.second) < 0);
- }
- int dummy;
- };
- static HMENU CreatePlanetarySystemMenu(string parentName, const PlanetarySystem* psys)
- {
- // Use some vectors to categorize and sort the bodies within this PlanetarySystem.
- // In order to generate sorted menus, we must carry the name and menu index as a
- // single unit in the sort. One obvous way is to create a vector<pair<int,string>>
- // and then use a comparison predicate to sort.the vector based on the string in
- // each pair.
- // Declare vector<pair<int,string>> objects for each classification of body
- vector<IntStrPair> asteroids;
- vector<IntStrPair> comets;
- vector<IntStrPair> invisibles;
- vector<IntStrPair> moons;
- vector<IntStrPair> planets;
- vector<IntStrPair> spacecraft;
- // We will use these objects to iterate over all the above vectors
- vector<IntStrPairVec> objects;
- vector<string> menuNames;
- // Place each body in the correct vector based on classification
- HMENU menu = CreatePopupMenu();
- for (int i = 0; i < psys->getSystemSize(); i++)
- {
- Body* body = psys->getBody(i);
- if (!body->getName().empty())
- {
- switch(body->getClassification())
- {
- case Body::Asteroid:
- asteroids.push_back(make_pair(i, UTF8ToCurrentCP(body->getName(true))));
- break;
- case Body::Comet:
- comets.push_back(make_pair(i, UTF8ToCurrentCP(body->getName(true))));
- break;
- case Body::Invisible:
- invisibles.push_back(make_pair(i, UTF8ToCurrentCP(body->getName(true))));
- break;
- case Body::Moon:
- moons.push_back(make_pair(i, UTF8ToCurrentCP(body->getName(true))));
- break;
- case Body::Planet:
- planets.push_back(make_pair(i, UTF8ToCurrentCP(body->getName(true))));
- break;
- case Body::Spacecraft:
- spacecraft.push_back(make_pair(i, UTF8ToCurrentCP(body->getName(true))));
- break;
- }
- }
- }
- // Add each vector of PlanetarySystem bodies to a vector to iterate over
- objects.push_back(asteroids);
- menuNames.push_back(UTF8ToCurrentCP(_("Asteroids")));
- objects.push_back(comets);
- menuNames.push_back(UTF8ToCurrentCP(_("Comets")));
- objects.push_back(invisibles);
- menuNames.push_back(UTF8ToCurrentCP(_("Invisibles")));
- objects.push_back(moons);
- menuNames.push_back(UTF8ToCurrentCP(_("Moons")));
- objects.push_back(planets);
- menuNames.push_back(UTF8ToCurrentCP(_("Planets")));
- objects.push_back(spacecraft);
- menuNames.push_back(UTF8ToCurrentCP(_("Spacecraft")));
- // Now sort each vector and generate submenus
- IntStrPairComparePredicate pred;
- vector<IntStrPairVec>::iterator obj;
- vector<IntStrPair>::iterator it;
- vector<string>::iterator menuName;
- HMENU hSubMenu;
- int numSubMenus;
- // Count how many submenus we need to create
- numSubMenus = 0;
- for (obj=objects.begin(); obj != objects.end(); obj++)
- {
- if (obj->size() > 0)
- numSubMenus++;
- }
- menuName = menuNames.begin();
- for (obj=objects.begin(); obj != objects.end(); obj++)
- {
- // Only generate a submenu if the vector is not empty
- if (obj->size() > 0)
- {
- // Don't create a submenu for a single item
- if (obj->size() == 1)
- {
- it=obj->begin();
- AppendMenu(menu, MF_STRING, MENU_CHOOSE_PLANET + it->first, it->second.c_str());
- }
- else
- {
- // Skip sorting if we are dealing with the planets in our own Solar System.
- if (parentName != "Sol" || *menuName != UTF8ToCurrentCP(_("Planets")))
- sort(obj->begin(), obj->end(), pred);
- if (numSubMenus > 1)
- {
- // Add items to submenu
- hSubMenu = CreatePopupMenu();
- for(it=obj->begin(); it != obj->end(); it++)
- AppendMenu(hSubMenu, MF_STRING, MENU_CHOOSE_PLANET + it->first, it->second.c_str());
- AppendMenu(menu, MF_POPUP | MF_STRING, (DWORD)hSubMenu, menuName->c_str());
- }
- else
- {
- // Just add items to the popup
- for(it=obj->begin(); it != obj->end(); it++)
- AppendMenu(menu, MF_STRING, MENU_CHOOSE_PLANET + it->first, it->second.c_str());
- }
- }
- }
- menuName++;
- }
- return menu;
- }
- static HMENU CreateAlternateSurfaceMenu(const vector<string>& surfaces)
- {
- HMENU menu = CreatePopupMenu();
- AppendMenu(menu, MF_STRING, MENU_CHOOSE_SURFACE, "Normal");
- for (unsigned int i = 0; i < surfaces.size(); i++)
- {
- AppendMenu(menu, MF_STRING, MENU_CHOOSE_SURFACE + i + 1,
- surfaces[i].c_str());
- }
- return menu;
- }
- VOID APIENTRY handlePopupMenu(HWND hwnd,
- float x, float y,
- const Selection& sel)
- {
- HMENU hMenu;
- string name;
- hMenu = CreatePopupMenu();
- switch (sel.getType())
- {
- case Selection::Type_Body:
- {
- name = sel.body()->getName(true);
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_CENTER, UTF8ToCurrentCP(name).c_str());
- AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_GOTO, UTF8ToCurrentCP(_("&Goto")).c_str());
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_FOLLOW, UTF8ToCurrentCP(_("&Follow")).c_str());
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_SYNCORBIT, UTF8ToCurrentCP(_("S&ync Orbit")).c_str());
- AppendMenu(hMenu, MF_STRING, ID_INFO, UTF8ToCurrentCP(_("&Info")).c_str());
- HMENU refVectorMenu = CreatePopupMenu();
- AppendMenu(hMenu, MF_POPUP | MF_STRING, (DWORD) refVectorMenu, UTF8ToCurrentCP(_("&Reference Vectors")).c_str());
- AppendMenu(refVectorMenu, MF_STRING, ID_RENDER_BODY_AXES, UTF8ToCurrentCP(_("Show Body Axes")).c_str());
- AppendMenu(refVectorMenu, MF_STRING, ID_RENDER_FRAME_AXES, UTF8ToCurrentCP(_("Show Frame Axes")).c_str());
- AppendMenu(refVectorMenu, MF_STRING, ID_RENDER_SUN_DIRECTION, UTF8ToCurrentCP(_("Show Sun Direction")).c_str());
- AppendMenu(refVectorMenu, MF_STRING, ID_RENDER_VELOCITY_VECTOR, UTF8ToCurrentCP(_("Show Velocity Vector")).c_str());
- AppendMenu(refVectorMenu, MF_STRING, ID_RENDER_PLANETOGRAPHIC_GRID, UTF8ToCurrentCP(_("Show Planetographic Grid")).c_str());
- AppendMenu(refVectorMenu, MF_STRING, ID_RENDER_TERMINATOR, UTF8ToCurrentCP(_("Show Terminator")).c_str());
- CheckMenuItem(refVectorMenu, ID_RENDER_BODY_AXES, sel.body()->findReferenceMark("body axes") ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(refVectorMenu, ID_RENDER_FRAME_AXES, sel.body()->findReferenceMark("frame axes") ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(refVectorMenu, ID_RENDER_SUN_DIRECTION, sel.body()->findReferenceMark("sun direction") ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(refVectorMenu, ID_RENDER_VELOCITY_VECTOR, sel.body()->findReferenceMark("velocity vector") ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(refVectorMenu, ID_RENDER_PLANETOGRAPHIC_GRID, sel.body()->findReferenceMark("planetographic grid") ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(refVectorMenu, ID_RENDER_TERMINATOR, sel.body()->findReferenceMark("terminator") ? MF_CHECKED : MF_UNCHECKED);
- const PlanetarySystem* satellites = sel.body()->getSatellites();
- if (satellites != NULL && satellites->getSystemSize() != 0)
- {
- HMENU satMenu = CreatePlanetarySystemMenu(name, satellites);
- AppendMenu(hMenu, MF_POPUP | MF_STRING, (DWORD) satMenu,
- UTF8ToCurrentCP(_("&Satellites")).c_str());
- }
- vector<string>* altSurfaces = sel.body()->getAlternateSurfaceNames();
- if (altSurfaces != NULL)
- {
- if (altSurfaces->size() != NULL)
- {
- HMENU surfMenu = CreateAlternateSurfaceMenu(*altSurfaces);
- AppendMenu(hMenu, MF_POPUP | MF_STRING, (DWORD) surfMenu,
- UTF8ToCurrentCP(_("&Alternate Surfaces")).c_str());
- }
- delete altSurfaces;
- }
- }
- break;
- case Selection::Type_Star:
- {
- Simulation* sim = appCore->getSimulation();
- name = sim->getUniverse()->getStarCatalog()->getStarName(*(sel.star()));
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_CENTER, UTF8ToCurrentCP(name).c_str());
- AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_GOTO, UTF8ToCurrentCP(_("&Goto")).c_str());
- AppendMenu(hMenu, MF_STRING, ID_INFO, UTF8ToCurrentCP(_("&Info")).c_str());
- SolarSystemCatalog* solarSystemCatalog = sim->getUniverse()->getSolarSystemCatalog();
- SolarSystemCatalog::iterator iter = solarSystemCatalog->find(sel.star()->getCatalogNumber());
- if (iter != solarSystemCatalog->end())
- {
- SolarSystem* solarSys = iter->second;
- HMENU planetsMenu = CreatePlanetarySystemMenu(name, solarSys->getPlanets());
- if (name == "Sol")
- AppendMenu(hMenu, MF_POPUP | MF_STRING, (DWORD) planetsMenu, UTF8ToCurrentCP(_("Orbiting Bodies")).c_str());
- else
- AppendMenu(hMenu, MF_POPUP | MF_STRING, (DWORD) planetsMenu, UTF8ToCurrentCP(_("Planets")).c_str());
- }
- }
- break;
- case Selection::Type_DeepSky:
- {
- Simulation* sim = appCore->getSimulation();
- name = sim->getUniverse()->getDSOCatalog()->getDSOName(sel.deepsky());
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_CENTER, UTF8ToCurrentCP(name).c_str());
- AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_GOTO, UTF8ToCurrentCP(_("&Goto")).c_str());
- AppendMenu(hMenu, MF_STRING, ID_NAVIGATION_FOLLOW, UTF8ToCurrentCP(_("&Follow")).c_str());
- AppendMenu(hMenu, MF_STRING, ID_INFO, UTF8ToCurrentCP(_("&Info")).c_str());
- }
- break;
- case Selection::Type_Location:
- break;
- default:
- break;
- }
- if (appCore->getSimulation()->getUniverse()->isMarked(sel, 1))
- AppendMenu(hMenu, MF_STRING, ID_TOOLS_UNMARK, UTF8ToCurrentCP(_("&Unmark")).c_str());
- else
- AppendMenu(hMenu, MF_STRING, ID_TOOLS_MARK, UTF8ToCurrentCP(_("&Mark")).c_str());
- POINT point;
- point.x = (int) x;
- point.y = (int) y;
- if (currentScreenMode == 0)
- ClientToScreen(hwnd, (LPPOINT) &point);
- appCore->getSimulation()->setSelection(sel);
- TrackPopupMenu(hMenu, 0, point.x, point.y, 0, hwnd, NULL);
- // TODO: Do we need to explicitly destroy submenus or does DestroyMenu
- // work recursively?
- // According to the MSDN documentation, DestroyMenu() IS recursive. Clint 11/01.
- DestroyMenu(hMenu);
- #ifdef INFINITE_MOUSE
- ignoreNextMoveEvent = true;
- #endif // INFINITE_MOUSE
- }
- // TODO: get rid of fixed urls
- void ShowWWWInfo(const Selection& sel)
- {
- string url;
- switch (sel.getType())
- {
- case Selection::Type_Body:
- {
- url = sel.body()->getInfoURL();
- if (url.empty())
- {
- string name = sel.body()->getName();
- for (unsigned int i = 0; i < name.size(); i++)
- name[i] = tolower(name[i]);
- url = string("http://www.nineplanets.org/") + name + ".html";
- }
- }
- break;
- case Selection::Type_Star:
- {
- url = sel.star()->getInfoURL();
- if (url.empty())
- {
- char name[32];
- sprintf(name, "HIP%d", sel.star()->getCatalogNumber() & ~0xf0000000);
- url = string("http://simbad.u-strasbg.fr/sim-id.pl?protocol=html&Ident=") + name;
- }
- }
- break;
- case Selection::Type_DeepSky:
- url = sel.deepsky()->getInfoURL();
- break;
- case Selection::Type_Location:
- break;
- default:
- break;
- }
- ShellExecute(mainWindow,
- "open",
- url.c_str(),
- NULL,
- NULL,
- 0);
- }
- void ContextMenu(float x, float y, Selection sel)
- {
- handlePopupMenu(mainWindow, x, y, sel);
- }
- bool EnableFullScreen(const DEVMODE& dm)
- {
- DEVMODE devMode;
- ZeroMemory(&devMode, sizeof devMode);
- devMode.dmSize = sizeof devMode;
- devMode.dmPelsWidth = dm.dmPelsWidth;
- devMode.dmPelsHeight = dm.dmPelsHeight;
- devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) !=
- DISP_CHANGE_SUCCESSFUL)
- {
- MessageBox(NULL,
- "Unable to switch to full screen mode; running in window mode",
- "Error",
- MB_OK | MB_ICONERROR);
- return false;
- }
- return true;
- }
- void DisableFullScreen()
- {
- ChangeDisplaySettings(0, 0);
- }
- unsigned int
- ChooseBestMSAAPixelFormat(HDC hdc, int *formats, unsigned int numFormats,
- int samplesRequested)
- {
- int idealFormat = 0;
- int bestFormat = 0;
- int bestSamples = 0;
- for (unsigned int i = 0; i < numFormats; i++)
- {
- int query = WGL_SAMPLES_ARB;
- int result = 0;
- bool isFloatFormat = false;
- query = WGL_SAMPLES_ARB;
- wglGetPixelFormatAttribivARB(hdc, formats[i], 0, 1, &query, &result);
- if (result <= samplesRequested && result >= bestSamples)
- {
- bestSamples = result;
- bestFormat = formats[i];
- }
- if (result == samplesRequested)
- idealFormat = formats[i];
- }
- if (idealFormat != 0)
- return idealFormat;
- return bestFormat;
- }
- // Select the pixel format for a given device context
- bool SetDCPixelFormat(HDC hDC)
- {
- bool msaa = false;
- if (appCore->getConfig()->aaSamples > 1 &&
- WGLExtensionSupported("WGL_ARB_pixel_format") &&
- WGLExtensionSupported("WGL_ARB_multisample"))
- {
- msaa = true;
- }
-
- if (!msaa)
- {
- static PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
- 1, // Version of this structure
- PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)
- PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
- PFD_DOUBLEBUFFER, // Double buffered mode
- PFD_TYPE_RGBA, // RGBA Color mode
- GetDeviceCaps(hDC, BITSPIXEL),// Want the display bit depth
- 0,0,0,0,0,0, // Not used to select mode
- 0,0, // Not used to select mode
- 0,0,0,0,0, // Not used to select mode
- 24, // Size of depth buffer
- 0, // Not used to select mode
- 0, // Not used to select mode
- PFD_MAIN_PLANE, // Draw in main plane
- 0, // Not used to select mode
- 0,0,0 // Not used to select mode
- };
- // Choose a pixel format that best matches that described in pfd
- int nPixelFormat = ChoosePixelFormat(hDC, &pfd);
- if (nPixelFormat == 0)
- {
- // Uh oh . . . looks like we can't handle OpenGL on this device.
- return false;
- }
- else
- {
- // Set the pixel format for the device context
- SetPixelFormat(hDC, nPixelFormat, &pfd);
- return true;
- }
- }
- else
- {
- PIXELFORMATDESCRIPTOR pfd;
- int ifmtList[] = {
- WGL_DRAW_TO_WINDOW_ARB, TRUE,
- WGL_SUPPORT_OPENGL_ARB, TRUE,
- WGL_DOUBLE_BUFFER_ARB, TRUE,
- WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
- WGL_DEPTH_BITS_ARB, 24,
- WGL_COLOR_BITS_ARB, 24,
- WGL_RED_BITS_ARB, 8,
- WGL_GREEN_BITS_ARB, 8,
- WGL_BLUE_BITS_ARB, 8,
- WGL_ALPHA_BITS_ARB, 0,
- WGL_ACCUM_BITS_ARB, 0,
- WGL_STENCIL_BITS_ARB, 0,
- WGL_SAMPLE_BUFFERS_ARB, appCore->getConfig()->aaSamples > 1,
- 0
- };
- int pixelFormatIndex;
- int pixFormats[256];
- unsigned int numFormats;
- wglChoosePixelFormatARB(hDC, ifmtList, NULL, 256, pixFormats, &numFormats);
- pixelFormatIndex = ChooseBestMSAAPixelFormat(hDC, pixFormats,
- numFormats,
- appCore->getConfig()->aaSamples);
- DescribePixelFormat(hDC, pixelFormatIndex,
- sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if (!SetPixelFormat(hDC, pixelFormatIndex, &pfd))
- return false;
- return true;
- }
- }
- HWND CreateOpenGLWindow(int x, int y, int width, int height,
- int mode, int& newMode)
- {
- assert(mode >= 0 && mode <= displayModes->size());
- if (mode != 0)
- {
- x = 0;
- y = 0;
- width = displayModes->at(mode - 1).dmPelsWidth;
- height = displayModes->at(mode - 1).dmPelsHeight;
- }
- // Set up and register the window class
- WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wc.lpfnWndProc = (WNDPROC) MainWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = appInstance;
- wc.hIcon = LoadIcon(hRes, MAKEINTRESOURCE(IDI_CELESTIA_ICON));
- wc.hCursor = hDefaultCursor;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = AppName;
- if (RegisterClass(&wc) == 0)
- {
- MessageBox(NULL,
- "Failed to register the window class.", "Fatal Error",
- MB_OK | MB_ICONERROR);
- return NULL;
- }
- newMode = currentScreenMode;
- if (mode != 0)
- {
- if (EnableFullScreen(displayModes->at(mode - 1)))
- newMode = mode;
- }
- else
- {
- DisableFullScreen();
- newMode = 0;
- }
- // Determine the proper window style to use
- DWORD dwStyle;
- if (newMode != 0)
- {
- dwStyle = WS_POPUP;
- }
- else
- {
- dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
- }
- // Create the window
- HWND hwnd = CreateWindow(AppName,
- AppName,
- dwStyle,
- x, y,
- width, height,
- NULL,
- NULL,
- appInstance,
- NULL);
- if (hwnd == NULL)
- return NULL;
- ShowWindow(hwnd, SW_SHOW);
- SetForegroundWindow(hwnd);
- SetFocus(hwnd);
- deviceContext = GetDC(hwnd);
- if (!SetDCPixelFormat(deviceContext))
- {
- MessageBox(NULL,
- "Could not get appropriate pixel format for OpenGL rendering.", "Fatal Error",
- MB_OK | MB_ICONERROR);
- return NULL;
- }
- if (glContext == NULL)
- glContext = wglCreateContext(deviceContext);
- wglMakeCurrent(deviceContext, glContext);
- if (newMode == 0)
- SetMenu(hwnd, menuBar);
- else
- hideMenuBar = true;
- return hwnd;
- }
- void DestroyOpenGLWindow()
- {
- #if 0
- if (glContext != NULL)
- {
- wglMakeCurrent(NULL, NULL);
- if (!wglDeleteContext(glContext))
- {
- MessageBox(NULL,
- "Releasing GL context failed.", "Error",
- MB_OK | MB_ICONERROR);
- }
- glContext = NULL;
- }
- #endif
- if (deviceContext != NULL)
- {
- if (!ReleaseDC(mainWindow, deviceContext))
- {
- MessageBox(NULL,
- "Releasing device context failed.", "Error",
- MB_OK | MB_ICONERROR);
- }
- deviceContext = NULL;
- }
- if (mainWindow != NULL)
- {
- SetMenu(mainWindow, NULL);
- DestroyWindow(mainWindow);
- mainWindow = NULL;
- }
- UnregisterClass(AppName, appInstance);
- }
- void handleKey(WPARAM key, bool down)
- {
- int k = -1;
- int modifiers = 0;
- if (GetKeyState(VK_SHIFT) & 0x8000)
- modifiers |= CelestiaCore::ShiftKey;
- if (GetKeyState(VK_CONTROL) & 0x8000)
- modifiers |= CelestiaCore::ControlKey;
- switch (key)
- {
- case VK_UP:
- k = CelestiaCore::Key_Up;
- break;
- case VK_DOWN:
- k = CelestiaCore::Key_Down;
- break;
- case VK_LEFT:
- k = CelestiaCore::Key_Left;
- break;
- case VK_RIGHT:
- k = CelestiaCore::Key_Right;
- break;
- case VK_HOME:
- k = CelestiaCore::Key_Home;
- break;
- case VK_END:
- k = CelestiaCore::Key_End;
- break;
- case VK_PRIOR:
- k = CelestiaCore::Key_PageUp;
- break;
- case VK_NEXT:
- k = CelestiaCore::Key_PageDown;
- break;
- case VK_F1:
- k = CelestiaCore::Key_F1;
- break;
- case VK_F2:
- k = CelestiaCore::Key_F2;
- break;
- case VK_F3:
- k = CelestiaCore::Key_F3;
- break;
- case VK_F4:
- k = CelestiaCore::Key_F4;
- break;
- case VK_F5:
- k = CelestiaCore::Key_F5;
- break;
- case VK_F6:
- k = CelestiaCore::Key_F6;
- break;
- case VK_F7:
- k = CelestiaCore::Key_F7;
- break;
- case VK_F8:
- if (joystickAvailable && down)
- {
- appCore->joystickAxis(CelestiaCore::Joy_XAxis, 0);
- appCore->joystickAxis(CelestiaCore::Joy_YAxis, 0);
- appCore->joystickAxis(CelestiaCore::Joy_ZAxis, 0);
- useJoystick = !useJoystick;
- }
- break;
- case VK_F11:
- k = CelestiaCore::Key_F11;
- break;
- case VK_F12:
- k = CelestiaCore::Key_F12;
- break;
- case VK_NUMPAD2:
- k = CelestiaCore::Key_NumPad2;
- break;
- case VK_NUMPAD4:
- k = CelestiaCore::Key_NumPad4;
- break;
- case VK_NUMPAD5:
- k = CelestiaCore::Key_NumPad5;
- break;
- case VK_NUMPAD6:
- k = CelestiaCore::Key_NumPad6;
- break;
- case VK_NUMPAD7:
- k = CelestiaCore::Key_NumPad7;
- break;
- case VK_NUMPAD8:
- k = CelestiaCore::Key_NumPad8;
- break;
- case VK_NUMPAD9:
- k = CelestiaCore::Key_NumPad9;
- break;
- case VK_DELETE:
- if (!down)
- appCore->charEntered('177');
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- // Special handling required to send Ctrl+number keys to
- // Celestia keyboard handler.
- if (!down && (modifiers & CelestiaCore::ControlKey))
- appCore->charEntered((char) key, modifiers);
- break;
- case 'A':
- case 'Z':
- if ((GetKeyState(VK_CONTROL) & 0x8000) == 0)
- k = key;
- break;
- }
- if (k >= 0)
- {
- if (down)
- appCore->keyDown(k, modifiers);
- else
- appCore->keyUp(k, modifiers);
- }
- }
- static void BuildScriptsMenu(HMENU menuBar, const string& scriptsDir)
- {
- HMENU fileMenu = GetSubMenu(menuBar, 0);
- if (ScriptMenuItems != NULL)
- delete ScriptMenuItems;
- ScriptMenuItems = ScanScriptsDirectory(scriptsDir, false);
- if (ScriptMenuItems == NULL || ScriptMenuItems->size() == 0)
- {
- EnableMenuItem(fileMenu, ID_FILE_SCRIPTS, MF_GRAYED);
- return;
- }