1 //============================================================================
2 //
3 //   SSSS    tt          lll  lll
4 //  SS  SS   tt           ll   ll
5 //  SS     tttttt  eeee   ll   ll   aaaa
6 //   SSSS    tt   ee  ee  ll   ll      aa
7 //      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
8 //  SS  SS   tt   ee      ll   ll  aa  aa
9 //   SSSS     ttt  eeeee llll llll  aaaaa
10 //
11 // Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
12 // and the Stella Team
13 //
14 // See the file "License.txt" for information on usage and redistribution of
15 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 //============================================================================
17 
18 #ifndef BROWSER_DIALOG_HXX
19 #define BROWSER_DIALOG_HXX
20 
21 class GuiObject;
22 class ButtonWidget;
23 class EditTextWidget;
24 class FileListWidget;
25 class StaticTextWidget;
26 
27 #include "Dialog.hxx"
28 #include "Command.hxx"
29 #include "FSNode.hxx"
30 #include "bspf.hxx"
31 
32 class BrowserDialog : public Dialog
33 {
34   public:
35     enum class Mode {
36       FileLoad,   // File selector, no input from user
37       FileSave,   // File selector, filename changable by user
38       Directories // Directories only, no input from user
39     };
40 
41     /** Function which is run when the user clicks OK or Cancel.
42         Boolean parameter is passed as 'true' when OK is clicked, else 'false'.
43         FilesystemNode parameter is what is currently selected in the browser.
44     */
45     using Command = std::function<void(bool, const FilesystemNode&)>;
46 
47   public:
48     // NOTE: Do not call this c'tor directly!  Use the static show method below
49     //       There is no point in doing so, since the result can't be returned
50     BrowserDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h);
51     ~BrowserDialog() override = default;
52 
53     /**
54       Place the browser window onscreen, using the given attributes.
55 
56       @param parent     The parent object of the browser (cannot be nullptr)
57       @param font       The font to use in the browser
58       @param title      The title of the browser window
59       @param startpath  The initial path to select in the browser
60       @param mode       The functionality to use (load/save/display)
61       @param command    The command to run when 'OK' or 'Cancel' is clicked
62       @param namefilter Filter files/directories in browser display
63     */
64     static void show(GuiObject* parent, const GUI::Font& font,
65                      const string& title, const string& startpath,
66                      BrowserDialog::Mode mode,
67                      const Command& command,
68                      const FilesystemNode::NameFilter& namefilter = {
__anon3cca82690102(const FilesystemNode&) 69                       [](const FilesystemNode&) { return true; }});
70 
71     /**
72       Place the browser window onscreen, using the given attributes.
73 
74       @param parent     The parent object of the browser (cannot be nullptr)
75       @param title      The title of the browser window
76       @param startpath  The initial path to select in the browser
77       @param mode       The functionality to use (load/save/display)
78       @param command    The command to run when 'OK' or 'Cancel' is clicked
79       @param namefilter Filter files/directories in browser display
80     */
81     static void show(GuiObject* parent,
82                      const string& title, const string& startpath,
83                      BrowserDialog::Mode mode,
84                      const Command& command,
85                      const FilesystemNode::NameFilter& namefilter = {
__anon3cca82690202(const FilesystemNode&) 86                       [](const FilesystemNode&) { return true; } });
87 
88     /**
89       Since the show methods allocate a static BrowserDialog, at some
90       point we need to manually de-allocate it.  This method must be
91       called from one of the lowest-level destructors to do that.
92       Currently this is called from the OSystem destructor.
93     */
94     static void hide();
95 
96   private:
97     /** Place the browser window onscreen, using the given attributes */
98     void show(const string& startpath,
99               BrowserDialog::Mode mode,
100               const Command& command,
101               const FilesystemNode::NameFilter& namefilter);
102 
103     /** Get resulting file node (called after receiving kChooseCmd) */
104     const FilesystemNode& getResult() const;
105 
106     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
107     void updateUI(bool fileSelected);
108 
109   private:
110     enum {
111       kChooseCmd  = 'CHOS',
112       kGoUpCmd    = 'GOUP',
113       kBaseDirCmd = 'BADR',
114       kHomeDirCmd = 'HODR'
115     };
116 
117     // Called when the user selects OK (bool is true) or Cancel (bool is false)
118     // FSNode will be set to whatever is active (basically, getResult())
__anon3cca82690402()119     Command _command{[](bool, const FilesystemNode&){}};
120 
121     FileListWidget*   _fileList{nullptr};
122     EditTextWidget*   _currentPath{nullptr};
123     StaticTextWidget* _name{nullptr};
124     EditTextWidget*   _selected{nullptr};
125     ButtonWidget*     _goUpButton{nullptr};
126     CheckboxWidget*   _savePathBox{nullptr};
127 
128     BrowserDialog::Mode _mode{Mode::Directories};
129 
130     static unique_ptr<BrowserDialog> ourBrowser;
131 
132   private:
133     // Following constructors and assignment operators not supported
134     BrowserDialog() = delete;
135     BrowserDialog(const BrowserDialog&) = delete;
136     BrowserDialog(BrowserDialog&&) = delete;
137     BrowserDialog& operator=(const BrowserDialog&) = delete;
138     BrowserDialog& operator=(BrowserDialog&&) = delete;
139 };
140 
141 #endif
142