Merge pull request #588 from Vultraz/gui2_widget_groups

gui2: implement widget groups
This commit is contained in:
Charles Dang 2016-02-25 22:20:22 +11:00
commit 2185faa403
4 changed files with 148 additions and 38 deletions

View file

@ -759,6 +759,7 @@
<Unit filename="../../src/gui/widgets/grid.cpp" />
<Unit filename="../../src/gui/widgets/grid.hpp" />
<Unit filename="../../src/gui/widgets/grid_private.hpp" />
<Unit filename="../../src/gui/widgets/group.hpp" />
<Unit filename="../../src/gui/widgets/helper.cpp" />
<Unit filename="../../src/gui/widgets/helper.hpp" />
<Unit filename="../../src/gui/widgets/horizontal_scrollbar.cpp" />

View file

@ -248,22 +248,24 @@ void tpreferences::setup_combobox(
callback, options.second));
}
template <typename T>
void tpreferences::setup_radio_toggle(
const std::string& toggle_id,
LOBBY_JOINS enum_value,
int start_value,
std::vector<std::pair<ttoggle_button*, int> >& vec,
const T& enum_value,
const int start_value,
tgroup<T>& group,
boost::function<void(int)> callback,
twindow& window)
{
ttoggle_button& button = find_widget<ttoggle_button>(&window, toggle_id, false);
button.set_value(enum_value == start_value);
connect_signal_mouse_left_click(button, boost::bind(
&tpreferences::toggle_radio_callback,
this, boost::ref(vec), boost::ref(start_value), &button));
group.add_member(&button, enum_value);
vec.push_back(std::make_pair(&button, enum_value));
connect_signal_mouse_left_click(button, boost::bind(
&tpreferences::toggle_radio_callback<T>,
this, group, callback));
}
template <typename T>
@ -629,11 +631,11 @@ void tpreferences::initialize_members(twindow& window)
/* LOBBY JOIN NOTIFICATIONS */
setup_radio_toggle("lobby_joins_none", SHOW_NONE,
lobby_joins(), lobby_joins_, window);
lobby_joins(), lobby_joins_group, _set_lobby_joins, window);
setup_radio_toggle("lobby_joins_friends", SHOW_FRIENDS,
lobby_joins(), lobby_joins_, window);
lobby_joins(), lobby_joins_group, _set_lobby_joins, window);
setup_radio_toggle("lobby_joins_all", SHOW_ALL,
lobby_joins(), lobby_joins_, window);
lobby_joins(), lobby_joins_group, _set_lobby_joins, window);
/* FRIENDS LIST */
setup_friends_list(window);
@ -1022,25 +1024,12 @@ void tpreferences::font_scaling_slider_callback(tslider& slider)
font_scaling_ = slider.get_value();
}
template <typename T>
void tpreferences::toggle_radio_callback(
const std::vector<std::pair<ttoggle_button*, int> >& vec,
int& value,
ttoggle_button* active)
tgroup<T>& group,
boost::function<void(int)> setter)
{
FOREACH(const AUTO & e, vec)
{
ttoggle_button* const b = e.first;
if(b == NULL) {
continue;
} else if(b == active && !b->get_value()) {
b->set_value(true);
} else if(b == active) {
value = e.second;
_set_lobby_joins(value);
} else if(b != active && b->get_value()) {
b->set_value(false);
}
}
setter(group.get_active_member_value());
}
void tpreferences::on_page_select(twindow& window)

View file

