root/cafu/trunk/CaWE/DialogReplaceMaterials.cpp

Revision 455, 13.9 KB (checked in by Carsten, 4 months ago)

Updated copyright banners (in C++ files).

Line 
1/*
2=================================================================================
3This file is part of Cafu, the open-source game engine and graphics engine
4for multiplayer, cross-platform, real-time 3D action.
5Copyright (C) 2002-2012 Carsten Fuchs Software.
6
7Cafu is free software: you can redistribute it and/or modify it under the terms
8of the GNU General Public License as published by the Free Software Foundation,
9either version 3 of the License, or (at your option) any later version.
10
11Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with Cafu. If not, see <http://www.gnu.org/licenses/>.
17
18For support and more information about Cafu, visit us at <http://www.cafu.de>.
19=================================================================================
20*/
21
22#include "DialogReplaceMaterials.hpp"
23#include "AppCaWE.hpp"
24#include "GameConfig.hpp"
25#include "ParentFrame.hpp"
26#include "ChildFrame.hpp"
27#include "MapDocument.hpp"
28#include "CommandHistory.hpp"
29#include "EditorMaterial.hpp"
30#include "EditorMaterialManager.hpp"
31
32#include "MaterialBrowser/DocAccess.hpp"
33#include "MaterialBrowser/MaterialBrowserDialog.hpp"
34#include "MapCommands/ReplaceMat.hpp"
35#include "MapCommands/Select.hpp"
36
37#include "wx/image.h"
38
39
40static const int PREVIEW_BITMAP_SIZE=128;
41
42
43BEGIN_EVENT_TABLE(ReplaceMaterialsDialogT, wxDialog)
44    EVT_BUTTON(wxID_OK, ReplaceMaterialsDialogT::OnOK)
45    EVT_BUTTON(ReplaceMaterialsDialogT::ID_BUTTON_BROWSE_FIND, ReplaceMaterialsDialogT::OnButtonBrowseFind)
46    EVT_BUTTON(ReplaceMaterialsDialogT::ID_BUTTON_BROWSE_REPLACE, ReplaceMaterialsDialogT::OnButtonBrowseReplace)
47    EVT_CHECKBOX(ReplaceMaterialsDialogT::ID_CHECKBOX_FINDONLY, ReplaceMaterialsDialogT::OnCheckboxFindOnly)
48    EVT_RADIOBUTTON(ReplaceMaterialsDialogT::ID_RADIOBUTTON_SEARCH_IN_SELECTION, ReplaceMaterialsDialogT::OnRadioButtonSearchIn)
49    EVT_RADIOBUTTON(ReplaceMaterialsDialogT::ID_RADIOBUTTON_SEARCH_IN_WHOLEWORLD, ReplaceMaterialsDialogT::OnRadioButtonSearchIn)
50    EVT_TEXT(ReplaceMaterialsDialogT::ID_TEXTCTRL_FINDMATNAME, ReplaceMaterialsDialogT::OnTextUpdateFindMatName)
51    EVT_TEXT(ReplaceMaterialsDialogT::ID_TEXTCTRL_REPLACEMATNAME, ReplaceMaterialsDialogT::OnTextUpdateReplaceMatName)
52END_EVENT_TABLE()
53
54
55ReplaceMaterialsDialogT::ReplaceMaterialsDialogT(bool IsSomethingSelected, MapDocumentT& MapDoc, const wxString& InitialFindMatName)
56    : wxDialog(NULL, -1, wxString("Replace Materials"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
57      m_MapDoc(MapDoc),
58      TextCtrlFindMatName(NULL),
59      TextCtrlReplaceMatName(NULL),
60      RadioButtonSearchInSelection(NULL),
61      RadioButtonSearchInWholeWorld(NULL),
62      CheckBoxInclusiveBrushes(NULL),
63      CheckBoxInclusiveBPs(NULL),
64      CheckBoxInclusiveHidden(NULL),
65      RadioBoxSearchFor(NULL),
66      RadioBoxReplaceRescaleMode(NULL),
67      CheckBoxFindOnly(NULL),
68      m_BitmapFindMat(NULL),
69      m_BitmapReplaceMat(NULL),
70      StaticBoxReplace(NULL),
71      ButtonBrowseReplace(NULL)
72{
73    wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
74
75    wxStaticBox *item2 = new wxStaticBox(this, -1, wxT("Find") );
76    wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL );
77
78    wxBoxSizer *item3 = new wxBoxSizer( wxHORIZONTAL );
79
80    // Warning: Setting a non-empty default text here does cause a text update event,
81    // and thus an early call to the event handler that in turn will cause a crash, as we are still in mid-constructor!
82    TextCtrlFindMatName=new wxTextCtrl(this, ID_TEXTCTRL_FINDMATNAME, wxT(""), wxDefaultPosition, wxSize(80,-1), 0 );
83    item3->Add(TextCtrlFindMatName, 1, wxALIGN_CENTER|wxALL, 5 );
84
85    wxButton *item5 = new wxButton(this, ID_BUTTON_BROWSE_FIND, wxT("Browse"));
86    item3->Add( item5, 0, wxALIGN_CENTER|wxALL, 5 );
87
88    item1->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
89
90    wxBoxSizer *item6 = new wxBoxSizer( wxHORIZONTAL );
91
92    m_BitmapFindMat=new wxStaticBitmap(this, -1, wxBitmap(), wxDefaultPosition, wxSize(PREVIEW_BITMAP_SIZE, PREVIEW_BITMAP_SIZE), wxSUNKEN_BORDER);
93    item6->Add(m_BitmapFindMat, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
94
95    wxBoxSizer *item8 = new wxBoxSizer( wxVERTICAL );
96
97    wxStaticBox *item10 = new wxStaticBox(this, -1, wxT("Search in") );
98    wxStaticBoxSizer *item9 = new wxStaticBoxSizer( item10, wxVERTICAL );
99
100    RadioButtonSearchInSelection=new wxRadioButton(this, ID_RADIOBUTTON_SEARCH_IN_SELECTION, wxT("selected objects"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
101    RadioButtonSearchInSelection->SetValue(IsSomethingSelected);
102    item9->Add(RadioButtonSearchInSelection, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP, 5 );
103
104    RadioButtonSearchInWholeWorld=new wxRadioButton(this, ID_RADIOBUTTON_SEARCH_IN_WHOLEWORLD, wxT("all objects (whole world)"), wxDefaultPosition, wxDefaultSize, 0 );
105    RadioButtonSearchInWholeWorld->SetValue(!IsSomethingSelected);
106    item9->Add(RadioButtonSearchInWholeWorld, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP, 5 );
107
108    wxBoxSizer *item13 = new wxBoxSizer( wxVERTICAL );
109
110    CheckBoxInclusiveBrushes=new wxCheckBox(this, -1, wxT("inclusive brushes"), wxDefaultPosition, wxDefaultSize, 0 );
111    CheckBoxInclusiveBrushes->SetValue(true);
112    CheckBoxInclusiveBrushes->Enable(RadioButtonSearchInWholeWorld->GetValue());
113    item13->Add(CheckBoxInclusiveBrushes, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
114
115    CheckBoxInclusiveBPs=new wxCheckBox(this, -1, wxT("inclusive bezier patches"), wxDefaultPosition, wxDefaultSize, 0 );
116    CheckBoxInclusiveBPs->SetValue(true);
117    CheckBoxInclusiveBPs->Enable(RadioButtonSearchInWholeWorld->GetValue());
118    item13->Add(CheckBoxInclusiveBPs, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
119
120    CheckBoxInclusiveHidden=new wxCheckBox(this, -1, wxT("also in hidden groups"), wxDefaultPosition, wxDefaultSize, 0 );
121    CheckBoxInclusiveHidden->SetValue(false);
122    CheckBoxInclusiveHidden->Enable(RadioButtonSearchInWholeWorld->GetValue());
123    item13->Add(CheckBoxInclusiveHidden, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
124
125    item9->Add( item13, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 25 );
126
127    item8->Add( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
128
129    wxString strs17[] =
130    {
131        wxT("exact matches"),
132        wxT("partial matches")
133    };
134    RadioBoxSearchFor=new wxRadioBox(this, -1, wxT("Search for"), wxDefaultPosition, wxDefaultSize, 2, strs17, 1, wxRA_SPECIFY_COLS );
135    item8->Add(RadioBoxSearchFor, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
136
137    item6->Add( item8, 1, wxALIGN_CENTER, 5 );
138
139    item1->Add( item6, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
140
141    item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
142
143    CheckBoxFindOnly= new wxCheckBox(this, ID_CHECKBOX_FINDONLY, wxT("Find only (mark found faces, don't replace)"), wxDefaultPosition, wxDefaultSize, 0 );
144    item0->Add(CheckBoxFindOnly, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
145
146    StaticBoxReplace= new wxStaticBox(this, -1, wxT("Replace") );
147    wxStaticBoxSizer *item19 = new wxStaticBoxSizer(StaticBoxReplace, wxVERTICAL );
148
149    wxBoxSizer *item21 = new wxBoxSizer( wxHORIZONTAL );
150
151    // Warning: Setting a non-empty default text here does cause a text update event,
152    // and thus an early call to the event handler that in turn will cause a crash, as we are still in mid-constructor!
153    TextCtrlReplaceMatName= new wxTextCtrl(this, ID_TEXTCTRL_REPLACEMATNAME, wxT(""), wxDefaultPosition, wxSize(80,-1), 0 );
154    item21->Add(TextCtrlReplaceMatName, 1, wxALIGN_CENTER|wxALL, 5 );
155
156    ButtonBrowseReplace= new wxButton(this, ID_BUTTON_BROWSE_REPLACE, wxT("Browse"));
157    item21->Add(ButtonBrowseReplace, 0, wxALIGN_CENTER|wxALL, 5 );
158
159    item19->Add( item21, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
160
161    wxBoxSizer *item24 = new wxBoxSizer( wxHORIZONTAL );
162
163    m_BitmapReplaceMat=new wxStaticBitmap(this, -1, wxBitmap(), wxDefaultPosition, wxSize(PREVIEW_BITMAP_SIZE, PREVIEW_BITMAP_SIZE), wxSUNKEN_BORDER);
164    item24->Add(m_BitmapReplaceMat, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
165
166    wxString strs26[] =
167    {
168        wxT("do rescale (texture is repeated/tiled as often as before)"),
169        wxT("do not rescale (pixels don't change their size)")
170    };
171    RadioBoxReplaceRescaleMode= new wxRadioBox(this, -1, wxT("Replace and"), wxDefaultPosition, wxDefaultSize, 2, strs26, 1, wxRA_SPECIFY_COLS );
172    RadioBoxReplaceRescaleMode->Disable();
173    item24->Add(RadioBoxReplaceRescaleMode, 1, wxALIGN_TOP|wxALL, 5 );
174
175    item19->Add( item24, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
176
177    item0->Add( item19, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
178
179    wxStaticText *item27 = new wxStaticText(this, -1,
180        wxT("Hint: You may also replace materials by loading the cmap\n")
181        wxT("file into a text editor and use the search and replace function there.\n")
182        wxT("Only recommended for experts, and only after a backup!"),
183        wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
184    item0->Add( item27, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
185
186    wxBoxSizer *item28 = new wxBoxSizer( wxHORIZONTAL );
187
188    wxButton *item29 = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
189    item29->SetDefault();
190    item28->Add( item29, 0, wxALIGN_CENTER|wxALL, 5 );
191
192    wxButton *item30 = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
193    item28->Add( item30, 0, wxALIGN_CENTER|wxALL, 5 );
194
195    item0->Add( item28, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
196
197    this->SetSizer( item0 );
198    item0->SetSizeHints( this );
199
200
201    // This does also trigger a text update event (and thus a function call to OnTextUpdateFindMatName()).
202    TextCtrlFindMatName->SetValue(InitialFindMatName);
203}
204
205
206void ReplaceMaterialsDialogT::OnOK(wxCommandEvent& Event)
207{
208    // Clear selection before marking new stuff.
209    if (CheckBoxFindOnly->IsChecked()) m_MapDoc.GetHistory().SubmitCommand(CommandSelectT::Clear(&m_MapDoc));
210
211    // CF: The big TODO question with this dialog is:
212    // If I select something, and then hide it in a group, is it still selected?
213    CommandReplaceMatT* Command=new CommandReplaceMatT(
214        m_MapDoc,
215        m_MapDoc.GetSelection(),
216        TextCtrlFindMatName->GetValue(),
217        TextCtrlReplaceMatName->GetValue(),
218        CommandReplaceMatT::ReplaceActionT(RadioBoxSearchFor->GetSelection()),
219        CheckBoxFindOnly->IsChecked(),
220        RadioButtonSearchInSelection->GetValue(), // Search in selection? Or everywhere (whole world)?
221        CheckBoxInclusiveBrushes->IsChecked(),    // Include brushes?
222        CheckBoxInclusiveBPs->IsChecked(),        // Include bezier patches?
223        CheckBoxInclusiveHidden->IsChecked());    // Search for hidden if "all objects (inclusive hidden objects)" is selected.
224
225    m_MapDoc.GetHistory().SubmitCommand(Command);
226    wxMessageBox(Command->GetResultString());
227
228    // Tell wxWidgets to continue processing the default behavior for wxID_OK
229    // (which is to call all wxValidators, handle any data transfer with those validators, and close the dialog).
230    Event.Skip();
231}
232
233
234void ReplaceMaterialsDialogT::OnButtonBrowseFind(wxCommandEvent& Event)
235{
236    MaterialBrowser::DialogT MatBrowser(this, MaterialBrowser::MapDocAccessT(m_MapDoc), MaterialBrowser::ConfigT()
237        .InitialMaterial(m_MapDoc.GetGameConfig()->GetMatMan().FindMaterial(TextCtrlFindMatName->GetValue(), false))
238        .OnlyShowUsed());
239
240    if (MatBrowser.ShowModal()==wxID_OK)
241        TextCtrlFindMatName->SetValue(MatBrowser.GetCurrentMaterial()!=NULL ? MatBrowser.GetCurrentMaterial()->GetName() : "");
242}
243
244
245void ReplaceMaterialsDialogT::OnButtonBrowseReplace(wxCommandEvent& Event)
246{
247    MaterialBrowser::DialogT MatBrowser(this, MaterialBrowser::MapDocAccessT(m_MapDoc), MaterialBrowser::ConfigT()
248        .InitialMaterial(m_MapDoc.GetGameConfig()->GetMatMan().FindMaterial(TextCtrlReplaceMatName->GetValue(), false)));
249
250    if (MatBrowser.ShowModal()==wxID_OK)
251        TextCtrlReplaceMatName->SetValue(MatBrowser.GetCurrentMaterial()!=NULL ? MatBrowser.GetCurrentMaterial()->GetName() : "");
252}
253
254
255void ReplaceMaterialsDialogT::OnCheckboxFindOnly(wxCommandEvent& Event)
256{
257    StaticBoxReplace      ->Enable(!Event.IsChecked());
258    TextCtrlReplaceMatName->Enable(!Event.IsChecked());
259    ButtonBrowseReplace   ->Enable(!Event.IsChecked());
260 // StaticBoxReplace      ->Enable(!Event.IsChecked());
261}
262
263
264static wxBitmap GetScaledBitmapFromMaterial(EditorMaterialI* MaterialPtr)
265{
266    if (MaterialPtr==NULL) return wxNullBitmap;
267
268    const int w  =MaterialPtr->GetWidth ();
269    const int h  =MaterialPtr->GetHeight();
270    const int Max=w>h ? w : h;
271
272    if (w<=PREVIEW_BITMAP_SIZE && h<=PREVIEW_BITMAP_SIZE) return wxBitmap(MaterialPtr->GetImage());
273
274    return wxBitmap(MaterialPtr->GetImage().Scale(w*PREVIEW_BITMAP_SIZE/Max, h*PREVIEW_BITMAP_SIZE/Max));
275}
276
277
278void ReplaceMaterialsDialogT::OnRadioButtonSearchIn(wxCommandEvent& Event)
279{
280    CheckBoxInclusiveBrushes->Enable(Event.GetId()==ID_RADIOBUTTON_SEARCH_IN_WHOLEWORLD);
281    CheckBoxInclusiveBPs    ->Enable(Event.GetId()==ID_RADIOBUTTON_SEARCH_IN_WHOLEWORLD);
282    CheckBoxInclusiveHidden ->Enable(Event.GetId()==ID_RADIOBUTTON_SEARCH_IN_WHOLEWORLD);
283}
284
285
286void ReplaceMaterialsDialogT::OnTextUpdateFindMatName(wxCommandEvent& Event)
287{
288    m_BitmapFindMat->SetBitmap(GetScaledBitmapFromMaterial(m_MapDoc.GetGameConfig()->GetMatMan().FindMaterial(TextCtrlFindMatName->GetValue(), false)));
289    m_BitmapFindMat->Refresh();
290}
291
292
293void ReplaceMaterialsDialogT::OnTextUpdateReplaceMatName(wxCommandEvent& Event)
294{
295    m_BitmapReplaceMat->SetBitmap(GetScaledBitmapFromMaterial(m_MapDoc.GetGameConfig()->GetMatMan().FindMaterial(TextCtrlReplaceMatName->GetValue(), false)));
296    m_BitmapReplaceMat->Refresh();
297}
Note: See TracBrowser for help on using the browser.