Skip to content

Commit 15419af

Browse files
authored
Merge pull request #60 from klaussilveira/feat/gallery-view
Added thumbnail browser to Media panel
2 parents 2d7f452 + fe95ac5 commit 15419af

2 files changed

Lines changed: 196 additions & 4 deletions

File tree

radiant/ui/mediabrowser/MediaBrowser.cpp

Lines changed: 167 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@
55
#include "ideclmanager.h"
66
#include "imap.h"
77
#include "ishaders.h"
8+
#include "icommandsystem.h"
89
#include "ishaderclipboard.h"
910

1011
#include "wxutil/dataview/ResourceTreeViewToolbar.h"
12+
#include "wxutil/Bitmap.h"
1113

1214
#include <wx/sizer.h>
15+
#include <wx/tglbtn.h>
16+
#include <wx/checkbox.h>
1317
#include <wx/app.h>
1418
#include <wx/popupwin.h>
1519

1620
#include "util/ScopedBoolLock.h"
21+
#include "registry/registry.h"
1722
#include "ui/texturebrowser/TextureBrowserManager.h"
1823
#include "ui/common/TexturePreviewCombo.h"
24+
#include "ui/materials/MaterialThumbnailBrowser.h"
1925

2026
#include "FocusMaterialRequest.h"
2127
#include "ui/UserInterfaceModule.h"
@@ -26,10 +32,19 @@
2632
namespace ui
2733
{
2834

35+
namespace
36+
{
37+
constexpr const char* const RKEY_MEDIABROWSER_VIEW_MODE = "user/ui/mediaBrowser/viewMode";
38+
}
39+
2940
MediaBrowser::MediaBrowser(wxWindow* parent) :
3041
DockablePanel(parent),
3142
_treeView(nullptr),
3243
_preview(nullptr),
44+
_thumbnailBrowser(nullptr),
45+
_viewToggleBtn(nullptr),
46+
_uniformScaleCheckbox(nullptr),
47+
_showingThumbnails(false),
3348
_blockShaderClipboardUpdates(false),
3449
_reloadTreeOnIdle(false),
3550
_showThumbnailBrowserOnIdle(false)
@@ -42,6 +57,13 @@ MediaBrowser::MediaBrowser(wxWindow* parent) :
4257

4358
MediaBrowser::~MediaBrowser()
4459
{
60+
GlobalRegistry().set(RKEY_MEDIABROWSER_VIEW_MODE,
61+
_showingThumbnails ? "thumbnails" : "tree");
62+
63+
_thumbnailSelectionConn.disconnect();
64+
_thumbnailActivatedConn.disconnect();
65+
_filterTextChangedConn.disconnect();
66+
4567
if (panelIsActive())
4668
{
4769
disconnectListeners();
@@ -188,6 +210,11 @@ void MediaBrowser::queueTreeReload()
188210
{
189211
requestIdleCallback();
190212
}
213+
214+
if (_thumbnailBrowser)
215+
{
216+
_thumbnailBrowser->queueUpdate();
217+
}
191218
}
192219

193220
void MediaBrowser::construct()
@@ -197,16 +224,31 @@ void MediaBrowser::construct()
197224
_treeView = new MediaBrowserTreeView(this);
198225
auto* toolbar = new wxutil::ResourceTreeViewToolbar(this, _treeView);
199226

227+
createViewToggleButton(toolbar);
228+
createUniformScaleCheckbox(toolbar);
229+
200230
GetSizer()->Add(toolbar, 0, wxALIGN_LEFT | wxEXPAND | wxALL, 6);
201231
GetSizer()->Add(_treeView, 1, wxEXPAND);
202232

203233
// Connect up the selection changed callback
204234
_treeView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MediaBrowser::_onTreeViewSelectionChanged, this);
205235

236+
_filterTextChangedConn = toolbar->signal_filterTextChanged().connect(
237+
sigc::mem_fun(this, &MediaBrowser::onFilterTextChanged));
238+
206239
// Add the info pane
207240
_preview = new TexturePreviewCombo(this);
208241
GetSizer()->Add(_preview, 0, wxEXPAND);
209242

243+
// Restore saved view mode
244+
std::string savedMode = GlobalRegistry().get(RKEY_MEDIABROWSER_VIEW_MODE);
245+
if (savedMode == "thumbnails")
246+
{
247+
_showingThumbnails = true;
248+
_viewToggleBtn->SetValue(true);
249+
switchView(true);
250+
}
251+
210252
// When destroying the main widget clear out the held references.
211253
// The dying populator thread might have posted a finished message which
212254
// runs into problems when the _treeView is still valid
@@ -236,12 +278,21 @@ void MediaBrowser::onMapEvent(IMap::MapEvent ev)
236278

237279
std::string MediaBrowser::getSelection()
238280
{
281+
if (_showingThumbnails && _thumbnailBrowser)
282+
{
283+
return _thumbnailBrowser->getSelectedShader();
284+
}
239285
return _treeView->GetSelectedDeclName();
240286
}
241287

242288
void MediaBrowser::setSelection(const std::string& selection)
243289
{
244290
_treeView->SetSelectedDeclName(selection);
291+
292+
if (_thumbnailBrowser)
293+
{
294+
_thumbnailBrowser->setSelectedShader(selection);
295+
}
245296
}
246297

247298
void MediaBrowser::onMaterialDefsLoaded()
@@ -262,6 +313,11 @@ void MediaBrowser::_onTreeViewSelectionChanged(wxDataViewEvent& ev)
262313
_preview->SetPreviewDeclName(getSelection());
263314
// Close any pending popups
264315
closePopup();
316+
317+
if (!_showingThumbnails && _thumbnailBrowser)
318+
{
319+
_thumbnailBrowser->setSelectedShader(_treeView->GetSelectedDeclName());
320+
}
265321
}
266322
else
267323
{
@@ -280,9 +336,11 @@ void MediaBrowser::sendSelectionToShaderClipboard()
280336

281337
util::ScopedBoolLock lock(_blockShaderClipboardUpdates);
282338

283-
if (!_treeView->IsDirectorySelected())
339+
std::string selection = getSelection();
340+
341+
if (!selection.empty())
284342
{
285-
GlobalShaderClipboard().setSourceShader(getSelection());
343+
GlobalShaderClipboard().setSourceShader(selection);
286344
}
287345
else
288346
{
@@ -314,4 +372,111 @@ void MediaBrowser::focusMaterial(FocusMaterialRequest& request)
314372
queueSelection(request.getRequestedMaterial());
315373
}
316374

375+
void MediaBrowser::createThumbnailBrowser()
376+
{
377+
_thumbnailBrowser = new MaterialThumbnailBrowser(this, MaterialThumbnailBrowser::TextureFilter::All);
378+
_thumbnailBrowser->Hide();
379+
380+
GetSizer()->Insert(2, _thumbnailBrowser, 1, wxEXPAND);
381+
382+
_thumbnailSelectionConn = _thumbnailBrowser->signal_selectionChanged().connect(
383+
sigc::mem_fun(this, &MediaBrowser::onThumbnailSelectionChanged));
384+
385+
_thumbnailActivatedConn = _thumbnailBrowser->signal_itemActivated().connect(
386+
sigc::mem_fun(this, &MediaBrowser::onThumbnailItemActivated));
387+
}
388+
389+
MaterialThumbnailBrowser* MediaBrowser::getOrCreateThumbnailBrowser()
390+
{
391+
if (!_thumbnailBrowser)
392+
{
393+
createThumbnailBrowser();
394+
}
395+
396+
return _thumbnailBrowser;
397+
}
398+
399+
void MediaBrowser::createViewToggleButton(wxutil::ResourceTreeViewToolbar* toolbar)
400+
{
401+
_viewToggleBtn = new wxBitmapToggleButton(toolbar, wxID_ANY,
402+
wxutil::GetLocalBitmap("bgimage16.png"));
403+
_viewToggleBtn->SetToolTip(_("Toggle between tree view and thumbnail grid view"));
404+
toolbar->GetRightSizer()->Add(_viewToggleBtn, wxSizerFlags().Border(wxLEFT, 6));
405+
_viewToggleBtn->Bind(wxEVT_TOGGLEBUTTON, &MediaBrowser::onViewToggle, this);
406+
}
407+
408+
void MediaBrowser::createUniformScaleCheckbox(wxutil::ResourceTreeViewToolbar* toolbar)
409+
{
410+
_uniformScaleCheckbox = new wxCheckBox(toolbar, wxID_ANY, _("Grid"));
411+
_uniformScaleCheckbox->SetValue(registry::getValue<bool>(RKEY_TEXTURE_USE_UNIFORM_SCALE));
412+
_uniformScaleCheckbox->Hide();
413+
toolbar->GetLeftSizer()->Add(_uniformScaleCheckbox, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 6);
414+
_uniformScaleCheckbox->Bind(wxEVT_CHECKBOX, &MediaBrowser::onUniformScaleToggle, this);
415+
}
416+
417+
void MediaBrowser::switchView(bool showThumbnails)
418+
{
419+
if (showThumbnails)
420+
{
421+
auto* browser = getOrCreateThumbnailBrowser();
422+
browser->setSelectedShader(_treeView->GetSelectedDeclName());
423+
_treeView->Hide();
424+
browser->Show();
425+
browser->queueUpdate();
426+
_uniformScaleCheckbox->Show();
427+
}
428+
else
429+
{
430+
if (_thumbnailBrowser)
431+
{
432+
std::string selectedShader = _thumbnailBrowser->getSelectedShader();
433+
if (!selectedShader.empty())
434+
{
435+
setSelection(selectedShader);
436+
}
437+
_thumbnailBrowser->Hide();
438+
}
439+
_treeView->Show();
440+
_uniformScaleCheckbox->Hide();
441+
}
442+
443+
_showingThumbnails = showThumbnails;
444+
Layout();
445+
}
446+
447+
void MediaBrowser::onViewToggle(wxCommandEvent& ev)
448+
{
449+
switchView(ev.IsChecked());
450+
}
451+
452+
void MediaBrowser::onUniformScaleToggle(wxCommandEvent& ev)
453+
{
454+
registry::setValue(RKEY_TEXTURE_USE_UNIFORM_SCALE, ev.IsChecked());
455+
}
456+
457+
void MediaBrowser::onThumbnailSelectionChanged()
458+
{
459+
std::string selected = _thumbnailBrowser->getSelectedShader();
460+
_preview->SetPreviewDeclName(selected);
461+
sendSelectionToShaderClipboard();
462+
}
463+
464+
void MediaBrowser::onThumbnailItemActivated()
465+
{
466+
std::string selection = _thumbnailBrowser->getSelectedShader();
467+
468+
if (!selection.empty())
469+
{
470+
GlobalCommandSystem().executeCommand("SetShaderOnSelection", selection);
471+
}
472+
}
473+
474+
void MediaBrowser::onFilterTextChanged(const std::string& filterText)
475+
{
476+
if (_thumbnailBrowser)
477+
{
478+
_thumbnailBrowser->setExternalFilterText(filterText);
479+
}
480+
}
481+
317482
} // namespace

