1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "ViewPreferencePane.h" 21 22 #include "StringUtils.h" 23 #include "PreferenceManager.h" 24 #include "Preferences.h" 25 #include "View/BorderLine.h" 26 #include "View/TitleBar.h" 27 #include "View/ViewConstants.h" 28 #include "View/wxUtils.h" 29 30 #include "Renderer/GL.h" 31 32 #include <wx/checkbox.h> 33 #include <wx/choice.h> 34 #include <wx/clrpicker.h> 35 #include <wx/gbsizer.h> 36 #include <wx/sizer.h> 37 #include <wx/slider.h> 38 #include <wx/stattext.h> 39 40 namespace TrenchBroom { 41 namespace View { 42 struct TextureMode { 43 int minFilter; 44 int magFilter; 45 String name; 46 TextureModeTrenchBroom::View::TextureMode47 TextureMode(const int i_minFilter, const int i_magFilter, const String& i_name) : 48 minFilter(i_minFilter), 49 magFilter(i_magFilter), 50 name(i_name) {} 51 }; 52 53 static const size_t NumTextureModes = 6; 54 static const TextureMode TextureModes[] = { 55 TextureMode(GL_NEAREST, GL_NEAREST, "Nearest"), 56 TextureMode(GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, "Nearest (mipmapped)"), 57 TextureMode(GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST, "Nearest (mipmaps, interpolated)"), 58 TextureMode(GL_LINEAR, GL_LINEAR, "Linear"), 59 TextureMode(GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, "Linear (mipmapped)"), 60 TextureMode(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, "Linear (mipmapped, interpolated") 61 }; 62 63 static const size_t NumFrameLayouts = 4; 64 ViewPreferencePane(wxWindow * parent)65 ViewPreferencePane::ViewPreferencePane(wxWindow* parent) : 66 PreferencePane(parent) { 67 createGui(); 68 bindEvents(); 69 } 70 71 OnLayoutChanged(wxCommandEvent & event)72 void ViewPreferencePane::OnLayoutChanged(wxCommandEvent& event) { 73 if (IsBeingDeleted()) return; 74 75 const int selection = m_layoutChoice->GetSelection(); 76 assert(selection >= 0 && selection < static_cast<int>(NumFrameLayouts)); 77 78 PreferenceManager& prefs = PreferenceManager::instance(); 79 prefs.set(Preferences::MapViewLayout, selection); 80 } 81 OnBrightnessChanged(wxScrollEvent & event)82 void ViewPreferencePane::OnBrightnessChanged(wxScrollEvent& event) { 83 if (IsBeingDeleted()) return; 84 85 const int value = m_brightnessSlider->GetValue(); 86 87 PreferenceManager& prefs = PreferenceManager::instance(); 88 prefs.set(Preferences::Brightness, value / 40.0f); 89 } 90 OnGridAlphaChanged(wxScrollEvent & event)91 void ViewPreferencePane::OnGridAlphaChanged(wxScrollEvent& event) { 92 if (IsBeingDeleted()) return; 93 94 const int value = m_gridAlphaSlider->GetValue(); 95 96 PreferenceManager& prefs = PreferenceManager::instance(); 97 const int max = m_gridAlphaSlider->GetMax(); 98 const float floatValue = static_cast<float>(value) / static_cast<float>(max); 99 prefs.set(Preferences::GridAlpha, floatValue); 100 } 101 OnBackgroundColorChanged(wxColourPickerEvent & event)102 void ViewPreferencePane::OnBackgroundColorChanged(wxColourPickerEvent& event) { 103 if (IsBeingDeleted()) return; 104 105 const Color value(fromWxColor(event.GetColour()), 1.0f); 106 107 PreferenceManager& prefs = PreferenceManager::instance(); 108 prefs.set(Preferences::BackgroundColor, value); 109 } 110 OnShowAxesChanged(wxCommandEvent & event)111 void ViewPreferencePane::OnShowAxesChanged(wxCommandEvent& event) { 112 if (IsBeingDeleted()) return; 113 114 const bool value = event.IsChecked(); 115 116 PreferenceManager& prefs = PreferenceManager::instance(); 117 prefs.set(Preferences::ShowAxes, value); 118 } 119 OnTextureModeChanged(wxCommandEvent & event)120 void ViewPreferencePane::OnTextureModeChanged(wxCommandEvent& event) { 121 if (IsBeingDeleted()) return; 122 123 const int selection = m_textureModeChoice->GetSelection(); 124 assert(selection >= 0); 125 126 const size_t index = static_cast<size_t>(selection); 127 assert(index < NumTextureModes); 128 const int minFilter = TextureModes[index].minFilter; 129 const int magFilter = TextureModes[index].magFilter; 130 131 PreferenceManager& prefs = PreferenceManager::instance(); 132 prefs.set(Preferences::TextureMinFilter, minFilter); 133 prefs.set(Preferences::TextureMagFilter, magFilter); 134 } 135 OnTextureBrowserIconSizeChanged(wxCommandEvent & event)136 void ViewPreferencePane::OnTextureBrowserIconSizeChanged(wxCommandEvent& event) { 137 if (IsBeingDeleted()) return; 138 139 PreferenceManager& prefs = PreferenceManager::instance(); 140 141 const int selection = m_textureBrowserIconSizeChoice->GetSelection(); 142 switch (selection) { 143 case 0: 144 prefs.set(Preferences::TextureBrowserIconSize, 0.25f); 145 break; 146 case 1: 147 prefs.set(Preferences::TextureBrowserIconSize, 0.5f); 148 break; 149 case 2: 150 prefs.set(Preferences::TextureBrowserIconSize, 1.0f); 151 break; 152 case 3: 153 prefs.set(Preferences::TextureBrowserIconSize, 1.5f); 154 break; 155 case 4: 156 prefs.set(Preferences::TextureBrowserIconSize, 2.0f); 157 break; 158 case 5: 159 prefs.set(Preferences::TextureBrowserIconSize, 2.5f); 160 break; 161 case 6: 162 prefs.set(Preferences::TextureBrowserIconSize, 3.0f); 163 break; 164 } 165 } 166 createGui()167 void ViewPreferencePane::createGui() { 168 wxWindow* viewPreferences = createViewPreferences(); 169 170 wxSizer* sizer = new wxBoxSizer(wxVERTICAL); 171 sizer->AddSpacer(LayoutConstants::NarrowVMargin); 172 sizer->Add(viewPreferences, 1, wxEXPAND); 173 sizer->AddSpacer(LayoutConstants::WideVMargin); 174 175 SetMinSize(sizer->GetMinSize()); 176 SetSizer(sizer); 177 178 SetBackgroundColour(*wxWHITE); 179 } 180 createViewPreferences()181 wxWindow* ViewPreferencePane::createViewPreferences() { 182 wxPanel* viewBox = new wxPanel(this); 183 viewBox->SetBackgroundColour(*wxWHITE); 184 185 wxStaticText* viewPrefsHeader = new wxStaticText(viewBox, wxID_ANY, "Map Views"); 186 viewPrefsHeader->SetFont(viewPrefsHeader->GetFont().Bold()); 187 188 wxString layoutNames[NumFrameLayouts]; 189 layoutNames[0] = "One Pane"; 190 layoutNames[1] = "Two Panes"; 191 layoutNames[2] = "Three Panes"; 192 layoutNames[3] = "Four Panes"; 193 194 wxStaticText* layoutLabel = new wxStaticText(viewBox, wxID_ANY, "Layout"); 195 m_layoutChoice = new wxChoice(viewBox, wxID_ANY, wxDefaultPosition, wxDefaultSize, NumFrameLayouts, layoutNames); 196 197 wxStaticText* brightnessLabel = new wxStaticText(viewBox, wxID_ANY, "Brightness"); 198 m_brightnessSlider = new wxSlider(viewBox, wxID_ANY, 50, 1, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_BOTTOM); 199 wxStaticText* gridLabel = new wxStaticText(viewBox, wxID_ANY, "Grid"); 200 m_gridAlphaSlider = new wxSlider(viewBox, wxID_ANY, 50, 1, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_BOTTOM); 201 202 wxStaticText* backgroundColorLabel = new wxStaticText(viewBox, wxID_ANY, "Background Color"); 203 m_backgroundColorPicker = new wxColourPickerCtrl(viewBox, wxID_ANY); 204 205 wxStaticText* axesLabel = new wxStaticText(viewBox, wxID_ANY, "Coordinate System"); 206 m_showAxes = new wxCheckBox(viewBox, wxID_ANY, "Show Axes"); 207 208 wxString textureModeNames[NumTextureModes]; 209 for (size_t i = 0; i < NumTextureModes; ++i) 210 textureModeNames[i] = TextureModes[i].name; 211 wxStaticText* textureModeLabel = new wxStaticText(viewBox, wxID_ANY, "Texture Mode"); 212 m_textureModeChoice = new wxChoice(viewBox, wxID_ANY, wxDefaultPosition, wxDefaultSize, NumTextureModes, textureModeNames); 213 214 wxStaticText* textureBrowserPrefsHeader = new wxStaticText(viewBox, wxID_ANY, "Texture Browser"); 215 textureBrowserPrefsHeader->SetFont(textureBrowserPrefsHeader->GetFont().Bold()); 216 217 wxStaticText* textureBrowserIconSizeLabel = new wxStaticText(viewBox, wxID_ANY, "Icon Size"); 218 wxString iconSizes[7] = {"25%", "50%", "100%", "150%", "200%", "250%", "300%"}; 219 m_textureBrowserIconSizeChoice = new wxChoice(viewBox, wxID_ANY, wxDefaultPosition, wxDefaultSize, 7, iconSizes); 220 m_textureBrowserIconSizeChoice->SetToolTip("Sets the icon size in the texture browser."); 221 222 223 const int HMargin = LayoutConstants::WideHMargin; 224 const int LMargin = LayoutConstants::WideVMargin; 225 const int HeaderFlags = wxLEFT; 226 const int LabelFlags = wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxLEFT; 227 const int SliderFlags = wxEXPAND | wxRIGHT; 228 const int ChoiceFlags = wxRIGHT; 229 const int CheckBoxFlags = wxLeft; 230 const int ColorPickerFlags = wxRIGHT; 231 const int LineFlags = wxEXPAND | wxTOP; 232 233 int r = 0; 234 235 wxGridBagSizer* sizer = new wxGridBagSizer(LayoutConstants::NarrowVMargin, LayoutConstants::WideHMargin); 236 sizer->Add(viewPrefsHeader, wxGBPosition( r, 0), wxGBSpan(1,2), HeaderFlags, HMargin); 237 ++r; 238 239 sizer->Add(layoutLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 240 sizer->Add(m_layoutChoice, wxGBPosition( r, 1), wxDefaultSpan, ChoiceFlags, HMargin); 241 ++r; 242 243 sizer->Add(brightnessLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 244 sizer->Add(m_brightnessSlider, wxGBPosition( r, 1), wxDefaultSpan, SliderFlags, HMargin); 245 ++r; 246 247 sizer->Add(gridLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 248 sizer->Add(m_gridAlphaSlider, wxGBPosition( r, 1), wxDefaultSpan, SliderFlags, HMargin); 249 ++r; 250 251 sizer->Add(axesLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 252 sizer->Add(m_showAxes, wxGBPosition( r, 1), wxDefaultSpan, CheckBoxFlags, HMargin); 253 ++r; 254 255 sizer->Add(backgroundColorLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 256 sizer->Add(m_backgroundColorPicker, wxGBPosition( r, 1), wxDefaultSpan, ColorPickerFlags, HMargin); 257 ++r; 258 259 sizer->Add(textureModeLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 260 sizer->Add(m_textureModeChoice, wxGBPosition( r, 1), wxDefaultSpan, ChoiceFlags, HMargin); 261 ++r; 262 263 sizer->Add(0, LayoutConstants::ChoiceSizeDelta, wxGBPosition( r, 0), wxGBSpan(1,2)); 264 ++r; 265 266 sizer->Add(new BorderLine(viewBox), wxGBPosition( r, 0), wxGBSpan(1,2), LineFlags, LMargin); 267 ++r; 268 269 sizer->Add(textureBrowserPrefsHeader, wxGBPosition( r, 0), wxGBSpan(1,2), HeaderFlags, HMargin); 270 ++r; 271 272 sizer->Add(textureBrowserIconSizeLabel, wxGBPosition( r, 0), wxDefaultSpan, LabelFlags, HMargin); 273 sizer->Add(m_textureBrowserIconSizeChoice, wxGBPosition( r, 1), wxDefaultSpan, ChoiceFlags, HMargin); 274 ++r; 275 276 sizer->Add(0, LayoutConstants::ChoiceSizeDelta, wxGBPosition( r, 0), wxGBSpan(1,2)); 277 278 sizer->AddGrowableCol(1); 279 sizer->SetMinSize(500, wxDefaultCoord); 280 viewBox->SetSizer(sizer); 281 return viewBox; 282 } 283 bindEvents()284 void ViewPreferencePane::bindEvents() { 285 m_layoutChoice->Bind(wxEVT_CHOICE, &ViewPreferencePane::OnLayoutChanged, this); 286 287 bindSliderEvents(m_brightnessSlider, &ViewPreferencePane::OnBrightnessChanged, this); 288 bindSliderEvents(m_gridAlphaSlider, &ViewPreferencePane::OnGridAlphaChanged, this); 289 290 m_backgroundColorPicker->Bind(wxEVT_COLOURPICKER_CHANGED, &ViewPreferencePane::OnBackgroundColorChanged, this); 291 m_showAxes->Bind(wxEVT_CHECKBOX, &ViewPreferencePane::OnShowAxesChanged, this); 292 293 m_textureModeChoice->Bind(wxEVT_CHOICE, &ViewPreferencePane::OnTextureModeChanged, this); 294 m_textureBrowserIconSizeChoice->Bind(wxEVT_CHOICE, &ViewPreferencePane::OnTextureBrowserIconSizeChanged, this); 295 } 296 doCanResetToDefaults()297 bool ViewPreferencePane::doCanResetToDefaults() { 298 return true; 299 } 300 doResetToDefaults()301 void ViewPreferencePane::doResetToDefaults() { 302 PreferenceManager& prefs = PreferenceManager::instance(); 303 prefs.resetToDefault(Preferences::Brightness); 304 prefs.resetToDefault(Preferences::GridAlpha); 305 prefs.resetToDefault(Preferences::BackgroundColor); 306 prefs.resetToDefault(Preferences::ShowAxes); 307 prefs.resetToDefault(Preferences::TextureMinFilter); 308 prefs.resetToDefault(Preferences::TextureMagFilter); 309 prefs.resetToDefault(Preferences::TextureBrowserIconSize); 310 } 311 doUpdateControls()312 void ViewPreferencePane::doUpdateControls() { 313 m_layoutChoice->SetSelection(pref(Preferences::MapViewLayout)); 314 315 m_brightnessSlider->SetValue(static_cast<int>(pref(Preferences::Brightness) * 40.0f)); 316 m_gridAlphaSlider->SetValue(static_cast<int>(pref(Preferences::GridAlpha) * m_gridAlphaSlider->GetMax())); 317 318 m_backgroundColorPicker->SetColour(toWxColor(pref(Preferences::BackgroundColor))); 319 m_showAxes->SetValue(pref(Preferences::ShowAxes)); 320 321 const size_t textureModeIndex = findTextureMode(pref(Preferences::TextureMinFilter), pref(Preferences::TextureMagFilter)); 322 assert(textureModeIndex < NumTextureModes); 323 m_textureModeChoice->SetSelection(static_cast<int>(textureModeIndex)); 324 325 const float textureBrowserIconSize = pref(Preferences::TextureBrowserIconSize); 326 if (textureBrowserIconSize == 0.25f) 327 m_textureBrowserIconSizeChoice->SetSelection(0); 328 else if (textureBrowserIconSize == 0.5f) 329 m_textureBrowserIconSizeChoice->SetSelection(1); 330 else if (textureBrowserIconSize == 1.5f) 331 m_textureBrowserIconSizeChoice->SetSelection(3); 332 else if (textureBrowserIconSize == 2.0f) 333 m_textureBrowserIconSizeChoice->SetSelection(4); 334 else if (textureBrowserIconSize == 2.5f) 335 m_textureBrowserIconSizeChoice->SetSelection(5); 336 else if (textureBrowserIconSize == 3.0f) 337 m_textureBrowserIconSizeChoice->SetSelection(6); 338 else 339 m_textureBrowserIconSizeChoice->SetSelection(2); 340 } 341 doValidate()342 bool ViewPreferencePane::doValidate() { 343 return true; 344 } 345 findTextureMode(const int minFilter,const int magFilter) const346 size_t ViewPreferencePane::findTextureMode(const int minFilter, const int magFilter) const { 347 for (size_t i = 0; i < NumTextureModes; ++i) 348 if (TextureModes[i].minFilter == minFilter && 349 TextureModes[i].magFilter == magFilter) 350 return i; 351 return NumTextureModes; 352 } 353 } 354 } 355