// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // client_configDlg.cpp : implementation file // #include "stdafx.h" #include "client_config.h" #include "client_configDlg.h" #include "cfg_file.h" #include "database.h" #include <nel/misc/debug.h> #include <nel/misc/system_utils.h> #define ICON_ZONE_WIDTH 128 #define LEFT_WIDTH 256 #define LEFT_HEIGHT 512 #define BAR_START_X (LEFT_WIDTH+ICON_ZONE_WIDTH) #define BAR_WIDTH 448 #define BAR_HEIGHT 72 #define TREE_ZONE_WIDTH 150 #define TREE_OFFSET_LEFT 10 #define TREE_OFFSET_TOP 10 // Label #define LARGE_LABEL_HEIGHT -22 #define LARGE_LABEL_START_X (LEFT_WIDTH+TREE_ZONE_WIDTH) #define LARGE_LABEL_START_Y (15) #define LARGE_LABEL_END_X (LEFT_WIDTH+ICON_ZONE_WIDTH+BAR_WIDTH) #define LARGE_LABEL_END_Y BAR_HEIGHT // Icon #define ICON_WIDTH 64 #define ICON_HEIGHT 64 #define ICON_START_Y ((BAR_HEIGHT-ICON_HEIGHT)/2) #define ICON_START_X (LEFT_WIDTH+ICON_START_Y) #define ICON_START_Y ((BAR_HEIGHT-ICON_HEIGHT)/2) // *************************************************************************** // CAboutDlg dialog used for App About // *************************************************************************** class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; // *************************************************************************** CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } // *************************************************************************** void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } // *************************************************************************** BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) //}}AFX_MSG_MAP END_MESSAGE_MAP() // *************************************************************************** // CClient_configDlg dialog // *************************************************************************** CClient_configDlg::CClient_configDlg(CWnd* pParent /*=NULL*/) : CDialog(CClient_configDlg::IDD, pParent) { //{{AFX_DATA_INIT(CClient_configDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // Init dialog pointers Dialogs[PageGeneral] = &GeneralDlg; Dialogs[PageDisplay] = &DisplayDlg; Dialogs[PageDisplayDetails] = &DisplayDetailsDlg; Dialogs[PageDisplayAdvanced] = &DisplayAdvancedDlg; Dialogs[PageDisplaySysInfo] = &SystemInformationDlg; Dialogs[PageDisplayOpenGLInfo] = &DisplayInformationGLDlg; Dialogs[PageDisplayOpenD3DInfo] = &DisplayInformationD3DDlg; Dialogs[PageSound] = &SoundDlg; _CurrentPage = 0; } // *************************************************************************** void CClient_configDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CClient_configDlg) DDX_Control(pDX, ID_APPLY, ApplyCtrl); //}}AFX_DATA_MAP } // *************************************************************************** BEGIN_MESSAGE_MAP(CClient_configDlg, CDialog) //{{AFX_MSG_MAP(CClient_configDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(ID_APPLY, OnApply) ON_BN_CLICKED(ID_DEFAULT, OnDefault) ON_BN_CLICKED(ID_LAUNCH, OnLaunch) //}}AFX_MSG_MAP END_MESSAGE_MAP() // *************************************************************************** // CClient_configDlg message handlers // *************************************************************************** BOOL CClient_configDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu = "uiConfigMenuAbout"; if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // Create bitmaps uint i; for (i=0; i<BitmapCount; i++) { Bitmaps[i].LoadBitmap (BitmapId[i].ResId); } // Create others controls nlverify (Left.Create (NULL, WS_CHILD|WS_VISIBLE|SS_BITMAP, CRect (0, 0, LEFT_WIDTH, LEFT_HEIGHT), this)); Left.SetBitmap (LoadBitmap (theApp.m_hInstance, MAKEINTRESOURCE (IDB_LEFT_0))); nlverify (Icon.Create (NULL, WS_CHILD|WS_VISIBLE|SS_BITMAP, CRect (ICON_START_X, ICON_START_Y, ICON_START_X+ICON_WIDTH, ICON_START_Y+ICON_HEIGHT), this)); Icon.SetBitmap (Bitmaps[BitmapWelcome]); // Create bars nlverify (Top.Create (CRect (LEFT_WIDTH, BAR_HEIGHT, LEFT_WIDTH+ICON_ZONE_WIDTH+BAR_WIDTH, BAR_HEIGHT+1), this)); nlverify (Bottom.Create (CRect (0, LEFT_HEIGHT, LEFT_WIDTH+ICON_ZONE_WIDTH+BAR_WIDTH, LEFT_HEIGHT+1), this)); // Create the tree nlverify (Tree.Create ( WS_CHILD|WS_VISIBLE|TVS_NOSCROLL|TVS_TRACKSELECT|TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS, CRect (LEFT_WIDTH+TREE_OFFSET_LEFT, BAR_HEIGHT+2+TREE_OFFSET_TOP, LEFT_WIDTH+TREE_ZONE_WIDTH, BAR_HEIGHT+LEFT_HEIGHT-BAR_HEIGHT), this, TreeId)); Tree.SetFont (GetFont ()); // Create fonts nlverify (BarFont.CreateFont (LARGE_LABEL_HEIGHT, 0, 0, 0, FW_BOLD, TRUE, FALSE, 0, DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, TMPF_TRUETYPE | DEFAULT_PITCH | FF_MODERN, "Arial")); // Create dialog for (i=0; i<PageCount; i++) { nlverify (Dialogs[i]->Create (Pages[i].ResId, this)); nlverify (Dialogs[i]->SetWindowPos (NULL, LEFT_WIDTH+TREE_ZONE_WIDTH, BAR_HEIGHT+2, 0, 0, SWP_NOZORDER|SWP_NOSIZE)); } // Build the tree CPage *page = Root.Children[0]; HTREEITEM parent = TVI_ROOT; while (page) { // Add an item parent = Tree.InsertItem ("", parent); Tree.SetItemData (parent, page->PageId); if (page->Bold) Tree.SetItemState (parent, TVIS_BOLD, TVIS_BOLD); // Next if (page->Children.size ()) page = page->Children[0]; else { // Got a parent ? while (page->Parent) { // Brother ? if (page->ChildId < page->Parent->Children.size ()-1) { page = page->Parent->Children[page->ChildId+1]; parent = Tree.GetParentItem (parent); break; } else { page = page->Parent; parent = Tree.GetParentItem (parent); Tree.Expand (parent, TVE_EXPAND); } } if (!page->Parent) break; } } ApplyCtrl.EnableWindow (FALSE); // Get from the config file GetFromConfigFile (); theApp.Modified = false; // Build the localisation map backupWindowHandleRec (); // Localize the windows changeLanguage (::GetIntForceLanguage()?"en" : ::GetString ("LanguageCode").c_str()); theApp.Localized = true; // Focus Tree.SelectItem(Tree.GetChildItem (Tree.GetRootItem())); Tree.SetFocus (); return TRUE; // return TRUE unless you set the focus to a control } // *************************************************************************** void CClient_configDlg::changeLanguage (const char *language) { // Init CI18N NLMISC::CI18N::load(language); localizeWindowsRec (); translateTree (); // Set the general page setPage (_CurrentPage); DisplayDlg.updateState (); DisplayDlg.UpdateData (FALSE); DisplayDetailsDlg.updateState (); SoundDlg.updateState (); // Set the title setWindowText(*this, (WCHAR*)((NLMISC::CI18N::get ("uiConfigTitle") + (theApp.Modified?" *":"")).c_str())); // The menu CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu) { if (NLMISC::CSystemUtils::supportUnicode()) { nlverify (::ModifyMenuW(*pSysMenu, IDM_ABOUTBOX, MF_BYCOMMAND|MF_STRING, IDM_ABOUTBOX, (WCHAR*)NLMISC::CI18N::get ("uiConfigMenuAbout").c_str())); } else { nlverify (::ModifyMenu(*pSysMenu, IDM_ABOUTBOX, MF_BYCOMMAND|MF_STRING, IDM_ABOUTBOX, (LPCTSTR)NLMISC::CI18N::get ("uiConfigMenuAbout").toString().c_str())); } } } // *************************************************************************** void CClient_configDlg::translateTree () { // Set the item text HTREEITEM item = Tree.GetRootItem (); while (item) { // Set the item text uint page = (uint)Tree.GetItemData (item); ucstring name = NLMISC::CI18N::get (Pages[page].Name); if (NLMISC::CSystemUtils::supportUnicode()) { TVITEMEXW itemDesc; memset (&itemDesc, 0, sizeof(TVITEMEXW)); itemDesc.hItem = item; itemDesc.mask = TVIF_TEXT; itemDesc.pszText = (WCHAR*)name.c_str(); nlverify (SendMessageW (Tree, TVM_SETITEMW, 0, (LPARAM)&itemDesc)); } else { TVITEMEXA itemDesc; memset (&itemDesc, 0, sizeof(TVITEMEXA)); itemDesc.hItem = item; itemDesc.mask = TVIF_TEXT; std::string tmpStr = name.toString(); itemDesc.pszText = (LPSTR) tmpStr.c_str(); nlverify (::SendMessageA(Tree, TVM_SETITEMA, 0 , (LPARAM)&itemDesc)); } // Next item HTREEITEM old = item; item = Tree.GetChildItem (item); if (!item) { // No more child, try a brother item = Tree.GetNextSiblingItem (old); } if (!item) { // No more brother, try an oncle item = Tree.GetParentItem (old); if (item) item = Tree.GetNextSiblingItem (item); } } } // *************************************************************************** void CClient_configDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // *************************************************************************** // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CClient_configDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { // Draw rect CPaintDC dc(this); // device context for painting dc.FillSolidRect( LEFT_WIDTH, BAR_HEIGHT+2, TREE_ZONE_WIDTH, LEFT_HEIGHT-BAR_HEIGHT-2, GetSysColor (COLOR_WINDOW)); // Draw top bar dc.FillSolidRect( LEFT_WIDTH, 0, ICON_ZONE_WIDTH, BAR_HEIGHT, RGB (255,255,255)); CDC bitmapDC; bitmapDC.CreateCompatibleDC (&dc); bitmapDC.SelectObject (&Bitmaps[BitmapTopRight]); nlverify (dc.BitBlt( LEFT_WIDTH + ICON_ZONE_WIDTH, 0, BAR_WIDTH, BAR_HEIGHT, &bitmapDC, 0, 0, SRCCOPY)); // Draw some text dc.SetBkMode (TRANSPARENT); dc.SelectObject (&BarFont); CRect labelRect (LARGE_LABEL_START_X, LARGE_LABEL_START_Y, LARGE_LABEL_END_X, LARGE_LABEL_END_Y); DrawTextW (&(*dc), (WCHAR*)TopLargeLabel.c_str (), (sint)TopLargeLabel.size (), &labelRect, DT_LEFT|DT_TOP); CDialog::OnPaint(); } } // *************************************************************************** HCURSOR CClient_configDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } // *************************************************************************** void CClient_configDlg::setPage (uint pageId) { CPage &page = Pages[pageId]; Icon.SetBitmap (Bitmaps[page.Icon]); TopLargeLabel = NLMISC::CI18N::get (std::string(page.Name)); // Hide all the dialog uint i; for (i=0; i<PageCount; i++) Dialogs[i]->ShowWindow (SW_HIDE); // Show the dialog Dialogs[pageId]->ShowWindow (SW_SHOW); // Invalidate bar InvalidateBar (); _CurrentPage = pageId; } // *************************************************************************** BOOL CClient_configDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { // TODO: Add your specialized code here and/or call the base class int idCtrl = (int) wParam; LPNMHDR pnmh = (LPNMHDR) lParam; switch (idCtrl) { case TreeId: { switch (pnmh->code) { case TVN_SELCHANGED: { // Get the selection HTREEITEM item = Tree.GetSelectedItem (); if (item) { // Get the page uint pageId = (uint)Tree.GetItemData (item); setPage (pageId); } } break; } } break; } return CDialog::OnNotify(wParam, lParam, pResult); } // *************************************************************************** void CClient_configDlg::InvalidateBar () { CRect rect (BAR_START_X, 0, BAR_START_X+BAR_WIDTH, BAR_HEIGHT); InvalidateRect (&rect); } // *************************************************************************** BOOL CClient_configDlg::UpdateData ( BOOL bSaveAndValidate ) { // For each pages uint i; for (i=0; i<PageCount; i++) { Dialogs[i]->UpdateData (bSaveAndValidate); } return CDialog::UpdateData ( bSaveAndValidate ); } // *************************************************************************** void CClient_configDlg::OnApply() { // Update config file SetToConfigFile (); // Save the config file SaveConfigFile (); // Doc is validated theApp.Modified = false; ApplyCtrl.EnableWindow (FALSE); // Set the title setWindowText(*this, (WCHAR*)NLMISC::CI18N::get ("uiConfigTitle").c_str()); } // *************************************************************************** void CClient_configDlg::OnCancel() { // Modified ? if (theApp.Modified) { // Quit without saving ? if (theApp.yesNo (NLMISC::CI18N::get ("uiConfigQuitWithoutSaving"))) { CDialog::OnCancel(); } } else CDialog::OnCancel(); } // *************************************************************************** void CClient_configDlg::OnOK() { if (theApp.Modified) { // Update config file SetToConfigFile (); // Save the config file SaveConfigFile (); // Doc is validated theApp.Modified = false; } CDialog::OnOK(); } // *************************************************************************** void CClient_configDlg::OnDefault() { /* Yoyo: Don't use the preset dlg for now cause doesn't work everywhere // Open the preset dialog CPresetDlg preset; if (preset.DoModal () == IDOK) { // Reset the CFG to default ResetConfigFile(); // invalidate InvalidateConfig (); // Update widgets GetFromConfigFile (); } */ // Quit without saving ? if (theApp.yesNo (NLMISC::CI18N::get ("uiConfigRestaureDefault"))) { // Reset the CFG to default ResetConfigFileToDefault(); // invalidate InvalidateConfig (); // Update widgets GetFromConfigFile (); } } // *************************************************************************** void CClient_configDlg::OnLaunch() { if (theApp.Modified) { // Update config file SetToConfigFile (); // Save the config file SaveConfigFile (); // Doc is validated theApp.Modified = false; } // launch ryzom NLMISC::launchProgram("client_ryzom_rd.exe",""); CDialog::OnOK(); } // *************************************************************************** BOOL CAboutDlg::OnInitDialog() { CDialog::OnInitDialog(); localizeWindowsRec (this, false); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }