Skip to content

Commit

Permalink
Merge pull request #588 from Vultraz/gui2_widget_groups
Browse files Browse the repository at this point in the history
gui2: implement widget groups
  • Loading branch information
Vultraz committed Feb 25, 2016
2 parents dd70544 + 6d883e1 commit 2185faa
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 38 deletions.
1 change: 1 addition & 0 deletions projectfiles/CodeBlocks/wesnoth.cbp
Expand Up @@ -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" />
Expand Down
43 changes: 16 additions & 27 deletions src/gui/dialogs/preferences_dialog.cpp
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
24 changes: 13 additions & 11 deletions src/gui/dialogs/preferences_dialog.hpp
Expand Up @@ -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.
Expand Down Expand Up @@ -67,7 +68,7 @@ class tpreferences : public tdialog

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);
Expand Down Expand Up @@ -152,17 +153,21 @@ class tpreferences : public tdialog
* 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.
Expand All @@ -183,10 +188,7 @@ class tpreferences : public tdialog
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")
Expand Down
118 changes: 118 additions & 0 deletions src/gui/widgets/group.hpp
@@ -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

0 comments on commit 2185faa

Please sign in to comment.