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-2019 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 FILE_LIST_WIDGET_HXX
19#define FILE_LIST_WIDGET_HXX
20
21class CommandSender;
22
23#include "FSNode.hxx"
24#include "Stack.hxx"
25#include "StringListWidget.hxx"
26
27/**
28 Provides an encapsulation of a file listing, allowing to descend into
29 directories, and send signals based on whether an item is selected or
30 activated.
31
32 When the signals ItemChanged and ItemActivated are emitted, the caller
33 can query the selected() and/or currentDir() methods to determine the
34 current state.
35
36 Note that the ItemActivated signal is not sent when activating a
37 directory; instead the selection descends into the directory.
38
39 Widgets wishing to enforce their own filename filtering are able
40 to use a 'NameFilter' as described below.
41*/
42class FileListWidget : public StringListWidget
43{
44 public:
45 enum {
46 ItemChanged = 'FLic', // Entry in the list is changed (single-click, etc)
47 ItemActivated = 'FLac' // Entry in the list is activated (double-click, etc)
48 };
49
50 public:
51 FileListWidget(GuiObject* boss, const GUI::Font& font,
52 int x, int y, int w, int h);
53 virtual ~FileListWidget() = default;
54
55 /** Determines how to display files/folders; either setDirectory or reload
56 must be called after any of these are called. */
57 void setListMode(FilesystemNode::ListMode mode) { _fsmode = mode; }
58 void setNameFilter(const FilesystemNode::NameFilter& filter) { _filter = filter; }
59
60 /**
61 Set initial directory, and optionally select the given item.
62
63 @param node The directory to display. If this is a file, its parent
64 will instead be used, and the file will be selected
65 @param select An optional entry to select (if applicable)
66 */
67 void setDirectory(const FilesystemNode& node, string select = "");
68
69 /** Select parent directory (if applicable) */
70 void selectParent();
71
72 /** Reload current location (file or directory) */
73 void reload();
74
75 /** Gets current node(s) */
76 const FilesystemNode& selected() {
77 _selected = BSPF::clamp(_selected, 0u, uInt32(_fileList.size()-1));
78 return _fileList[_selected];
79 }
80 const FilesystemNode& currentDir() const { return _node; }
81
82 static void setQuickSelectDelay(uInt64 time) { _QUICK_SELECT_DELAY = time; }
83
84 private:
85 /** Very similar to setDirectory(), but also updates the history */
86 void setLocation(const FilesystemNode& node, string select = EmptyString);
87
88 /** Descend into currently selected directory */
89 void selectDirectory();
90
91 bool handleText(char text) override;
92 void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
93
94 private:
95 FilesystemNode::ListMode _fsmode;
96 FilesystemNode::NameFilter _filter;
97 FilesystemNode _node;
98 FSList _fileList;
99
100 Common::FixedStack<string> _history;
101 uInt32 _selected;
102
103 string _quickSelectStr;
104 uInt64 _quickSelectTime;
105 static uInt64 _QUICK_SELECT_DELAY;
106
107 private:
108 // Following constructors and assignment operators not supported
109 FileListWidget() = delete;
110 FileListWidget(const FileListWidget&) = delete;
111 FileListWidget(FileListWidget&&) = delete;
112 FileListWidget& operator=(const FileListWidget&) = delete;
113 FileListWidget& operator=(FileListWidget&&) = delete;
114};
115
116#endif
117