radiant/ui/mediabrowser/MediaBrowser.h

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,35 @@
99
#include "wxutil/DockablePanel.h"
1010
#include "wxutil/event/SingleIdleCallback.h"
1111

12-
namespace wxutil { class TransientPopupWindow; }
12+
namespace wxutil
13+
{
14+
class TransientPopupWindow;
15+
class ResourceTreeViewToolbar;
16+
}
1317

1418
class wxWindow;
1519
class wxTreeCtrl;
1620
class wxFrame;
1721
class wxDataViewTreeStore;
1822
class wxTreeEvent;
1923
class wxRadioButton;
24+
class wxBitmapToggleButton;
25+
class wxCheckBox;
2026

2127
namespace ui
2228
{
2329

2430
class FocusMaterialRequest;
2531
class TexturePreviewCombo;
32+
class MaterialThumbnailBrowser;
2633

2734
/**
2835
* \brief Media Browser control
2936
*
3037
* This control allows browsing of individual textures by name and loading them
3138
* into the texture window or applying directly to map geometry.
3239
*/
33-
class MediaBrowser :
40+
class MediaBrowser :
3441
public wxutil::DockablePanel,
3542
public wxutil::SingleIdleCallback
3643
{
@@ -40,10 +47,19 @@ class MediaBrowser :
4047
// Texture preview combo (GL widget and info table)
4148
TexturePreviewCombo* _preview;
4249

50+
// Thumbnail grid browser
51+
MaterialThumbnailBrowser* _thumbnailBrowser;
52+
wxBitmapToggleButton* _viewToggleBtn;
53+
wxCheckBox* _uniformScaleCheckbox;
54+
bool _showingThumbnails;
55+
4356
sigc::connection _materialDefsLoaded;
4457
sigc::connection _materialDefsUnloaded;
4558
sigc::connection _shaderClipboardConn;
4659
sigc::connection _mapLoadedConn;
60+
sigc::connection _thumbnailSelectionConn;
61+
sigc::connection _thumbnailActivatedConn;
62+
sigc::connection _filterTextChangedConn;
4763

4864
bool _blockShaderClipboardUpdates;
4965
bool _reloadTreeOnIdle;
@@ -96,6 +112,17 @@ class MediaBrowser :
96112
void sendSelectionToShaderClipboard();
97113
wxutil::TransientPopupWindow* findOrCreateBrowserPopup();
98114
void closePopup();
115+
116+
void createThumbnailBrowser();
117+
MaterialThumbnailBrowser* getOrCreateThumbnailBrowser();
118+
void createViewToggleButton(wxutil::ResourceTreeViewToolbar* toolbar);
119+
void switchView(bool showThumbnails);
120+
void onViewToggle(wxCommandEvent& ev);
121+
void onUniformScaleToggle(wxCommandEvent& ev);
122+
void createUniformScaleCheckbox(wxutil::ResourceTreeViewToolbar* toolbar);
123+
void onThumbnailSelectionChanged();
124+
void onThumbnailItemActivated();
125+
void onFilterTextChanged(const std::string& filterText);
99126
};
100127

101128
}

0 commit comments

Comments
 (0)