This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/editor/guiforms.c

1051 lines
27 KiB
C

//=======================================================================
// Copyright XashXT Group 2007 ©
// editor.c - game editor dll
//=======================================================================
#include "editor.h"
#define IDI_ICON1 101
#define MAIN_WND_WIDTH 640
#define MAIN_WND_HEIGHT 480
#define OPTS_WND_WIDTH 420
#define OPTS_WND_HEIGHT 380
#define C_PAGES 3
#define EDITOR_CONSOLE "Xash Editor Console"
#define EDITOR_SETTINGS "Xash Editor Settings"
static MSG msg;
static window_t g_MainWindow;
static window_t g_IdleWindow;
HINSTANCE platform_dll;
typedef struct tag_dlghdr
{
HWND hwndTab; // tab control
HWND hwndDisplay; // current child dialog box
RECT rcDisplay; // display rectangle for the tab control
DLGTEMPLATE *apRes[C_PAGES];
}DLGHDR;
GUI_Form s_gui;
wnd_options_t w_opts; //window options
platform_exp_t *pi;//platform utils
static bool editor_init = false;
static char textbuffer[MAX_INPUTLINE];
/*
=============================================================================
GUI Set Font
=============================================================================
*/
void GUI_AddToolTip( HWND hwnd, const char *text )
{
TOOLINFO ti;
memset (&ti, 0, sizeof (TOOLINFO));
ti.cbSize = sizeof (TOOLINFO);
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
ti.uId = (UINT)hwnd;
ti.lpszText = (LPTSTR) text;
SendMessage (s_gui.hTips, TTM_ADDTOOL, 0, (LPARAM) &ti);
}
static void GUI_AddButton( HWND parent, const char *name, int x, int y, int id )
{
HWND btn;
btn = CreateWindow( "button", name, WS_CHILD | WS_VISIBLE, x, y, 78, 26,
parent, (HMENU)id, s_gui.gHinst, NULL);
GUI_ApplyFont( btn );
GUI_AddToolTip( btn, "test" );
}
void GUI_DisplayTooltips( HWND hwnd, DWORD dParam )
{
switch( dParam )
{
case IDB_CHOOSEFONT:
Msg("display help\n");
//MessageBox(hwnd, "Choose default font for editor", "Help", MB_OK|MB_ICONINFORMATION);
break;
}
}
// DoLockDlgRes - loads and locks a dialog box template resource.
// Returns the address of the locked resource.
// lpszResName - name of the resource
DLGTEMPLATE *WINAPI DoLockDlgRes(LPCSTR lpszResName)
{
HGLOBAL hglb;
HRSRC hrsrc = FindResource(GetModuleHandle("editor"), lpszResName, RT_DIALOG);
if(!hrsrc) Sys_Error("not found res\n");
hglb = LoadResource(GetModuleHandle("editor"), hrsrc);
return (DLGTEMPLATE *)LockResource(hglb);
}
// OnChildDialogInit - Positions the child dialog box to fall
// within the display area of the tab control.
void WINAPI OnChildDialogInit(HWND hwndDlg)
{
HWND hwndParent = GetParent(hwndDlg);
DLGHDR *pHdr = (DLGHDR *) GetWindowLong( hwndParent, GWL_USERDATA);
SetWindowPos(hwndDlg, HWND_TOP, pHdr->rcDisplay.left, pHdr->rcDisplay.top, 0, 0, SWP_NOSIZE);
ShowWindow(hwndDlg, SW_SHOWNORMAL);
GUI_AddToolTip(GetDlgItem(hwndDlg, IDB_CHOOSEFONT), "Choose font" );
}
void GUI_UpdateOptions( WPARAM wParam );
static LRESULT CALLBACK ChildDialogProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
HELPINFO *hi;
switch( uMessage )
{
case WM_INITDIALOG:
OnChildDialogInit( hwnd );
break;
//return true;
case WM_COMMAND:
GUI_UpdateOptions(wParam);
break;
case WM_HELP:
hi = (HELPINFO *)lParam;
GUI_DisplayTooltips( hwnd, hi->iCtrlId );
break;
}
return DefWindowProc (hwnd, uMessage, wParam, lParam);
}
// OnSelChanged - processes the TCN_SELCHANGE notification.
// hwndDlg - handle to the parent dialog box.
void WINAPI OnSelChanged(HWND hwndDlg)
{
DLGHDR *pHdr = (DLGHDR *) GetWindowLong( hwndDlg, GWL_USERDATA);
int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
// Destroy the current child dialog box, if any.
if (pHdr->hwndDisplay != NULL) DestroyWindow(pHdr->hwndDisplay);
// Create the new child dialog box.
pHdr->hwndDisplay = CreateDialogIndirect(s_gui.gHinst, pHdr->apRes[iSel], hwndDlg, ChildDialogProc);
}
void WINAPI OnTabbedDialogInit( HWND hwndDlg )
{
DLGHDR *pHdr = (DLGHDR *)LocalAlloc(LPTR, sizeof(DLGHDR));
DWORD dwDlgBase = GetDialogBaseUnits();
int cxMargin = LOWORD(dwDlgBase) / 4;
int cyMargin = HIWORD(dwDlgBase) / 8;
TCITEM tie;
RECT rcTab;
int i;
// Save a pointer to the DLGHDR structure.
SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pHdr);
// Create the tab control.
pHdr->hwndTab = CreateWindow( WC_TABCONTROL, "", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
0, 0, OPTS_WND_WIDTH, OPTS_WND_HEIGHT, hwndDlg, NULL, s_gui.gHinst, NULL );
if (pHdr->hwndTab == NULL)
{
// handle error
GUI_Error("can't create hwnd dialog\n" );
return;
}
GUI_ApplyFont( pHdr->hwndTab );
// Add a tab for each of the three child dialog boxes.
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
tie.pszText = "General";
TabCtrl_InsertItem(pHdr->hwndTab, 0, &tie);
tie.pszText = "Compilers";
TabCtrl_InsertItem(pHdr->hwndTab, 1, &tie);
tie.pszText = "QuakeC";
TabCtrl_InsertItem(pHdr->hwndTab, 2, &tie);
// Lock the resources for the three child dialog boxes.
pHdr->apRes[0] = DoLockDlgRes(MAKEINTRESOURCE(DLG_FIRST));
pHdr->apRes[1] = DoLockDlgRes(MAKEINTRESOURCE(DLG_SECOND));
pHdr->apRes[2] = DoLockDlgRes(MAKEINTRESOURCE(DLG_THIRD));
// Determine the bounding rectangle for all child dialog boxes.
SetRectEmpty(&rcTab);
for (i = 0; i < C_PAGES; i++)
{
if (pHdr->apRes[i]->cx > rcTab.right)
rcTab.right = pHdr->apRes[i]->cx;
if (pHdr->apRes[i]->cy > rcTab.bottom)
rcTab.bottom = pHdr->apRes[i]->cy;
}
rcTab.right = rcTab.right * LOWORD(dwDlgBase) / 4;
rcTab.bottom = rcTab.bottom * HIWORD(dwDlgBase) / 8;
// Calculate how large to make the tab control, so
// the display area can accommodate all the child dialog boxes.
TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
OffsetRect(&rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top);
// Calculate the display rectangle.
CopyRect(&pHdr->rcDisplay, &rcTab);
TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
// Set the size and position of the tab control, buttons,
// and dialog box.
SetWindowPos(pHdr->hwndTab, NULL, rcTab.left, rcTab.top, OPTS_WND_WIDTH + 10, OPTS_WND_HEIGHT, SWP_NOZORDER);
// Size the dialog box.
SetWindowPos(hwndDlg, NULL, 0, 0, OPTS_WND_WIDTH + 10, OPTS_WND_HEIGHT, SWP_NOMOVE | SWP_NOZORDER);
s_gui.hTips = CreateWindowEx (0, TOOLTIPS_CLASS, "", WS_POPUP | WS_EX_TOPMOST, 0, 0, 0, 0, pHdr->hwndTab, NULL, s_gui.gHinst, NULL);
// Simulate selection of the first item.
OnSelChanged( hwndDlg );
}
/*
=============================================================================
GUI Table Options
=============================================================================
*/
void GUI_ResizeTab(HWND hwnd)
{
TC_ITEM ti;
int index = TabCtrl_GetCurSel (hwnd);
if( index >= 0 )
{
ti.mask = TCIF_PARAM;
TabCtrl_GetItem (hwnd, index, &ti);
if (s_gui.hOptions)
{
RECT rc, rc2;
HDWP hdwp;
GetWindowRect (hwnd, &rc);
ScreenToClient (s_gui.hTabs, (LPPOINT) &rc.left);
ScreenToClient (s_gui.hTabs, (LPPOINT) &rc.right);
TabCtrl_GetItemRect (hwnd, index, &rc2);
rc.top += (rc2.bottom - rc2.top) - 6;
hdwp = BeginDeferWindowPos (2);
DeferWindowPos (hdwp, s_gui.hTabs, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
DeferWindowPos (hdwp, s_gui.hTabs, HWND_TOP, rc.left + 3, rc.top - 8, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW);
EndDeferWindowPos (hdwp);
}
}
}
static void GUI_AddTab( const char *name )
{
TC_ITEM ti;
ti.mask = TCIF_TEXT | TCIF_PARAM;
ti.pszText = (LPSTR)name;
TabCtrl_InsertItem (s_gui.hTabs, TabCtrl_GetItemCount(s_gui.hTabs), &ti);
GUI_ResizeTab(s_gui.hTabs);
}
bool GUI_CloseOptions( void )
{
ShowWindow( s_gui.hOptions, SW_HIDE );
//return to main window
EnableWindow( s_gui.hWnd, true );
SetFocus( s_gui.hWnd );
return false;
}
bool GUI_ApplyOptions( void )
{
//TODO:
//1. copy parameters from temporary struct to global
//2. apply some changes immediately if needed
//3. save settings into "bin/editor.dat"
return GUI_CloseOptions();
}
void GUI_UpdateOptions( WPARAM wParam )
{
CHOOSEFONT cf;
static LOGFONT lf; // logical font structure
static DWORD rgbCurrent; // current text color
ZeroMemory(&cf, sizeof(cf));
cf.lStructSize = sizeof (cf);
cf.hwndOwner = s_gui.hWnd;
cf.lpLogFont = &lf;
cf.rgbColors = rgbCurrent;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
switch(LOWORD(wParam))
{
case IDOK:
GUI_ApplyOptions();
break;
case IDCANCEL:
GUI_CloseOptions();
break;
case IDB_CHOOSEFONT:
if(ChooseFont(&cf))
{
Msg("apply font %s\n", cf.lpLogFont->lfFaceName);
strcpy(w_opts.fontname, cf.lpLogFont->lfFaceName);
//Msg("apply font %d\n", cf.lpLogFont->lfHeight -MulDiv(cf.iPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72));
}
break;
}
}
static LRESULT CALLBACK OptWndProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch( uMessage )
{
case WM_CREATE:
OnTabbedDialogInit( hwnd );
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
EndPaint(hwnd,(LPPAINTSTRUCT)&ps);
return TRUE;
break;
case WM_COMMAND:
GUI_UpdateOptions(wParam);
break;
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case TCN_SELCHANGE:
OnSelChanged( hwnd );
break;
}
break;
return true;
case WM_SIZE:
break;
case WM_CLOSE:
return GUI_CloseOptions();
break;
}
return DefWindowProc (hwnd, uMessage, wParam, lParam);
}
void GUI_CreateOptionsWindow( void )
{
WNDCLASS wc;
RECT rect;
int w_pos, h_pos;
//int WNDSTYLE = WS_POPUP | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX;
int WNDSTYLE = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;
int TABSTYLE = WS_CHILD | WS_VISIBLE | WS_TABSTOP | TCS_TOOLTIPS;
int bpos_x, bpos_y;
memset( &wc, 0, sizeof( wc ));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = OptWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_gui.gHinst;
wc.hIcon = LoadIcon(NULL, NULL);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) COLOR_3DSHADOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = EDITOR_SETTINGS;
if (!RegisterClass (&wc)) GUI_Error("Can't create options window\n");
//move window into center of screen
rect.left = 0;
rect.right = OPTS_WND_WIDTH;
rect.top = 0;
rect.bottom = OPTS_WND_HEIGHT;
AdjustWindowRect( &rect, WNDSTYLE, FALSE );
w_pos = ( s_gui.scr_width - OPTS_WND_WIDTH ) / 2;
h_pos = ( s_gui.scr_height - OPTS_WND_HEIGHT ) / 2;
s_gui.hOptions = CreateWindowEx( WS_EX_CLIENTEDGE | WS_EX_CONTEXTHELP, EDITOR_SETTINGS, "Settings", WNDSTYLE,
w_pos, h_pos, rect.right - rect.left, rect.bottom - rect.top, s_gui.hWnd, NULL, s_gui.gHinst, NULL);
GetClientRect(s_gui.hOptions, &rect);
bpos_x = rect.right - rect.left - 78 - 5;
bpos_y = rect.bottom - rect.top - 26 - 5;
GUI_AddButton( s_gui.hOptions, "&Cancel", bpos_x, bpos_y, IDCANCEL );
bpos_x -= 78 + 5;//move next button
GUI_AddButton( s_gui.hOptions, "&OK", bpos_x, bpos_y, IDOK );
}
/*
=============================================================================
GUI Acellerators
=============================================================================
*/
void GUI_ResetWndOptions( void )
{
//get info about debug mode
if(CheckParm ("-debug")) debug_mode = true;
s_gui.gHinst = (HINSTANCE) GetModuleHandle( NULL );
//reset options
w_opts.id = IDEDITORHEADER;
w_opts.version = (int)EDITOR_VERSION;
w_opts.csize = sizeof(wnd_options_t);
w_opts.show_console = true;
w_opts.con_scale = 6L;
w_opts.exp_scale = 5L;
w_opts.font_size = 7;
strcpy(w_opts.fontname, "Courier");
w_opts.font_type = CFM_BOLD | CFM_FACE | CFM_COLOR;
w_opts.font_color = RGB(0,0,0);
}
bool GUI_LoadPlatfrom( char *funcname, int argc, char **argv )
{
stdinout_api_t pistd;//platform callback
platform_t CreatePlat;
//create callbacks for platform.dll
pistd.printf = GUI_Msg;
pistd.dprintf = GUI_MsgDev;
pistd.wprintf = GUI_MsgWarn;
pistd.error = GUI_Error;
pistd.exit = std.exit;
pistd.print = GUI_Print;
//loading platform.dll
if (( platform_dll = LoadLibrary( "bin/platform.dll" )) == 0 )
{
GUI_Error("couldn't find platform.dll\n");
return false;
}
if ((CreatePlat = (void *)GetProcAddress( platform_dll, "CreateAPI" ) ) == 0 )
{
GUI_Error("platform.dll has no valid entry point\n");
return false;
}
pi = CreatePlat( pistd );//make links
//initialziing platform.dll
pi->Init( argc, argv );
pi->Fs.ClearSearchPath();
pi->AddGameHierarchy( "bin" );
return true;
}
HWND GUI_CreateConsole( bool readonly )
{
HWND newwnd;
DWORD dwStyle = WS_CHILD | WS_HSCROLL |
WS_VSCROLL | ES_LEFT | ES_WANTRETURN | ES_MULTILINE | ES_AUTOVSCROLL;
if (readonly) dwStyle |= ES_READONLY;
if (!s_gui.richedit) s_gui.richedit = LoadLibrary("riched32.dll");
newwnd = CreateWindowEx(WS_EX_CLIENTEDGE, s_gui.richedit ? RICHEDIT_CLASS:"EDIT", "",
dwStyle, 0, 0, 0, 0, s_gui.hWnd, NULL, s_gui.gHinst, NULL);
if (!newwnd)
{
//fall back to the earlier version
newwnd = CreateWindowEx(WS_EX_CLIENTEDGE, s_gui.richedit ? RICHEDIT_CLASS10A : "EDIT", "",
dwStyle, 0, 0, 0, 0, s_gui.hWnd, NULL, s_gui.gHinst, NULL);
}
if (!newwnd)
{
//we don't have RICHEDIT installed properly
FreeLibrary(s_gui.richedit);
s_gui.richedit = NULL;
newwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", dwStyle, 0, 0, 0, 0,
s_gui.hWnd, NULL, s_gui.gHinst, NULL);
}
GUI_SetFont( newwnd );
if (s_gui.richedit) SendMessage(newwnd, EM_EXLIMITTEXT, 0, 1<<20);
return newwnd;
}
void GUI_CreateEditorWindow( void )
{
s_gui.hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, CLASSNAME, "Xash Resource Editor", WS_OVERLAPPEDWINDOW,
s_gui.top, s_gui.bottom, s_gui.width, s_gui.height, NULL, NULL, s_gui.gHinst, NULL);
s_gui.hConsole = GUI_CreateConsole( true );
}
/*
=============================================================================
GUI Console System
=============================================================================
*/
void GUI_PrintIntoBuffer(const char *pMsg)
{
strcat(textbuffer, pMsg );
}
void GUI_ExecuteBuffer(void)
{
editor_init = true;
GUI_Print(textbuffer);
}
/*
====================
GUI_Print
stdout into editor internal console
====================
*/
void GUI_Print(const char *pMsg)
{
CHARFORMAT cf;
char buffer[MAX_INPUTLINE*2];
char *b = buffer;
const char *msg;
int bufLen;
int i = 0;
int color = RGB(0, 0, 0);
static unsigned long s_totalChars;
if(!editor_init)
{
GUI_PrintIntoBuffer( pMsg );
return;
}
// if the message is REALLY long, use just the last portion of it
if ( strlen( pMsg ) > MAX_INPUTLINE - 1 )
msg = pMsg + strlen( pMsg ) - MAX_INPUTLINE + 1;
else msg = pMsg;
// copy into an intermediate buffer
while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) )
{
if ( msg[i] == '\n' && msg[i+1] == '\r' )
{
b[0] = '\r';
b[1] = '\n';
b += 2;
i++;
}
else if ( msg[i] == '\r' )
{
b[0] = '\r';
b[1] = '\n';
b += 2;
}
else if ( msg[i] == '\n' )
{
b[0] = '\r';
b[1] = '\n';
b += 2;
}
else if ( IsColorString( &msg[i] ))
{
int code = 0;
i++;
code = atoi( &msg[i] );
if(code == 5) color = RGB(255, 0, 0);
}
else
{
*b= msg[i];
b++;
}
i++;
}
*b = 0;
bufLen = b - buffer;
s_totalChars += bufLen;
//Edit_SetSel(s_gui.hConsole, 0, s_totalChars);
memset(&cf, 0, sizeof(cf));
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.crTextColor = color;
// replace selection instead of appending if we're overflowing
if ( s_totalChars > 0x7fff )
{
SendMessage( s_gui.hConsole, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
//SendMessage( s_gui.hConsole, EM_SETSEL, 0, -1 );
s_totalChars = bufLen;
//Edit_SetSel(s_gui.hConsole, bufLen, s_totalChars);
}
// put this text into the windows console
SendMessage( s_gui.hConsole, EM_LINESCROLL, 0, 0xffff );
SendMessage( s_gui.hConsole, EM_SCROLLCARET, 0, 0 );
SendMessage( s_gui.hConsole, EM_REPLACESEL, 0, (LPARAM) buffer );
}
/*
================
GUI_Msg
formatted message
================
*/
void GUI_Msg( const char *pMsg, ... )
{
va_list argptr;
char text[MAX_INPUTLINE];
va_start (argptr, pMsg);
vsprintf (text, pMsg, argptr);
va_end (argptr);
GUI_Print( text );
//echo into system console
std.print( text );
}
void GUI_MsgDev( const char *pMsg, ... )
{
va_list argptr;
char text[MAX_INPUTLINE];
if(debug_mode)
{
va_start (argptr, pMsg);
vsprintf (text, pMsg, argptr);
va_end (argptr);
GUI_Print( text );
//echo into system console
std.print( text );
}
}
void GUI_MsgWarn( const char *pMsg, ... )
{
va_list argptr;
char text[MAX_INPUTLINE];
if(debug_mode)
{
va_start (argptr, pMsg);
vsprintf (text, pMsg, argptr);
va_end (argptr);
GUI_Print( text );
//echo into system console
std.print( text );
}
}
void GUI_Error( const char *pMsg, ... )
{
va_list argptr;
char text[MAX_INPUTLINE];
va_start (argptr, pMsg);
vsprintf (text, pMsg, argptr);
va_end (argptr);
GUI_DisableMenus();
GUI_Print( text );
std.print( text );//echo into system console
//3. waiting for user input
//std.exit();
}
void GUI_CreateMenus( void )
{
int TREESTYLE = WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES;
//create root menu
s_gui.menu = CreateMenu();
//create volumes
s_gui.file = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.file, "&File");
s_gui.edit = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.edit, "&Edit");
s_gui.cmds = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.cmds, "&Tools");
s_gui.help = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.help, "&Help");
//build menu "file"
GUI_AddMenuItem(s_gui.file, "&New... Ctrl + N", IDM_CREATE, VK_N );
GUI_AddMenuItem(s_gui.file, "&Open... Ctrl + O", IDM_OPEN, VK_O );
GUI_AddMenuItem(s_gui.file, "&Close", IDM_CLOSE, 0 );
GUI_AddMenuItem(s_gui.file, "", 0, 0 );//separator
GUI_AddMenuItem(s_gui.file, "&Save... Ctrl + S", IDM_SAVE, VK_S );
GUI_AddMenuItem(s_gui.file, "Save &As...", IDM_SAVEAS, 0 );
GUI_AddMenuItem(s_gui.file, "", 0, 0 );//separator
GUI_AddMenuItem(s_gui.file, "E&xit", IDM_QUIT, 0 );
//build menu "edit"
GUI_AddMenuItem(s_gui.edit, "&Undo Ctrl + Z", IDM_UNDO, VK_Z );
GUI_AddMenuItem(s_gui.edit, "&Redo Ctrl + Y", IDM_REDO, VK_Y );
GUI_AddMenuItem(s_gui.edit, "", 0, 0 );//separator
GUI_AddMenuItem(s_gui.edit, "Cu&t Ctrl + X", IDM_CUT, VK_X );
GUI_AddMenuItem(s_gui.edit, "&Copy Ctrl + C", IDM_COPY, VK_C );
GUI_AddMenuItem(s_gui.edit, "&Paste Ctrl + V", IDM_PASTE, VK_V );
GUI_AddMenuItem(s_gui.edit, "&Delete Del", IDM_DELETE, VK_DELETE );
GUI_AddMenuItem(s_gui.edit, "", 0, 0 );//separator
GUI_AddMenuItem(s_gui.edit, "&Find Ctrl + F", IDM_FIND, VK_F );
GUI_AddMenuItem(s_gui.edit, "R&eplace Ctrl + H", IDM_REPLACE, VK_H );
GUI_AddMenuItem(s_gui.edit, "&Go to... Ctrl + G", IDM_GOTO, VK_G );
//build menu "tools"
GUI_AddMenuItem(s_gui.cmds, "&Compile... F7", IDM_COMPILE, VK_F7 );
GUI_AddMenuItem(s_gui.cmds, "D&ump Info... F3", IDM_GETINFO, VK_F3 );
GUI_AddMenuItem(s_gui.cmds, "", 0, 0 );//separator
GUI_AddMenuItem(s_gui.cmds, "&Settings... F10", IDM_SETTINGS, VK_F10 );
AppendMenu(s_gui.cmds, MF_CHECKED, IDM_SHOWCONSOLE, "Show console");
RegisterHotKey(s_gui.hWnd, IDH_HIDECONSOLE, 0, VK_ESCAPE );
//fill menu "help"
AppendMenu(s_gui.help, 0, IDM_ABOUT, "&About");
SetMenu(s_gui.hWnd, s_gui.menu);
s_gui.hTree = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREEVIEW, "", TREESTYLE,
0, 0, 127, 380, s_gui.hWnd, (HMENU)IDM_FIRSTCHILD, s_gui.gHinst, NULL);
GUI_CreateAccelTable();
ShowWindow(s_gui.hTree, SW_SHOWDEFAULT);
}
void GUI_DisableMenus( void )
{
EnableMenuItem(s_gui.file, IDM_CREATE, MF_GRAYED);
EnableMenuItem(s_gui.file, IDM_OPEN, MF_GRAYED);
EnableMenuItem(s_gui.file, IDM_CLOSE, MF_GRAYED);
EnableMenuItem(s_gui.file, IDM_SAVE, MF_GRAYED);
EnableMenuItem(s_gui.file, IDM_SAVEAS, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_UNDO, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_REDO, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_CUT, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_COPY, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_PASTE, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_DELETE, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_FIND, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_REPLACE, MF_GRAYED);
EnableMenuItem(s_gui.edit, IDM_GOTO, MF_GRAYED);
EnableMenuItem(s_gui.cmds, IDM_COMPILE, MF_GRAYED);
EnableMenuItem(s_gui.cmds, IDM_GETINFO, MF_GRAYED);
EnableMenuItem(s_gui.cmds, IDM_SETTINGS, MF_GRAYED);
}
void GUI_ShowConsole( void )
{
w_opts.show_console = true;
ShowWindow( s_gui.hConsole, SW_SHOWNORMAL );
SendMessage( s_gui.hConsole, EM_LINESCROLL, 0, 0xffff );
CheckMenuItem(s_gui.cmds, IDM_SHOWCONSOLE, MF_CHECKED);
SendMessage( s_gui.hWnd, WM_SIZE, 1, 0 );
}
void GUI_HideConsole( void )
{
w_opts.show_console = false;
ShowWindow(s_gui.hConsole, SW_HIDE);
CheckMenuItem(s_gui.cmds, IDM_SHOWCONSOLE, MF_UNCHECKED);
SendMessage( s_gui.hWnd, WM_SIZE, 1, 0 );//update windows
}
void GUI_UpdateDefault( WPARAM wParam )
{
switch(LOWORD(wParam))
{
case IDM_DELETE:
Msg("delete accel\n");
break;
case IDM_COMPILE:
break;
case IDM_GETINFO:
break;
case IDM_SETTINGS:
ShowWindow( s_gui.hOptions, SW_SHOWNORMAL );
SetFocus( s_gui.hOptions );
EnableWindow( s_gui.hWnd, false );
break;
case IDM_SHOWCONSOLE:
if(w_opts.show_console) GUI_HideConsole();
else GUI_ShowConsole();
break;
case IDM_ABOUT:
if(!w_opts.show_console) GUI_ShowConsole();
Msg("Xash Resource Editor. Ver %g\n", EDITOR_VERSION );
Msg("Copyright XashXT Group 2007 ©.\n");
break;
}
}
void GUI_UpdateMenu( WPARAM wParam )
{
switch(LOWORD(wParam))
{
case IDM_CREATE:
Msg("Create new file\n");
break;
case IDM_OPEN:
Msg("open file\n");
break;
case IDM_CLOSE:
break;
case IDM_SAVE:
break;
case IDM_SAVEAS:
break;
case IDM_QUIT:
PostQuitMessage (0);
break;
default:
GUI_UpdateDefault( wParam );
break;
}
}
void GUI_HotKeys( WPARAM wParam )
{
switch(LOWORD(wParam))
{
case IDH_HIDECONSOLE:
if(w_opts.show_console)
GUI_HideConsole();
break;
default:
MsgWarn("GUI_HotKeys: call unused hotkey %d\n", LOWORD(wParam));
break;
}
}
static LRESULT CALLBACK WndProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (uMessage)
{
case WM_CREATE:
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
EndPaint(hwnd,(LPPAINTSTRUCT)&ps);
return TRUE;
break;
case WM_HOTKEY:
GUI_HotKeys( wParam );
break;
case WM_CHILDACTIVATE:
Msg("process child\n");
break;
case WM_SIZE:
if(s_gui.hWnd)
{
int con_w, con_h, con_y;
int exp_w, exp_h, coffs;
RECT rect;
GetClientRect(s_gui.hWnd, &rect);
con_h = (rect.bottom - rect.top) / w_opts.con_scale; //console scale factor
con_y = rect.bottom - rect.top - con_h; //console hight
con_w = rect.right - rect.left;
if(s_gui.hConsole && IsWindowVisible(s_gui.hConsole)) coffs = con_h;
else coffs = 0;
exp_w = (rect.right - rect.left) / w_opts.exp_scale; //explorer scale factor
exp_h = rect.bottom - rect.top - coffs; //explorer height
//make me sure what handle is valid
if(s_gui.hConsole) SetWindowPos(s_gui.hConsole, NULL, 0, con_y, con_w, con_h, 0);
if(s_gui.hTree) SetWindowPos(s_gui.hTree, NULL, 0, 0, exp_w, exp_h, 0);
}
break;
case WM_COMMAND:
GUI_UpdateMenu(wParam);
break;
case WM_CLOSE:
if (hwnd == s_gui.hWnd) PostQuitMessage (0);
else ShowWindow (hwnd, SW_HIDE);
return 0;
break;
}
return DefWindowProc (hwnd, uMessage, wParam, lParam);
}
void InitEditor ( char *funcname, int argc, char **argv )
{
HDC hDC;
WNDCLASS wc;
RECT rect;
int WNDSTYLE = WS_OVERLAPPEDWINDOW;
int iErrors = 0;
memset( &wc, 0, sizeof( wc ));
com_argc = argc;
memcpy(com_argv, argv, MAX_NUM_ARGVS );
GUI_ResetWndOptions();//load default settings
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_gui.gHinst;
wc.hIcon = LoadIcon (wc.hInstance, MAKEINTRESOURCE(IDI_ICON1));
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = CLASSNAME;
if (!wc.hIcon) wc.hIcon = LoadIcon (NULL, IDI_WINLOGO);
if (!RegisterClass (&wc)) Sys_Error("Can't create editor window\n");
//move window into center of screen
rect.left = 0;
rect.right = MAIN_WND_WIDTH;
rect.top = 0;
rect.bottom = MAIN_WND_HEIGHT;
AdjustWindowRect( &rect, WNDSTYLE, FALSE );
hDC = GetDC( GetDesktopWindow() );
s_gui.scr_width = GetDeviceCaps( hDC, HORZRES );
s_gui.scr_height = GetDeviceCaps( hDC, VERTRES );
ReleaseDC( GetDesktopWindow(), hDC );
s_gui.width = rect.right - rect.left;
s_gui.height = rect.bottom - rect.top;
s_gui.top = ( s_gui.scr_width - MAIN_WND_WIDTH ) / 2;
s_gui.bottom = ( s_gui.scr_height - MAIN_WND_HEIGHT ) / 2;
InitCommonControls ();
if(GUI_LoadPlatfrom( funcname, argc, argv )) //load config
{
wnd_options_t *config_dat;
int config_size;
config_dat = (wnd_options_t *)pi->Fs.LoadFile( "editor.dat", &config_size );
if(config_dat) //verify our config before read
{
if(config_dat->id != IDEDITORHEADER)
{
MsgWarn("InitEditor: editor.dat have mismath header!\n");
iErrors++;
}
if(config_dat->version != (int)EDITOR_VERSION)
{
MsgWarn("InitEditor: editor.dat have mismath version!\n");
iErrors++;
}
if(config_dat->csize != config_size)
{
MsgWarn("InitEditor: editor.dat have mismath size!\n");
iErrors++;
}
//copy settings into main structure
if(!iErrors) memcpy( &w_opts, config_dat, sizeof(w_opts));
}
}
else iErrors++;
GUI_CreateEditorWindow();
GUI_CreateMenus();
GUI_CreateOptionsWindow();
//apply chnages
if(w_opts.show_console) GUI_ShowConsole();
else GUI_HideConsole();
if(iErrors) GUI_DisableMenus(); // apply error
GUI_ExecuteBuffer(); //show all messages
//end of all initializations
ShowWindow(s_gui.hWnd, SW_SHOWDEFAULT);
MsgDev("------- Xash Recource Editor ver. %g initialized -------\n", EDITOR_VERSION );
}
void EditorMain ( void )
{
// wait for the user to quit
while(msg.message != WM_QUIT)
{
if(GetMessage (&msg, 0, 0, 0))
{
if (!LookupAccelTable( msg ))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
}
if(platform_dll)
{
// save our settings
pi->Fs.WriteFile("editor.dat", &w_opts, w_opts.csize );
}
}
void FreeEditor ( void )
{
//free richedit32
if (s_gui.richedit) FreeLibrary( s_gui.richedit );
//free platform
if(platform_dll)
{
pi->Shutdown();
FreeLibrary(platform_dll);
}
GUI_RemoveAccelTable();
UnregisterClass (CLASSNAME, s_gui.gHinst);
}