@ -20,6 +20,7 @@
#include "game_preferences.hpp"
#include "make_enum.hpp"
#include "gui/dialogs/dialog.hpp"
#include "gui/widgets/group.hpp"
// This file is not named preferences.hpp in order -I conflicts with
// src/preferences.hpp.
@ -67,7 +68,7 @@ private:
void edit_friend_list_entry(tlistbox& friends, ttext_box& textbox);
void remove_friend_list_entry(tlistbox& friends_list,
void remove_friend_list_entry(tlistbox& friends_list,
ttext_box& textbox, twindow& window);
void add_tab(tlistbox& tab_bar, const std::string& label);
@ -152,17 +153,21 @@ private:
* If (at a later date) more groups need to be added, this will have to be
* generalized.
*/
tgroup<preferences::LOBBY_JOINS> lobby_joins_group;
template <typename T>
void setup_radio_toggle(
const std::string& toggle_id,
preferences::LOBBY_JOINS enum_value,
int start_value,
std::vector<std::pair<ttoggle_button*, int> >& vec,
const T& enum_value,
const int start_value,
tgroup<T>& group,
boost::function<void(int)> callback,
twindow& window);
template <typename T>
void toggle_radio_callback(
const std::vector<std::pair<ttoggle_button*, int> >& vec,
int& value,
ttoggle_button* active);
tgroup<T>& group,
boost::function<void(int)> setter);
/**
* Sets up a label that always displays the value of another widget.
@ -183,10 +188,7 @@ private:
void status_label_callback(T& parent_widget,
tcontrol& label_widget, const std::string& suffix = "");
typedef std::pair<ttoggle_button*, int> lobby_radio_toggle;
std::vector<lobby_radio_toggle> lobby_joins_;
MAKE_ENUM(ADVANCED_PREF_TYPE,
MAKE_ENUM(ADVANCED_PREF_TYPE,
(TOGGLE, "boolean")
(SLIDER, "int")
(COMBO, "combo")

118
src/gui/widgets/group.hpp Normal file
View file

@ -0,0 +1,118 @@
/*
Copyright (C) 2008 - 2016 The Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef GUI_WIDGETS_GROUP_HPP_INCLUDED
#define GUI_WIDGETS_GROUP_HPP_INCLUDED
#include "gui/auxiliary/event/dispatcher.hpp"
#include "gui/widgets/selectable.hpp"
#include "gui/widgets/widget.hpp"
#include "utils/foreach.tpp"
#include <vector>
#include <boost/bind.hpp>
namespace gui2
{
template <class T>
class tgroup
{
public:
typedef typename std::vector<std::pair<tselectable_*, T> > group_list;
typedef typename group_list::iterator group_iterator;
typedef typename group_list::const_iterator group_iterator_const;
/**
* Adds a widget/value pair to the group vector. A callback is set
* that sets all members' toggle states to false when clicked. This
* happens before individual widget handlers fire, meaning that the
* clicked widget will remain the only one selected.
*/
void add_member(tselectable_* widget, const T& value)
{
members_.push_back(std::make_pair(widget, value));
dynamic_cast<twidget*>(widget)->connect_signal<event::LEFT_BUTTON_CLICK>(boost::bind(
&tgroup::group_operator, this), event::tdispatcher::front_child);
}
/**
* Removes a member from the group vector.
*
* TODO: implement
void remove_member(tselectable_* widget)
{
}*/
/**
* Group member getters
*/
std::pair<group_iterator, group_iterator> members()
{
return std::make_pair(members_.begin(), members_.end());
}
std::pair<group_iterator_const, group_iterator_const> members() const
{
return std::make_pair(members_.begin(), members_.end());
}
/**
* The default actions to take when clicking on one of the widgets
* in the group.
*/
void group_operator()
{
FOREACH(AUTO& member, members())
{
member.first->set_value(false);
}
}
/**
* Returns the value paired with the currently activiely toggled member
* of the group.
*/
T get_active_member_value()
{
FOREACH(AUTO& member, members())
{
if(member.first->get_value_bool()) {
return member.second;
}
}
return T();
}
/**
* Sets the toggle values for all widgets besides the one associated
* with the specified value to false.
*/
void set_member_states(const T& value)
{
FOREACH(AUTO& member, members())
{
member.first->set_value(member.second == value);
}
}
private:
group_list members_;
};
} // namespace gui2
#endif