khanat-opennel-code/code/ryzom/tools/client/client_config/client_configDlg.cpp
2010-11-02 13:42:25 +01:00

628 lines
17 KiB
C++

// 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
}