2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
34 #include "SurfaceDlg.h"
40 static char THIS_FILE[] = __FILE__;
43 /////////////////////////////////////////////////////////////////////////////
46 CSurfaceDlg g_dlgSurface;
49 CSurfaceDlg::CSurfaceDlg(CWnd* pParent /*=NULL*/)
50 : CDialog(CSurfaceDlg::IDD, pParent) {
51 //{{AFX_DATA_INIT(CSurfaceDlg)
59 m_strMaterial = _T("");
68 void CSurfaceDlg::DoDataExchange(CDataExchange* pDX) {
69 CDialog::DoDataExchange(pDX);
70 //{{AFX_DATA_MAP(CSurfaceDlg)
71 DDX_Control(pDX, IDC_ROTATE, m_wndRotateEdit);
72 DDX_Control(pDX, IDC_EDIT_VERT, m_wndVert);
73 DDX_Control(pDX, IDC_EDIT_HORZ, m_wndHorz);
74 DDX_Control(pDX, IDC_SLIDER_VERT, m_wndVerticalSubdivisions);
75 DDX_Control(pDX, IDC_SLIDER_HORZ, m_wndHorzSubdivisions);
76 DDX_Control(pDX, IDC_SPIN_WIDTH, m_wndWidth);
77 DDX_Control(pDX, IDC_SPIN_HEIGHT, m_wndHeight);
78 DDX_Control(pDX, IDC_SPIN_VSHIFT, m_wndVShift);
79 DDX_Control(pDX, IDC_SPIN_ROTATE, m_wndRotate);
80 DDX_Control(pDX, IDC_SPIN_HSHIFT, m_wndHShift);
81 DDX_Text(pDX, IDC_EDIT_HORZ, m_nHorz);
82 DDV_MinMaxInt(pDX, m_nHorz, 1, 64);
83 DDX_Text(pDX, IDC_EDIT_VERT, m_nVert);
84 DDV_MinMaxInt(pDX, m_nVert, 1, 64);
85 DDX_Text(pDX, IDC_HSCALE, m_horzScale);
86 DDX_Text(pDX, IDC_HSHIFT, m_horzShift);
87 DDX_Text(pDX, IDC_ROTATE, m_rotate);
88 DDX_Text(pDX, IDC_VSCALE, m_vertScale);
89 DDX_Text(pDX, IDC_VSHIFT, m_vertShift);
90 DDX_Text(pDX, IDC_TEXTURE, m_strMaterial);
91 DDX_Check(pDX, IDC_CHECK_SUBDIVIDE, m_subdivide);
92 DDX_Text(pDX, IDC_EDIT_HEIGHT, m_fHeight);
93 DDX_Text(pDX, IDC_EDIT_WIDTH, m_fWidth);
94 DDX_Check(pDX, IDC_CHECK_ABSOLUTE, m_absolute);
99 BEGIN_MESSAGE_MAP(CSurfaceDlg, CDialog)
100 //{{AFX_MSG_MAP(CSurfaceDlg)
106 ON_BN_CLICKED(IDCANCEL, OnBtnCancel)
107 ON_BN_CLICKED(IDC_BTN_COLOR, OnBtnColor)
110 ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSHIFT, OnDeltaPosSpin)
111 ON_BN_CLICKED(IDC_BTN_PATCHDETAILS, OnBtnPatchdetails)
112 ON_BN_CLICKED(IDC_BTN_PATCHNATURAL, OnBtnPatchnatural)
113 ON_BN_CLICKED(IDC_BTN_PATCHRESET, OnBtnPatchreset)
114 ON_BN_CLICKED(IDC_BTN_AXIAL, OnBtnAxial)
115 ON_BN_CLICKED(IDC_BTN_BRUSHFIT, OnBtnBrushfit)
116 ON_BN_CLICKED(IDC_BTN_FACEFIT, OnBtnFacefit)
117 ON_BN_CLICKED(IDC_CHECK_SUBDIVIDE, OnCheckSubdivide)
118 ON_EN_CHANGE(IDC_EDIT_HORZ, OnChangeEditHorz)
119 ON_EN_CHANGE(IDC_EDIT_VERT, OnChangeEditVert)
120 ON_EN_SETFOCUS(IDC_HSCALE, OnSetfocusHscale)
121 ON_EN_KILLFOCUS(IDC_HSCALE, OnKillfocusHscale)
122 ON_EN_KILLFOCUS(IDC_VSCALE, OnKillfocusVscale)
123 ON_EN_SETFOCUS(IDC_VSCALE, OnSetfocusVscale)
124 ON_EN_KILLFOCUS(IDC_EDIT_WIDTH, OnKillfocusEditWidth)
125 ON_EN_SETFOCUS(IDC_EDIT_WIDTH, OnSetfocusEditWidth)
126 ON_EN_KILLFOCUS(IDC_EDIT_HEIGHT, OnKillfocusEditHeight)
127 ON_EN_SETFOCUS(IDC_EDIT_HEIGHT, OnSetfocusEditHeight)
128 ON_BN_CLICKED(IDC_BTN_FLIPX, OnBtnFlipx)
129 ON_BN_CLICKED(IDC_BTN_FLIPY, OnBtnFlipy)
130 ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ROTATE, OnDeltaPosSpin)
131 ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSHIFT, OnDeltaPosSpin)
132 ON_EN_KILLFOCUS(IDC_ROTATE, OnKillfocusRotate)
133 ON_EN_SETFOCUS(IDC_ROTATE, OnSetfocusRotate)
137 /////////////////////////////////////////////////////////////////////////////
138 // CSurfaceDlg message handlers
142 ===================================================
146 ===================================================
149 texdef_t g_old_texdef;
150 texdef_t g_patch_texdef;
151 HWND g_surfwin = NULL;
152 bool g_changed_surface;
158 Set the fields to the current texdef
159 if one face selected -> will read this face texdef, else current texdef
160 if only patches selected, will read the patch texdef
163 extern void Face_GetScale_BrushPrimit(face_t *face, float *s, float *t, float *rot);
164 void CSurfaceDlg::SetTexMods() {
166 m_strMaterial = g_qeglobals.d_texturewin.texdef.name;
167 patchMesh_t *p = SinglePatchSelected();
169 m_subdivide = p->explicitSubdivisions;
170 m_strMaterial = p->d_texture->GetName();
175 int faceCount = g_ptrSelectedFaces.GetSize();
176 face_t *selFace = NULL;
178 selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0));
180 if (selected_brushes.next != &selected_brushes) {
181 brush_t *b = selected_brushes.next;
183 selFace = b->brush_faces;
190 Face_GetScale_BrushPrimit(selFace, &m_horzScale, &m_vertScale, &rot);
200 bool g_bNewFace = false;
201 bool g_bNewApplyHandling = false;
202 bool g_bGatewayhack = false;
211 void CSurfaceDlg::UpdateSpinners(bool up, int nID) {
216 case IDC_SPIN_ROTATE :
217 Select_RotateTexture((up) ? m_rotate : -m_rotate);
219 case IDC_SPIN_HSCALE :
220 m_horzScale += (up) ? 0.1f : -0.1f;
221 hdiv = (m_horzScale == 0.0f) ? 1.0f : m_horzScale;
222 Select_ScaleTexture( 1.0f / hdiv, 0.0f, true, ( m_absolute != FALSE ) );
225 case IDC_SPIN_VSCALE :
226 m_vertScale += (up) ? 0.1f : -0.1f;
227 vdiv = (m_vertScale == 0.0f) ? 1.0f : m_vertScale;
228 Select_ScaleTexture( 0.0f, 1.0f / vdiv, true, ( m_absolute != FALSE ) );
231 case IDC_SPIN_HSHIFT :
232 Select_ShiftTexture((up) ? m_horzShift : -m_horzShift, 0);
234 case IDC_SPIN_VSHIFT :
235 Select_ShiftTexture(0, (up) ? m_vertShift : -m_vertShift);
238 g_changed_surface = true;
241 void CSurfaceDlg::UpdateSpinners(int nScrollCode, int nPos, CScrollBar* pBar) {
245 if ((nScrollCode != SB_LINEUP) && (nScrollCode != SB_LINEDOWN)) {
249 bool up = (nScrollCode == SB_LINEUP);
251 // FIXME: bad resource define
252 #define IDC_ROTATEA 0
253 #define IDC_HSCALEA 0
254 #define IDC_VSCALEA 0
255 #define IDC_HSHIFTA 0
256 #define IDC_VSHIFTA 0
258 if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_ROTATEA)) {
259 Select_RotateTexture((up) ? m_rotate : -m_rotate);
260 } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_HSCALEA)) {
261 Select_ScaleTexture((up) ? -m_horzScale : m_horzScale, 0, true, ( m_absolute != FALSE ) );
262 } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_VSCALEA)) {
263 Select_ScaleTexture(0, (up) ? -m_vertScale : m_vertScale, true, ( m_absolute != FALSE ) );
264 } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_HSHIFTA)) {
265 Select_ShiftTexture((up) ? -m_horzShift : m_horzShift, 0);
266 } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_VSHIFTA)) {
267 Select_ShiftTexture((up) ? -m_vertShift : m_vertShift, 0);
270 g_changed_surface = true;
273 void UpdateSurfaceDialog() {
275 g_dlgSurface.SetTexMods();
277 g_pParentWnd->UpdateTextureBar();
280 bool ByeByeSurfaceDialog();
282 void DoSurface (void) {
284 g_bNewFace = ( g_PrefsDlg.m_bFace != FALSE );
285 g_bNewApplyHandling = ( g_PrefsDlg.m_bNewApplyHandling != FALSE );
286 g_bGatewayhack = ( g_PrefsDlg.m_bGatewayHack != FALSE );
287 // save current state for cancel
288 g_old_texdef = g_qeglobals.d_texturewin.texdef;
289 g_changed_surface = false;
291 if (g_surfwin == NULL && g_dlgSurface.GetSafeHwnd() == NULL) {
292 g_patch_texdef.scale[0] = 0.05f;
293 g_patch_texdef.scale[1] = 0.05f;
294 g_patch_texdef.shift[0] = 0.05f;
295 g_patch_texdef.shift[1] = 0.05f;
296 // use rotation increment from preferences
297 g_patch_texdef.rotate = g_PrefsDlg.m_nRotation;
299 g_dlgSurface.Create(IDD_SURFACE);
301 LONG lSize = sizeof(rct);
302 if (LoadRegistryInfo("radiant_SurfaceWindow", &rct, &lSize)) {
303 g_dlgSurface.SetWindowPos( NULL, rct.left, rct.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW );
305 g_dlgSurface.ShowWindow(SW_SHOW);
306 Sys_UpdateWindows(W_ALL);
308 g_surfwin = g_dlgSurface.GetSafeHwnd();
309 g_dlgSurface.SetTexMods ();
310 g_dlgSurface.ShowWindow(SW_SHOW);
314 bool ByeByeSurfaceDialog() {
316 if (g_bGatewayhack) {
317 PostMessage(g_surfwin, WM_COMMAND, IDC_APPLY, 0);
319 PostMessage(g_surfwin, WM_COMMAND, IDCANCEL, 0);
327 BOOL CSurfaceDlg::OnInitDialog() {
328 CDialog::OnInitDialog();
330 g_surfwin = GetSafeHwnd();
333 //m_wndHScale.SetRange(0, 100);
334 //m_wndVScale.SetRange(0, 100);
335 m_wndHShift.SetRange(0, 100);
336 m_wndVShift.SetRange(0, 100);
337 m_wndRotate.SetRange(0, 100);
338 m_wndWidth.SetRange(1, 32);
339 m_wndHeight.SetRange(1, 32);
341 m_wndVerticalSubdivisions.SetRange(1, 32);
342 m_wndVerticalSubdivisions.SetBuddy(&m_wndVert, FALSE);
343 m_wndHorzSubdivisions.SetRange(1, 32);
344 m_wndHorzSubdivisions.SetBuddy(&m_wndHorz, FALSE);
345 m_wndVerticalSubdivisions.SetPos(m_nVert);
346 m_wndHorzSubdivisions.SetPos(m_nHorz);
348 return TRUE; // return TRUE unless you set the focus to a control
349 // EXCEPTION: OCX Property Pages should return FALSE
352 void CSurfaceDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
354 if (pScrollBar->IsKindOf(RUNTIME_CLASS(CSliderCtrl))) {
355 CSliderCtrl *ctrl = reinterpret_cast<CSliderCtrl*>(pScrollBar);
357 if (ctrl == &m_wndVerticalSubdivisions) {
358 m_nVert = ctrl->GetPos();
360 m_nHorz = ctrl->GetPos();
365 Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert );
368 Sys_UpdateWindows(W_CAMERA | W_XY);
371 void CSurfaceDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
373 CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
376 void CSurfaceDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
377 //UpdateSpinners(nSBCode, nPos, pScrollBar);
378 //Sys_UpdateWindows(W_CAMERA);
382 void CSurfaceDlg::OnOK() {
385 if (m_strMaterial.Find(":") >= 0) {
386 const idMaterial *mat = declManager->FindMaterial(m_strMaterial);
387 Select_UpdateTextureName(m_strMaterial);
391 Sys_UpdateWindows(W_ALL);
394 void CSurfaceDlg::OnClose() {
399 void CSurfaceDlg::OnCancel() {
400 if (g_bGatewayhack) {
407 void CSurfaceDlg::OnDestroy() {
411 SaveRegistryInfo("radiant_SurfaceWindow", &rct, sizeof(rct));
413 CDialog::OnDestroy();
415 Sys_UpdateWindows(W_ALL);
418 void CSurfaceDlg::OnBtnCancel() {
419 g_qeglobals.d_texturewin.texdef = g_old_texdef;
420 if (g_changed_surface) {
421 //++timo if !g_qeglobals.m_bBrushPrimitMode send a NULL brushprimit_texdef
422 if (!g_qeglobals.m_bBrushPrimitMode) {
423 common->Printf("Warning : non brush primitive mode call to CSurfaceDlg::GetTexMods broken\n");
424 common->Printf(" ( Select_SetTexture not called )\n");
426 // Select_SetTexture(&g_qeglobals.d_texturewin.texdef);
432 void CSurfaceDlg::OnBtnColor() {
435 HBRUSH CSurfaceDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {
436 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
440 int CSurfaceDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) {
441 if (CDialog::OnCreate(lpCreateStruct) == -1)
447 BOOL CSurfaceDlg::PreCreateWindow(CREATESTRUCT& cs) {
448 // TODO: Add your specialized code here and/or call the base class
450 return CDialog::PreCreateWindow(cs);
454 void CSurfaceDlg::OnDeltaPosSpin(NMHDR* pNMHDR, LRESULT* pResult) {
455 NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
456 UpdateSpinners((pNMUpDown->iDelta > 0), pNMUpDown->hdr.idFrom);
460 void CSurfaceDlg::OnBtnPatchdetails() {
461 Patch_NaturalizeSelected(true);
462 g_pParentWnd->GetCamera()->MarkWorldDirty ();
463 Sys_UpdateWindows(W_ALL);
466 void CSurfaceDlg::OnBtnPatchnatural() {
467 Select_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false);
468 Patch_NaturalizeSelected();
469 g_pParentWnd->GetCamera()->MarkWorldDirty ();
470 g_changed_surface = true;
471 Sys_UpdateWindows(W_ALL);
474 void CSurfaceDlg::OnBtnPatchreset() {
475 //CTextureLayout dlg;
476 //if (dlg.DoModal() == IDOK) {
477 // Patch_ResetTexturing(dlg.m_fX, dlg.m_fY);
479 //Sys_UpdateWindows(W_ALL);
482 void CSurfaceDlg::OnBtnAxial() {
485 void CSurfaceDlg::OnBtnBrushfit() {
486 // TODO: Add your control notification handler code here
490 void CSurfaceDlg::OnBtnFacefit() {
494 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) {
495 if (!b->patchBrush) {
496 for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next) {
497 g_ptrSelectedFaces.Add(pFace);
498 g_ptrSelectedFaceBrushes.Add(b);
503 Select_FitTexture(m_fHeight, m_fWidth);
504 g_pParentWnd->GetCamera()->MarkWorldDirty ();
506 g_changed_surface = true;
507 Sys_UpdateWindows(W_ALL);
511 void CSurfaceDlg::OnCheckSubdivide() {
513 // turn any patches in explicit subdivides
514 Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert );
515 g_pParentWnd->GetCamera()->MarkWorldDirty ();
516 Sys_UpdateWindows( W_CAMERA | W_XY );
519 void CSurfaceDlg::OnChangeEditHorz()
521 // TODO: If this is a RICHEDIT control, the control will not
522 // send this notification unless you override the CDialog::OnInitDialog()
523 // function and call CRichEditCtrl().SetEventMask()
524 // with the ENM_CHANGE flag ORed into the mask.
526 // TODO: Add your control notification handler code here
528 // turn any patches in explicit subdivides
529 Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert );
530 Sys_UpdateWindows(W_CAMERA | W_XY);
534 void CSurfaceDlg::OnChangeEditVert()
536 // TODO: If this is a RICHEDIT control, the control will not
537 // send this notification unless you override the CDialog::OnInitDialog()
538 // function and call CRichEditCtrl().SetEventMask()
539 // with the ENM_CHANGE flag ORed into the mask.
541 // TODO: Add your control notification handler code here
543 // turn any patches in explicit subdivides
544 Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert );
545 Sys_UpdateWindows(W_CAMERA | W_XY);
549 BOOL CSurfaceDlg::PreTranslateMessage(MSG* pMsg)
551 if (pMsg->message == WM_KEYDOWN) {
552 if (pMsg->wParam == VK_RETURN) {
555 if (focusControl == &m_wndHScale) {
556 Select_ScaleTexture( m_horzScale, 1.0f, true, ( m_absolute != FALSE ) );
557 } else if (focusControl == &m_wndVScale) {
558 Select_ScaleTexture( 1.0f, m_vertScale, true, ( m_absolute != FALSE ) );
559 } else if (focusControl == &m_wndRotateEdit) {
560 Select_RotateTexture( m_rotate, true );
561 } else if (focusControl == &m_wndHeight || focusControl == &m_wndWidth) {
562 Select_FitTexture( m_fHeight, m_fWidth );
568 return CDialog::PreTranslateMessage(pMsg);
571 void CSurfaceDlg::OnSetfocusHscale()
573 focusControl = &m_wndHScale;
576 void CSurfaceDlg::OnKillfocusHscale()
581 void CSurfaceDlg::OnKillfocusVscale()
586 void CSurfaceDlg::OnSetfocusVscale()
588 focusControl = &m_wndVScale;
591 void CSurfaceDlg::OnKillfocusEditWidth()
596 void CSurfaceDlg::OnSetfocusEditWidth()
598 focusControl = &m_wndWidth;
601 void CSurfaceDlg::OnKillfocusEditHeight()
606 void CSurfaceDlg::OnSetfocusEditHeight()
608 focusControl = &m_wndHeight;
611 void CSurfaceDlg::OnBtnFlipx()
613 Select_FlipTexture(false);
616 void CSurfaceDlg::OnBtnFlipy()
618 Select_FlipTexture(true);
621 void CSurfaceDlg::OnKillfocusRotate()
626 void CSurfaceDlg::OnSetfocusRotate()
628 focusControl = &m_wndRotateEdit;