gui2/tfile_dialog: Add a bookmarks bar

The bookmarks bar holds predefined bookmarks (as in the stuff
src/desktop/paths.hpp exposes) and allows users to easily browse to them
in a single click. It will eventually be possible for the user to add or
remove custom bookmarks as well.

I might add a method to disable specific irrelevant bookmarks later, not
sure (e.g. nobody cares about the preferences dir when trying to find
wesnothd).
This commit is contained in:
Ignacio R. Morelle 2016-10-10 22:55:41 -03:00
parent 4915f0349c
commit d1951b40b9
4 changed files with 303 additions and 89 deletions

View file

@ -20,12 +20,22 @@
y = "(screen_height / 2 - window_height / 2)"
[linked_group]
id = "icon"
id = "bookmark_icons"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "file"
id = "bookmark_labels"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "fileview_icons"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "fileview_labels"
fixed_width = "true"
[/linked_group]
@ -79,14 +89,16 @@
[/row]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = true
vertical_grow = true
[grid]
[row]
grow_factor = 0
[column]
grow_factor = 0
@ -96,23 +108,205 @@
[label]
definition = "default"
label = _ "Location:"
label = _ "Places:"
[/label]
[/column]
[column]
grow_factor = 1
horizontal_grow = true
[grid]
[row]
[column]
grow_factor = 0
border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
definition = "default"
label = _ "Path:"
[/label]
[/column]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "current_dir"
definition = "default"
label = ""
wrap = false
[/label]
[/column]
[/row]
[/grid]
[/column]
[/row]
[row]
grow_factor = 1
[column]
grow_factor = 0
horizontal_grow = "true"
vertical_grow = "true"
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "current_dir"
[listbox]
id = "bookmarks"
definition = "default"
label = ""
wrap = false
[/label]
has_minimum = false
# horizontal_scrollbar_mode = "never"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
definition = "default"
[grid]
[row]
[column]
grow_factor = 0
horizontal_alignment = "left"
border = "all"
border_size = 5
[image]
id = "icon"
definition = "default"
linked_group = "bookmark_icons"
label = "misc/folder-bookmark-icon.png"
[/image]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "bookmark"
definition = "default"
linked_group = "bookmark_labels"
wrap = true
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
vertical_grow = "true"
border = "all"
border_size = 5
[listbox]
id = "filelist"
definition = "default"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
# Needed for double-click event handling!
id = "item_panel"
definition = "default"
[grid]
[row]
[column]
grow_factor = 0
horizontal_alignment = "left"
border = "all"
border_size = 5
[image]
id = "icon"
definition = "default"
linked_group = "fileview_icons"
[/image]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "file"
definition = "default"
linked_group = "fileview_labels"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
[/column]
@ -124,85 +318,6 @@
[/row]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = "true"
vertical_grow = "true"
border = "all"
border_size = 5
[listbox]
id = "filelist"
definition = "default"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
# Needed for double-click event handling!
id = "item_panel"
definition = "default"
[grid]
[row]
[column]
grow_factor = 0
horizontal_alignment = "left"
border = "all"
border_size = 5
[image]
id = "icon"
definition = "default"
linked_group = "icon"
[/image]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "file"
definition = "default"
linked_group = "file"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
[/column]
[/row]
[row]
grow_factor = 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

View file

@ -17,6 +17,7 @@
#include "gui/dialogs/file_dialog.hpp"
#include "cursor.hpp"
#include "desktop/paths.hpp"
#include "filesystem.hpp"
#include "formula/string_utils.hpp"
#include "gui/auxiliary/find_widget.hpp"
@ -114,6 +115,8 @@ tfile_dialog::tfile_dialog()
, save_mode_(false)
, dir_files_()
, dir_subdirs_()
, bookmark_paths_()
, current_bookmark_()
{
set_restore(true);
}
@ -182,6 +185,32 @@ void tfile_dialog::pre_show(twindow& window)
ok.set_label(ok_label_);
}
tlistbox& bookmarks_bar = find_widget<tlistbox>(&window, "bookmarks", false);
std::vector<desktop::path_info> bookmarks = desktop::game_paths();
const auto& sys_paths = desktop::system_paths();
bookmarks.insert(bookmarks.end(), sys_paths.begin(), sys_paths.end());
bookmark_paths_.clear();
current_bookmark_ = -1;
for(const auto& pinfo : bookmarks) {
bookmark_paths_.push_back(pinfo.path);
std::map<std::string, string_map> data;
data["bookmark"]["label"] = pinfo.display_name();
bookmarks_bar.add_row(data);
}
if(bookmarks.empty()) {
// Can't happen but...
// TODO: remove when user-defined bookmarks support lands
bookmarks_bar.set_visible(twidget::tvisible::invisible);
} else {
sync_bookmarks_bar(window);
}
tlistbox& filelist = find_widget<tlistbox>(&window, "filelist", false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
@ -189,9 +218,15 @@ void tfile_dialog::pre_show(twindow& window)
&tfile_dialog::on_row_selected
, *this
, std::ref(window)));
connect_signal_notify_modified(bookmarks_bar, std::begin(
&tfile_dialog::on_bookmark_selected
, *this
, std::ref(window)));
#else
filelist.set_callback_value_change(
dialog_callback<tfile_dialog, &tfile_dialog::on_row_selected>);
bookmarks_bar.set_callback_value_change(
dialog_callback<tfile_dialog, &tfile_dialog::on_bookmark_selected>);
#endif
tbutton& mkdir_button = find_widget<tbutton>(&window, "new_dir", false);
@ -273,6 +308,7 @@ bool tfile_dialog::process_submit_common(twindow& window, const std::string& nam
switch(stype) {
case SELECTION_IS_DIR:
// TODO: Adapt for implementing directory selection mode.
sync_bookmarks_bar(window);
refresh_fileview(window);
break;
case SELECTION_PARENT_NOT_FOUND:
@ -499,6 +535,34 @@ void tfile_dialog::push_fileview_row(tlistbox& filelist, const std::string& name
}
}
void tfile_dialog::sync_bookmarks_bar(twindow& window)
{
tlistbox& bookmarks_bar = find_widget<tlistbox>(&window, "bookmarks", false);
// Internal state has normalized path delimiters but dot entries aren't
// resolved after callers call set_path(), so compare against a canonical
// version. The bookmark paths are already canonical, though.
const std::string& canon_current_dir = fs::normalize_path(current_dir_, true, true);
auto it = std::find(bookmark_paths_.begin(), bookmark_paths_.end(), canon_current_dir);
if(it == bookmark_paths_.end()) {
if(current_bookmark_ >= 0) {
bookmarks_bar.select_row(unsigned(current_bookmark_), false);
}
current_bookmark_ = -1;
} else {
const int new_selection = int(std::distance(bookmark_paths_.begin(), it));
if(new_selection != current_bookmark_) {
assert(unsigned(new_selection) < bookmarks_bar.get_item_count());
if(current_bookmark_ >= 0) {
bookmarks_bar.select_row(unsigned(current_bookmark_), false);
}
bookmarks_bar.select_row(unsigned(new_selection), true);
current_bookmark_ = new_selection;
}
}
}
void tfile_dialog::on_row_selected(twindow& window)
{
tlistbox& filelist = find_widget<tlistbox>(&window, "filelist", false);
@ -520,6 +584,31 @@ void tfile_dialog::on_row_selected(twindow& window)
window.keyboard_capture(&file_textbox);
}
void tfile_dialog::on_bookmark_selected(twindow& window)
{
// Don't let us steal the focus from the primary widgets.
ttext_box& file_textbox = find_widget<ttext_box>(&window, "filename", false);
window.keyboard_capture(&file_textbox);
tlistbox& bookmarks_bar = find_widget<tlistbox>(&window, "bookmarks", false);
const int new_selection = bookmarks_bar.get_selected_row();
if(new_selection < 0) {
if(current_bookmark_ >= 0) {
// Don't allow the user to unselect the selected bookmark. That wouldn't
// make any sense.
bookmarks_bar.select_row(unsigned(current_bookmark_));
}
return;
}
assert(unsigned(new_selection) < bookmark_paths_.size());
current_bookmark_ = new_selection;
set_path(bookmark_paths_[new_selection]);
refresh_fileview(window);
}
void tfile_dialog::on_dir_create_cmd(twindow& window)
{
std::string new_dir_name;

View file

@ -195,6 +195,9 @@ private:
std::vector<std::string> dir_files_;
std::vector<std::string> dir_subdirs_;
std::vector<std::string> bookmark_paths_;
int current_bookmark_;
/** Inherited from tdialog, implemented by REGISTER_DIALOG. */
virtual const std::string& window_id() const;
@ -205,6 +208,8 @@ private:
bool on_exit(twindow& window);
/** Handles file/directory selection on single-click. */
void on_row_selected(twindow& window);
/** Handles selection or deselection of bookmarks. */
void on_bookmark_selected(twindow& window);
/** Handles New Folder button press events. */
void on_dir_create_cmd(twindow& window);
/** Handles Delete button press events. */
@ -234,6 +239,11 @@ private:
bool process_submit_common(twindow& window, const std::string& name);
/**
* Updates the bookmarks bar state to reflect the internal state.
*/
void sync_bookmarks_bar(twindow& window);
std::string get_filelist_selection(class tlistbox& filelist);
enum SELECTION_TYPE