forked from Mirrors/openclonk
262 lines
8.0 KiB
C++
262 lines
8.0 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
// file selection dialogs
|
|
|
|
#ifndef INC_C4FileSelDlg
|
|
#define INC_C4FileSelDlg
|
|
|
|
#include "gui/C4Gui.h"
|
|
#include "c4group/C4Components.h"
|
|
|
|
// callback handler for file selection dialog
|
|
class C4FileSel_BaseCB
|
|
{
|
|
public:
|
|
C4FileSel_BaseCB() = default;
|
|
virtual ~C4FileSel_BaseCB() = default;
|
|
|
|
public:
|
|
virtual void OnFileSelected(const char *szFilename) = 0;
|
|
};
|
|
|
|
template <class CB> class C4FileSel_CBEx : public C4FileSel_BaseCB
|
|
{
|
|
public:
|
|
typedef void (CB::*FileSelFunc)(const char *szFilename, int32_t idToken);
|
|
|
|
private:
|
|
CB *pCBClass;
|
|
FileSelFunc SelFunc;
|
|
int32_t idToken;
|
|
public:
|
|
void OnFileSelected(const char *szFilename) override
|
|
{ if (pCBClass && SelFunc) (pCBClass->*SelFunc)(szFilename, idToken); }
|
|
|
|
public:
|
|
C4FileSel_CBEx(CB * pCBClass, FileSelFunc SelFunc, int32_t idToken) : pCBClass(pCBClass), SelFunc(SelFunc), idToken(idToken) { }
|
|
};
|
|
|
|
// dialog to select one or more files
|
|
class C4FileSelDlg : public C4GUI::Dialog
|
|
{
|
|
public:
|
|
class ListItem : public C4GUI::Control
|
|
{
|
|
protected:
|
|
StdStrBuf sFilename; // full path to file
|
|
|
|
bool IsFocusOnClick() override { return false; } // do not focus; keep focus on listbox
|
|
|
|
public:
|
|
ListItem(const char *szFilename);
|
|
~ListItem() override;
|
|
|
|
const char *GetFilename() { return sFilename.getData(); }
|
|
|
|
// multisel-checkbox-options
|
|
virtual bool IsChecked() const { return false; }
|
|
virtual void SetChecked(bool fChecked) {}
|
|
virtual bool IsGrayed() const { return false; }
|
|
virtual bool UserToggleCheck() { return false; }
|
|
};
|
|
|
|
class DefaultListItem : public ListItem
|
|
{
|
|
private:
|
|
typedef ListItem BaseClass;
|
|
class C4GUI::Icon *pIco; class C4GUI::Label *pLbl;
|
|
class C4GUI::CheckBox *pCheck;
|
|
class C4KeyBinding *pKeyCheck; // space activates/deactivates selected file
|
|
bool fGrayed;
|
|
|
|
protected:
|
|
void UpdateOwnPos() override;
|
|
|
|
public:
|
|
DefaultListItem(const char *szFilename, bool fTruncateExtension, bool fCheckbox, bool fGrayed, C4GUI::Icons eIcon);
|
|
~DefaultListItem() override;
|
|
|
|
bool IsChecked() const override;
|
|
void SetChecked(bool fChecked) override;
|
|
bool IsGrayed() const override { return fGrayed; }
|
|
bool UserToggleCheck() override;
|
|
};
|
|
|
|
private:
|
|
typedef C4GUI::Dialog BaseClass;
|
|
|
|
C4KeyBinding *pKeyRefresh, *pKeyEnterOverride;
|
|
|
|
C4GUI::ComboBox *pLocationComboBox;
|
|
C4GUI::ListBox *pFileListBox;
|
|
C4GUI::TextWindow *pSelectionInfoBox;
|
|
C4GUI::Button *btnOK;
|
|
|
|
StdCopyStrBuf sTitle; // dlg title
|
|
|
|
StdCopyStrBuf sPath; // current path
|
|
struct Location
|
|
{
|
|
StdCopyStrBuf sName;
|
|
StdCopyStrBuf sPath;
|
|
};
|
|
Location *pLocations;
|
|
int32_t iLocationCount;
|
|
int32_t iCurrentLocationIndex;
|
|
|
|
|
|
ListItem *pSelection;
|
|
C4FileSel_BaseCB *pSelCallback;
|
|
|
|
void UpdateFileList(); // rebuild file listbox from sPath
|
|
|
|
protected:
|
|
void OnShown() override;
|
|
void UserClose(bool fOK) override; // allow OK only if something is sth is selected
|
|
void OnClosed(bool fOK) override; // callback when dlg got closed
|
|
|
|
virtual const char *GetFileMask() const { return nullptr; }
|
|
virtual bool IsMultiSelection() const { return false; } // if true, files are checked/unchecked using checkboxes
|
|
virtual bool IsItemGrayed(const char *szFilename) const { return false; }
|
|
virtual void UpdateSelection();
|
|
virtual bool HasNoneItem() const { return false; } // if true, an empty item can be selected
|
|
virtual bool HasPreviewArea() const { return true; }
|
|
virtual bool HasExtraOptions() const { return false; }
|
|
virtual void AddExtraOptions(const C4Rect &rcOptionsRect) {}
|
|
virtual C4GUI::Icons GetFileItemIcon() const { return C4GUI::Ico_None; }
|
|
virtual int32_t GetFileSelColWidth() const { return 0; } // width of each file selection element; 0 for default all listbox
|
|
|
|
void OnSelChange(class C4GUI::Element *pEl) { UpdateSelection(); }
|
|
void OnSelDblClick(class C4GUI::Element *pEl);
|
|
bool KeyRefresh() { UpdateFileList(); return true; }
|
|
void OnLocationComboFill(C4GUI::ComboBox_FillCB *pFiller);
|
|
bool OnLocationComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection);
|
|
|
|
void AddLocation(const char *szName, const char *szPath); // add location to be shown in dropdown list
|
|
void AddCheckedLocation(const char *szName, const char *szPath); // add location to be shown in dropdown list, only if path exists and isn't added yet
|
|
int32_t GetCurrentLocationIndex() const;
|
|
void SetCurrentLocation(int32_t idx, bool fRefresh);
|
|
|
|
virtual ListItem *CreateListItem(const char *szFilename);
|
|
virtual void BeginFileListUpdate() {}
|
|
virtual void EndFileListUpdate() {}
|
|
|
|
public:
|
|
C4FileSelDlg(const char *szRootPath, const char *szTitle, C4FileSel_BaseCB *pSelCallback, bool fInitElements=true);
|
|
~C4FileSelDlg() override;
|
|
void InitElements();
|
|
|
|
void SetPath(const char *szNewPath, bool fRefresh=true);
|
|
void SetSelection(const char *szNewSelection, bool fFilenameOnly);
|
|
StdStrBuf GetSelection(const char *szFixedSelection, bool fFilenameOnly) const; // get single selected file for single selection dlg ';'-separated list for multi selection dlg
|
|
};
|
|
|
|
// dialog to select a player file
|
|
class C4PlayerSelDlg : public C4FileSelDlg
|
|
{
|
|
protected:
|
|
const char *GetFileMask() const override { return C4CFN_PlayerFiles; }
|
|
C4GUI::Icons GetFileItemIcon() const override { return C4GUI::Ico_Player; }
|
|
|
|
public:
|
|
C4PlayerSelDlg(C4FileSel_BaseCB *pSelCallback);
|
|
};
|
|
|
|
// dialog to select definition files
|
|
class C4DefinitionSelDlg : public C4FileSelDlg
|
|
{
|
|
private:
|
|
StdStrBuf sFixedSelection; // initial selection which cannot be deselected
|
|
|
|
protected:
|
|
void OnShown() override;
|
|
const char *GetFileMask() const override { return C4CFN_DefFiles; }
|
|
bool IsMultiSelection() const override { return true; }
|
|
bool IsItemGrayed(const char *szFilename) const override;
|
|
C4GUI::Icons GetFileItemIcon() const override { return C4GUI::Ico_Definition; }
|
|
|
|
public:
|
|
C4DefinitionSelDlg(C4FileSel_BaseCB *pSelCallback, const char *szFixedSelection);
|
|
|
|
static bool SelectDefinitions(C4GUI::Screen *pOnScreen, StdStrBuf *pSelection);
|
|
};
|
|
|
|
// dialog to select portrait files
|
|
class C4PortraitSelDlg : public C4FileSelDlg
|
|
{
|
|
public:
|
|
enum { ImagePreviewSize = 100 };
|
|
|
|
private:
|
|
class ListItem : public C4FileSelDlg::ListItem
|
|
{
|
|
private:
|
|
bool fError; // loading error
|
|
bool fLoaded; // image loaded but not yet scaled
|
|
C4FacetSurface fctImage; // portrait, if loaded
|
|
C4FacetSurface fctLoadedImage; // image as loaded by background thread. Must be scaled by main thread
|
|
StdCopyStrBuf sFilenameLabelText;
|
|
|
|
protected:
|
|
void DrawElement(C4TargetFacet &cgo) override;
|
|
|
|
public:
|
|
ListItem(const char *szFilename);
|
|
|
|
void Load();
|
|
};
|
|
|
|
// portrait loader thread
|
|
class LoaderThread : public StdThread
|
|
{
|
|
private:
|
|
std::list<ListItem *> LoadItems; // items to be loaded by this thread
|
|
|
|
public:
|
|
LoaderThread() = default;
|
|
~LoaderThread() override { Stop(); }
|
|
|
|
void ClearLoadItems(); // stops thread
|
|
void AddLoadItem(ListItem *pItem); // not to be called when thread is running!
|
|
|
|
public:
|
|
void Execute() override;
|
|
};
|
|
|
|
private:
|
|
LoaderThread ImageLoader;
|
|
|
|
protected:
|
|
void OnClosed(bool fOK) override;
|
|
const char *GetFileMask() const override { return C4CFN_ImageFiles; }
|
|
bool HasNoneItem() const override { return true; } // if true, a special <none> item can be selected
|
|
bool HasPreviewArea() const override { return false; } // no preview area. Preview images directly
|
|
int32_t GetFileSelColWidth() const override { return ImagePreviewSize; } // width of each file selection element
|
|
|
|
C4FileSelDlg::ListItem *CreateListItem(const char *szFilename) override;
|
|
void BeginFileListUpdate() override;
|
|
void EndFileListUpdate() override;
|
|
|
|
void OnIdle() override;
|
|
|
|
public:
|
|
C4PortraitSelDlg(C4FileSel_BaseCB *pSelCallback);
|
|
|
|
static bool SelectPortrait(C4GUI::Screen *pOnScreen, StdStrBuf *pSelection);
|
|
};
|
|
|
|
#endif // INC_C4FileSelDlg
|