Exemplo n.º 1
0
void teditor_resize_map::pre_show(CVideo& /*video*/, twindow& window)
{
    tslider& height = find_widget<tslider>(&window, "height", false);
    connect_signal_notify_modified(height
                                   , boost::bind(
                                       &teditor_resize_map::update_expand_direction
                                       , this
                                       , boost::ref(window)));

    tslider& width = find_widget<tslider>(&window, "width", false);
    connect_signal_notify_modified(width
                                   , boost::bind(
                                       &teditor_resize_map::update_expand_direction
                                       , this
                                       , boost::ref(window)));

    std::string name_prefix = "expand";
    for (int i = 0; i < 9; ++i) {
        std::string name = name_prefix + lexical_cast<std::string>(i);
        direction_buttons_[i] = find_widget<ttoggle_button>(
                                    &window, name, false, true);

        direction_buttons_[i]->set_callback_state_change(
            dialog_callback<teditor_resize_map
            , &teditor_resize_map::update_expand_direction>);
    }
    direction_buttons_[0]->set_value(true);
    update_expand_direction(window);
}
Exemplo n.º 2
0
void tscrollbar_container::finalize_setup()
{
	/***** Setup vertical scrollbar *****/

	vertical_scrollbar_grid_ =
		find_widget<tgrid>(this, "_vertical_scrollbar_grid", false, true);

	vertical_scrollbar_ = find_widget<tscrollbar_>(
			vertical_scrollbar_grid_, "_vertical_scrollbar", false, true);

	connect_signal_notify_modified(*vertical_scrollbar_
			, boost::bind(
				  &tscrollbar_container::vertical_scrollbar_moved
				, this));

	/***** Setup horizontal scrollbar *****/
	horizontal_scrollbar_grid_ =
		find_widget<tgrid>(this, "_horizontal_scrollbar_grid", false, true);

	horizontal_scrollbar_ = find_widget<tscrollbar_>(
			horizontal_scrollbar_grid_, "_horizontal_scrollbar", false, true);

	connect_signal_notify_modified(*horizontal_scrollbar_
			, boost::bind(
				  &tscrollbar_container::horizontal_scrollbar_moved
				, this));

	/***** Setup the scrollbar buttons *****/
	typedef std::pair<std::string, tscrollbar_::tscroll> hack;
	BOOST_FOREACH(const hack& item, scroll_lookup()) {

		// Vertical.
		tclickable_* button = find_widget<tclickable_>(
				vertical_scrollbar_grid_, item.first, false, false);

		if(button) {
			button->connect_click_handler(boost::bind(
					  &tscrollbar_container::scroll_vertical_scrollbar
					, this
					, item.second));
		}

		// Horizontal.
		button = find_widget<tclickable_>(
				horizontal_scrollbar_grid_, item.first, false, false);

		if(button) {
			button->connect_click_handler(boost::bind(
					  &tscrollbar_container::scroll_horizontal_scrollbar
					, this
					, item.second));
		}
	}
std::function<void()> bind_status_label(
		widget* find_in,
		const std::string& source_id,
		const std::function<std::string(W&)> value_getter = default_status_value_getter<W>,
		const std::string& label_id = "")
{
	// If no label ID is provided, use the format source ID + '_label'.
	const std::string label_id_ = label_id.empty() ? source_id + "_label" : label_id;

	// Find the source value widget.
	W& source = find_widget<W>(find_in, source_id, false);

	// Find the target status label.
	styled_widget& label = find_widget<styled_widget>(find_in, label_id_, false);

	const auto update_label = [&, value_getter]() {
		const std::string value = value_getter(source);

		label.set_label(value);
	};

	// Bind the callback.
	connect_signal_notify_modified(source, std::bind(update_label));

	// Set initial value.
	update_label();

	return update_label;
}
Exemplo n.º 4
0
void tdata_manage::pre_show(CVideo& /*video*/, twindow& window)
{
	assert(txtFilter_);

	ttext_box* filter
			= find_widget<ttext_box>(&window, "txtFilter", false, true);
	window.keyboard_capture(filter);
	filter->set_text_changed_callback(
			boost::bind(&tdata_manage::filter_text_changed, this, _1, _2));

	tlistbox& list = find_widget<tlistbox>(&window, "persist_list", false);
	window.keyboard_capture(&list);

#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(list,
								   boost::bind(&tdata_manage::list_item_clicked,
											   this,
											   boost::ref(window)));
#else
	list.set_callback_value_change(
			dialog_callback<tdata_manage, &tdata_manage::list_item_clicked>);
#endif

	{
		cursor::setter cur(cursor::WAIT);
		games_ = savegame::get_saves_list();
	}
	fill_game_list(window, games_);

	connect_signal_mouse_left_click(
			find_widget<tbutton>(&window, "clear", false),
			boost::bind(&tdata_manage::delete_button_callback,
						this,
						boost::ref(window)));
}
Exemplo n.º 5
0
/**
 * Sets a callback on a widget of the current dialog.
 * - Arg 1: function.
 * - Args 2..n: path of strings and integers.
 */
int intf_set_dialog_callback(lua_State *L)
{
	gui2::twidget *w = find_widget(L, 2, true);

	scoped_dialog::callback_map &m = scoped_dialog::current->callbacks;
	scoped_dialog::callback_map::iterator i = m.find(w);
	if (i != m.end())
	{
		lua_pushstring(L
				, dlgclbkKey);
		lua_rawget(L, LUA_REGISTRYINDEX);
		lua_pushnil(L);
		lua_rawseti(L, -2, i->second);
		lua_pop(L, 1);
		m.erase(i);
	}

	if (lua_isnil(L, 1)) return 0;

	if (gui2::tclickable_ *c = dynamic_cast<gui2::tclickable_ *>(w)) {
		static tdialog_callback_wrapper wrapper;
		c->connect_click_handler(boost::bind(
									  &tdialog_callback_wrapper::forward
									, wrapper
									, w));
	} else if (gui2::tselectable_ *s = dynamic_cast<gui2::tselectable_ *>(w)) {
		s->set_callback_state_change(&dialog_callback);
	}
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	else if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w)) {
		static tdialog_callback_wrapper wrapper;
		connect_signal_notify_modified(*l
				, boost::bind(
					  &tdialog_callback_wrapper::forward
					, wrapper
					, w));
	}
#else
	else if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w)) {
		l->set_callback_value_change(&dialog_callback);
	}
#endif
	else if (gui2::ttree_view *tv = dynamic_cast<gui2::ttree_view *>(w)) {
		tv->set_selection_change_callback(&dialog_callback);
	}
	else
		return luaL_argerror(L, lua_gettop(L), "unsupported widget");

	lua_pushstring(L
			, dlgclbkKey);
	lua_rawget(L, LUA_REGISTRYINDEX);
	int n = lua_rawlen(L, -1) + 1;
	m[w] = n;
	lua_pushvalue(L, 1);
	lua_rawseti(L, -2, n);
	lua_pop(L, 1);

	return 0;
}
Exemplo n.º 6
0
void tunit_recruit::pre_show(twindow& window)
{
	tlistbox& list = find_widget<tlistbox>(&window, "recruit_list", false);

#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(*list,
		std::bind(&tunit_recruit::list_item_clicked,
		*this,
		std::ref(window)));
#else
	list.set_callback_value_change(
		dialog_callback<tunit_recruit, &tunit_recruit::list_item_clicked>);
#endif

	window.keyboard_capture(&list);

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "show_help", false),
		std::bind(&tunit_recruit::show_help, this, std::ref(window)));

	for(const auto& recruit : recruit_list_)
	{
		std::map<std::string, string_map> row_data;
		string_map column;

		std::string	image_string = recruit->image() + "~RC(" + recruit->flag_rgb() + ">"
			+ team::get_side_color_index(team_.side()) + ")";

		int wb_gold = 0;
		if(resources::controller) {
			if(const std::shared_ptr<wb::manager>& whiteb = resources::controller->get_whiteboard()) {
				wb::future_map future; // So gold takes into account planned spending
				wb_gold = whiteb->get_spent_gold_for(team_.side());
			}
		}

		const bool can_afford = recruit->cost() <= team_.gold() - wb_gold;

		const std::string cost_string = std::to_string(recruit->cost());

		column["use_markup"] = "true";

		column["label"] = image_string;
		row_data.emplace("unit_image", column);

		column["label"] = can_afford_unit(recruit->type_name(), can_afford);
		row_data.emplace("unit_type", column);

		column["label"] = can_afford_unit(cost_string, can_afford);
		row_data.emplace("unit_cost", column);

		list.add_row(row_data);
	}

	list_item_clicked(window);
}
Exemplo n.º 7
0
void tmp_create_game::pre_show(twindow& window)
{
	find_widget<tminimap>(&window, "minimap", false).set_config(&cfg_);

	tlistbox& list = find_widget<tlistbox>(&window, "map_list", false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(list,
								   boost::bind(&tmp_create_game::update_map,
											   *this,
											   boost::ref(window)));
#else
	list.set_callback_value_change(
			dialog_callback<tmp_create_game, &tmp_create_game::update_map>);
#endif

	// Load option (might turn it into a button later).
	string_map item;
	item.insert(std::make_pair("label", _("Load Game")));
	item.insert(std::make_pair("tooltip", _("Load Game...")));
	list.add_row(item);

	// User maps
	/*	FIXME implement user maps
		std::vector<std::string> maps;
		filesystem::get_files_in_dir(filesystem::get_user_data_dir() + "/editor/maps", &maps, nullptr,
	   filesystem::FILE_NAME_ONLY);

		for(const auto& map : maps) {
			std::map<std::string, t_string> item;
			item.insert(std::make_pair("label", map));
			list->add_row(item);
		}
	*/

	// Standard maps
	int i = 0;
	for(const auto & map : cfg_.child_range("multiplayer"))
	{
		if(map["allow_new_game"].to_bool(true)) {
			string_map item;
			item.insert(std::make_pair("label", map["name"].str()));
			item.insert(std::make_pair("tooltip", map["name"].str()));
			list.add_row(item);

			// This hack is needed since the next item is too wide to fit.
			// and the scrollbar can't truncate text yet.
			if(++i == 46) {
				break;
			}
		}
	}

	update_map_settings(window);
}
Exemplo n.º 8
0
void tcore_selection::pre_show(twindow& window)
{
    /***** Setup core list. *****/
    tlistbox& list = find_widget<tlistbox>(&window, "core_list", false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
    connect_signal_notify_modified(
        list,
        std::bind(&tcore_selection::core_selected,
                  this,
                  std::ref(window)));
#else
    list.set_callback_value_change(
        dialog_callback<tcore_selection,
        &tcore_selection::core_selected>);
#endif
    window.keyboard_capture(&list);

    /***** Setup core details. *****/
    tmulti_page& multi_page
        = find_widget<tmulti_page>(&window, "core_details", false);

    for(const auto & core : cores_)
    {
        /*** Add list item ***/
        string_map list_item;
        std::map<std::string, string_map> list_item_item;

        list_item["label"] = core["image"];
        list_item_item.insert(std::make_pair("image", list_item));

        list_item["label"] = core["name"];
        list_item_item.insert(std::make_pair("name", list_item));

        list.add_row(list_item_item);

        tgrid* grid = list.get_row_grid(list.get_item_count() - 1);
        assert(grid);

        /*** Add detail item ***/
        string_map detail_item;
        std::map<std::string, string_map> detail_page;

        detail_item["label"] = core["description"];
        detail_item["use_markup"] = "true";
        detail_page.insert(std::make_pair("description", detail_item));

        multi_page.add_page(detail_page);
    }
    list.select_row(choice_, true);

    core_selected(window);
}
Exemplo n.º 9
0
	void bind(twindow& window)
	{
		DBG_GUI << "Main: Binding widgets and callbacks\n";
		model_.sides_list
				= &find_widget<tlistbox>(&window, "sides_list", false);
		model_.nicks_list
				= &find_widget<tlistbox>(&window, "nicks_list", false);

#ifdef GUI2_EXPERIMENTAL_LISTBOX
		connect_signal_notify_modified(
				*model_.sides_list,
				std::bind(&tmp_change_control::view::
									 handle_sides_list_item_clicked,
							this,
							std::ref(window)));

		connect_signal_notify_modified(
				*model_.nicks_list,
				std::bind(&tmp_change_control::view::
									 handle_nicks_list_item_clicked,
							this,
							std::ref(window)));
#else
		model_.sides_list->set_callback_value_change(
				dialog_view_callback<tmp_change_control,
									 tmp_change_control::view,
									 &tmp_change_control::view::
											  handle_sides_list_item_clicked>);

		model_.nicks_list->set_callback_value_change(
				dialog_view_callback<tmp_change_control,
									 tmp_change_control::view,
									 &tmp_change_control::view::
											  handle_nicks_list_item_clicked>);
#endif
	}
Exemplo n.º 10
0
void tgame_load::pre_show(CVideo& /*video*/, twindow& window)
{
	find_widget<tminimap>(&window, "minimap", false).set_config(&cache_config_);

	sheet_.insert(std::make_pair(LOCAL_PAGE, find_widget<ttoggle_button>(&window, "local", false, true)));
	sheet_.insert(std::make_pair(NETWORK_PAGE, find_widget<ttoggle_button>(&window, "network", false, true)));
	for (std::map<int, ttoggle_button*>::iterator it = sheet_.begin(); it != sheet_.end(); ++ it) {
		it->second->set_callback_state_change(boost::bind(&tgame_load::sheet_toggled, this, _1));
		it->second->set_data(it->first);
	}

	connect_signal_mouse_left_click(
			find_widget<tbutton>(&window, "delete", false)
			, boost::bind(
				  &tgame_load::delete_button_callback
				, this
				, boost::ref(window)));

	connect_signal_mouse_left_click(
			find_widget<tbutton>(&window, "xmit", false)
			, boost::bind(
				  &tgame_load::xmit_button_callback
				, this
				, boost::ref(window)));

	savegame_list_ = find_widget<tlistbox>(&window, "savegame_list", false, true);
	sheet_.begin()->second->set_value(true);

	swap_page(window, LOCAL_PAGE, false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(*list, boost::bind(
				  &tgame_load::list_item_clicked
				, *this
				, boost::ref(window)));
#else
	savegame_list_->set_callback_value_change(
			dialog_callback<tgame_load, &tgame_load::list_item_clicked>);
#endif


	if (disp_.in_game()) {
		find_widget<tbutton>(&window, "xmit", false).set_visible(twidget::INVISIBLE);
		find_widget<ttoggle_button>(&window, "local", false).set_visible(twidget::INVISIBLE);
		find_widget<ttoggle_button>(&window, "network", false).set_visible(twidget::INVISIBLE);
	}
}
Exemplo n.º 11
0
void listbox::finalize(builder_grid_const_ptr header,
		builder_grid_const_ptr footer,
		const std::vector<std::map<std::string, string_map>>& list_data)
{
	// "Inherited."
	scrollbar_container::finalize_setup();

	assert(generator_);

	if(header) {
		swap_grid(&get_grid(), content_grid(), header->build(), "_header_grid");
	}

	grid& p = find_widget<grid>(this, "_header_grid", false);

	for(unsigned i = 0, max = std::max(p.get_cols(), p.get_rows()); i < max; ++i) {
		//
		// TODO: I had to change this to case to a toggle_button in order to use a signal handler.
		// Should probably look into a way to make it more general like it was before (used to be
		// cast to selectable_item).
		//
		// - vultraz, 2017-08-23
		//
		if(toggle_button* selectable = find_widget<toggle_button>(&p, "sort_" + std::to_string(i), false, false)) {
			// Register callback to sort the list.
			connect_signal_notify_modified(*selectable, std::bind(&listbox::order_by_column, this, i, _1));

			if(orders_.size() < max) {
				orders_.resize(max);
			}

			orders_[i].first = selectable;
		}
	}

	if(footer) {
		swap_grid(&get_grid(), content_grid(), footer->build(), "_footer_grid");
	}

	generator_->create_items(-1, list_builder_, list_data, std::bind(&listbox::list_item_clicked, this, _1));
	swap_grid(nullptr, content_grid(), generator_, "_list_grid");
}
Exemplo n.º 12
0
void tgame_load::pre_show(CVideo& /*video*/, twindow& window)
{
    assert(txtFilter_);

    find_widget<tminimap>(&window, "minimap", false).set_config(&cache_config_);

    ttext_box* filter = find_widget<ttext_box>(
                            &window, "txtFilter", false, true);
    window.keyboard_capture(filter);
    filter->set_text_changed_callback(boost::bind(
                                          &tgame_load::filter_text_changed, this, _1, _2));

    tlistbox* list = find_widget<tlistbox>(
                         &window, "savegame_list", false, true);
    window.keyboard_capture(list);

#ifdef GUI2_EXPERIMENTAL_LISTBOX
    connect_signal_notify_modified(*list, boost::bind(
                                       &tgame_load::list_item_clicked
                                       , *this
                                       , boost::ref(window)));
#else
    list->set_callback_value_change(
        dialog_callback<tgame_load, &tgame_load::list_item_clicked>);
#endif

    {
        cursor::setter cur(cursor::WAIT);
        games_ = savegame::get_saves_list();
    }
    fill_game_list(window, games_);

    connect_signal_mouse_left_click(
        find_widget<tbutton>(&window, "delete", false)
        , boost::bind(
            &tgame_load::delete_button_callback
            , this
            , boost::ref(window)));

    display_savegame(window);
}
Exemplo n.º 13
0
    void bind(twindow& window)
    {
        LOG_CHAT_LOG << "Entering tchat_log::view::bind" << std::endl;
        model_.msg_label = &find_widget<tcontrol>(&window, "msg", false);
        model_.page_number
            = &find_widget<tslider>(&window, "page_number", false);
        connect_signal_notify_modified(
            *model_.page_number,
            std::bind(&view::handle_page_number_changed,
                      this,
                      std::ref(window)));

        model_.previous_page
            = &find_widget<tbutton>(&window, "previous_page", false);
        model_.previous_page->connect_click_handler(
            std::bind(&view::previous_page, this, std::ref(window)));

        model_.next_page = &find_widget<tbutton>(&window, "next_page", false);
        model_.next_page->connect_click_handler(
            std::bind(&view::next_page, this, std::ref(window)));

        model_.filter = &find_widget<ttext_box>(&window, "filter", false);
        model_.filter->set_text_changed_callback(
            std::bind(&view::filter, this, std::ref(window)));
        window.keyboard_capture(model_.filter);

        model_.copy_button = &find_widget<tbutton>(&window, "copy", false);
        connect_signal_mouse_left_click(
            *model_.copy_button,
            std::bind(&view::handle_copy_button_clicked,
                      this,
                      std::ref(window)));
        if (!desktop::clipboard::available()) {
            model_.copy_button->set_active(false);
            model_.copy_button->set_tooltip(_("Clipboard support not found, contact your packager"));
        }

        model_.page_label = &find_widget<tcontrol>(&window, "page_label", false);

        LOG_CHAT_LOG << "Exiting tchat_log::view::bind" << std::endl;
    }
Exemplo n.º 14
0
std::function<void()> bind_status_label(twidget& find_in, const std::string& id,
		const std::function<std::string(W&)> value_getter = default_value_getter<W>,
		const std::string& label_id = "")
{
	const std::string label_id_ = label_id.empty() ? id + "_label" : label_id;

	W& source = find_widget<W>(&find_in, id, false);
	tcontrol& label = find_widget<tcontrol>(&find_in, label_id_, false);

	const auto update_label = [&, value_getter]() {
		const std::string value = value_getter(source);

		label.set_label(value);
	};

	// Bind the callback
	connect_signal_notify_modified(source, std::bind(update_label));

	// Set initial value
	update_label();

	return update_label;
}
Exemplo n.º 15
0
void custom_tod::pre_show(window& window)
{
	assert(!tods_.empty());

	tod_red_field_
			= find_widget<slider>(&window, "tod_red", false, true);

	tod_green_field_
			= find_widget<slider>(&window, "tod_green", false, true);

	tod_blue_field_
			= find_widget<slider>(&window, "tod_blue", false, true);

	current_tod_name_
			= find_widget<text_box>(&window, "tod_name", false, true);

	current_tod_id_ = find_widget<text_box>(&window, "tod_id", false, true);

	current_tod_image_
			= find_widget<image>(&window, "current_tod_image", false, true);

	current_tod_mask_
			= find_widget<image>(&window, "current_tod_mask", false, true);

	current_tod_sound_
			= find_widget<label>(&window, "current_sound", false, true);

	current_tod_number_
			= find_widget<label>(&window, "tod_number", false, true);

	connect_signal_mouse_left_click(find_widget<button>(&window, "image_button", false),
			std::bind(&custom_tod::select_file,
					this,
					get_selected_tod().image,
					"data/core/images/misc",
					"image",
					std::ref(window)));

	connect_signal_mouse_left_click(find_widget<button>(&window, "mask_button", false),
			std::bind(&custom_tod::select_file,
					this,
					get_selected_tod().image_mask,
					"data/core/images",
					"mask",
					std::ref(window)));

	connect_signal_mouse_left_click(find_widget<button>(&window, "sound_button", false),
			std::bind(&custom_tod::select_file,
					this,
					get_selected_tod().sounds,
					"data/core/sounds/ambient",
					"sound",
					std::ref(window)));

	connect_signal_mouse_left_click(
			find_widget<button>(&window, "next_tod", false),
			std::bind(&custom_tod::do_next_tod, this, std::ref(window)));

	connect_signal_mouse_left_click(
			find_widget<button>(&window, "previous_tod", false),
			std::bind(&custom_tod::do_prev_tod, this, std::ref(window)));

	connect_signal_mouse_left_click(
			find_widget<button>(&window, "new", false),
			std::bind(&custom_tod::do_new_tod, this, std::ref(window)));

	connect_signal_mouse_left_click(
			find_widget<button>(&window, "delete", false),
			std::bind(&custom_tod::do_delete_tod, this, std::ref(window)));

	connect_signal_notify_modified(
			*(lawful_bonus_field_->get_widget()),
			std::bind(&custom_tod::update_lawful_bonus,
					this,
					std::ref(window)));

	connect_signal_notify_modified(
			*tod_red_field_,
			std::bind(&custom_tod::update_tod_display,
					this,
					std::ref(window)));

	connect_signal_notify_modified(
			*tod_green_field_,
			std::bind(&custom_tod::update_tod_display,
					this,
					std::ref(window)));

	connect_signal_notify_modified(
			*tod_blue_field_,
			std::bind(&custom_tod::update_tod_display,
					this,
					std::ref(window)));

	for(size_t i = 0; i < tods_.size(); ++i) {
		time_of_day& tod = tods_[i];
		const int r = tod_red_field_->get_value();
		const int g = tod_green_field_->get_value();
		const int b = tod_blue_field_->get_value();
		if(tod.color.r == r && tod.color.g == g && tod.color.b == b) {
			current_tod_ = i;
			update_selected_tod_info(window);
			return;
		}
	}

	update_selected_tod_info(window);
}
Exemplo n.º 16
0
void tlobby_main::pre_show(twindow& window)
{
	SCOPE_LB;

	gamelistbox_ = find_widget<tlistbox>(&window, "game_list", false, true);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(
			*gamelistbox_,
			std::bind(&tlobby_main::gamelist_change_callback, *this, std::ref(window)));
#else
	gamelistbox_->set_callback_value_change(
			dialog_callback<tlobby_main, &tlobby_main::gamelist_change_callback>);
#endif

	window.keyboard_capture(gamelistbox_);

	player_list_.init(window);

	player_list_.sort_by_name->set_value(preferences::playerlist_sort_name());
	player_list_.sort_by_relation->set_value(preferences::playerlist_sort_relation());
	player_list_.update_sort_icons();

	player_list_.sort_by_name->set_callback_state_change(
			std::bind(&tlobby_main::player_filter_callback, this, _1));
	player_list_.sort_by_relation->set_callback_state_change(
			std::bind(&tlobby_main::player_filter_callback, this, _1));

	window.set_enter_disabled(true);
	window.set_escape_disabled(true);

	// A new key handler to deal with escape in a different manner.
	window.connect_signal<event::SDL_KEY_DOWN>(
		std::bind(&tlobby_main::signal_handler_key_down, this, _5, _3, _4),
		event::tdispatcher::front_pre_child);

	window_ = &window;

	chatbox_ = find_widget<tchatbox>(&window, "chat", false, true);
	chatbox_->set_lobby_info(lobby_info_);
	chatbox_->set_wesnothd_connection(wesnothd_connection_);
	chatbox_->set_active_window_changed_callback([this]() { player_list_dirty_ = true; });

	find_widget<tbutton>(&window, "create", false).set_retval(CREATE);

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "refresh", false),
		std::bind(&tlobby_main::refresh_button_callback, this, std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "show_preferences", false),
		std::bind(&tlobby_main::show_preferences_button_callback, this, std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "join_global", false),
		std::bind(&tlobby_main::join_global_button_callback, this, std::ref(window)));

	find_widget<tbutton>(&window, "join_global", false).set_active(false);

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "observe_global", false),
		std::bind(&tlobby_main::observe_global_button_callback, this, std::ref(window)));

	find_widget<tbutton>(&window, "observe_global", false).set_active(false);

	tmenu_button& replay_options = find_widget<tmenu_button>(&window, "replay_options", false);

	if(preferences::skip_mp_replay()) {
		replay_options.set_selected(1);
	}

	if(preferences::blindfold_replay()) {
		replay_options.set_selected(2);
	}

	replay_options.connect_click_handler(
			std::bind(&tlobby_main::skip_replay_changed_callback, this, std::ref(window)));

	filter_friends_ = find_widget<ttoggle_button>(&window, "filter_with_friends", false, true);
	filter_ignored_ = find_widget<ttoggle_button>(&window, "filter_without_ignored", false, true);
	filter_slots_   = find_widget<ttoggle_button>(&window, "filter_vacant_slots", false, true);
	filter_invert_  = find_widget<ttoggle_button>(&window, "filter_invert", false, true);
	filter_text_    = find_widget<ttext_box>(&window, "filter_text", false, true);

	filter_friends_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	filter_ignored_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	filter_slots_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	filter_invert_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	connect_signal_pre_key_press(
			*filter_text_,
			std::bind(&tlobby_main::game_filter_keypress_callback, this, _5));

	chatbox_->room_window_open("lobby", true);
	chatbox_->active_window_changed();
	game_filter_reload();

	// Force first update to be directly.
	tlobby_main::network_handler();
	lobby_update_timer_ = add_timer(
		game_config::lobby_network_timer, std::bind(&tlobby_main::network_handler, this), true);

	// Set up Lua plugin context
	plugins_context_.reset(new plugins_context("Multiplayer Lobby"));

	plugins_context_->set_callback("join",    [&, this](const config&) {
		if(do_game_join(get_game_index_from_id(selected_game_id_), false)) {
			window.set_retval(JOIN);
		}
	}, true);

	plugins_context_->set_callback("observe", [&, this](const config&) {
		if(do_game_join(get_game_index_from_id(selected_game_id_), true)) {
			window.set_retval(OBSERVE);
		}
	}, true);

	plugins_context_->set_callback("create", [this, &window](const config&) { window.set_retval(CREATE); }, true);
	plugins_context_->set_callback("quit", [&window](const config&) { window.set_retval(twindow::CANCEL); }, false);

	plugins_context_->set_callback("chat", [this](const config& cfg) { chatbox_->send_chat_message(cfg["message"], false); }, true);
	plugins_context_->set_callback("select_game", [this](const config& cfg) {
		selected_game_id_ = cfg.has_attribute("id") ? cfg["id"].to_int() : lobby_info_.games()[cfg["index"].to_int()]->id;
	}, true);

	plugins_context_->set_accessor("game_list",   [this](const config&) { return lobby_info_.gamelist(); });
	plugins_context_->set_accessor("game_config", [this](const config&) { return game_config_; });
}
Exemplo n.º 17
0
void tgame_version::pre_show(twindow& window)
{
	string_map i18n_syms;

	//
	// General information.
	//

	tcontrol& version_label = find_widget<tcontrol>(&window, "version", false);
	i18n_syms["version"] = game_config::revision;
	version_label.set_label(VGETTEXT("Version $version", i18n_syms));

	tcontrol& os_label = find_widget<tcontrol>(&window, "os", false);
	i18n_syms["os"] = desktop::os_version();
	os_label.set_label(VGETTEXT("Running on $os", i18n_syms));

	tbutton& copy_all = find_widget<tbutton>(&window, "copy_all", false);
	connect_signal_mouse_left_click(
			copy_all,
			std::bind(&tgame_version::report_copy_callback, this));

	//
	// Game paths tab.
	//

	for(const auto & path_ent : path_map_)
	{
		const std::string& path_id = path_ent.first;
		const std::string& path_path = path_ent.second;

		ttext_& path_w
				= find_widget<ttext_>(&window, path_wid_stem_ + path_id, false);
		tbutton& copy_w = find_widget<tbutton>(
				&window, copy_wid_stem_ + path_id, false);
		tbutton& browse_w = find_widget<tbutton>(
				&window, browse_wid_stem_ + path_id, false);

		path_w.set_value(path_path);
		path_w.set_active(false);

		connect_signal_mouse_left_click(
				copy_w,
				std::bind(&tgame_version::copy_to_clipboard_callback,
							this,
							path_path));
		connect_signal_mouse_left_click(
				browse_w,
				std::bind(&tgame_version::browse_directory_callback,
							this,
							path_path));

		if(!desktop::open_object_is_supported()) {
			// No point in displaying these on platforms that can't do
			// open_object().
			browse_w.set_visible(tcontrol::tvisible::invisible);
		}

		if(!desktop::clipboard::available()) {
			copy_w.set_active(false);
			copy_w.set_tooltip(_("Clipboard support not found, contact your packager"));
		}
	}

#ifndef _WIN32
	tgrid& w32_options_grid
			= find_widget<tgrid>(&window, "win32_paths", false);
	w32_options_grid.set_visible(twidget::tvisible::invisible);
#else
	tbutton& stderr_button
			= find_widget<tbutton>(&window, "open_stderr", false);
	connect_signal_mouse_left_click(
			stderr_button,
			std::bind(&tgame_version::browse_directory_callback,
						this,
						log_path_));
	stderr_button.set_active(!log_path_.empty());
#endif

	//
	// Build info tab.
	//

	std::map<std::string, string_map> list_data;

	tlistbox& deps_listbox
			= find_widget<tlistbox>(&window, "deps_listbox", false);

	for(const auto & dep : deps_)
	{
		list_data["dep_name"]["label"] = dep[0];

		list_data["dep_build_version"]["label"] = dep[1];

		// The build version is always known, but runtime version isn't, esp.
		// for header-only libraries like Boost for which the concept does not
		// apply.
		if(!dep[2].empty()) {
			list_data["dep_rt_version"]["label"] = dep[2];
		} else {
			list_data["dep_rt_version"]["label"] = _("version^N/A");
		}

		deps_listbox.add_row(list_data);
	}

	deps_listbox.select_row(0);
	list_data.clear();

	//
	// Features tab.
	//

	tlistbox& opts_listbox
			= find_widget<tlistbox>(&window, "opts_listbox", false);

	for(const auto & opt : opts_)
	{
		list_data["opt_name"]["label"] = opt.name;

		if(opt.enabled) {
			list_data["opt_status"]["label"] = text_feature_on;
		} else {
			list_data["opt_status"]["label"] = text_feature_off;
		}
		list_data["opt_status"]["use_markup"] = "true";

		opts_listbox.add_row(list_data);
	}

	opts_listbox.select_row(0);
	list_data.clear();

	//
	// Set-up page stack and auxiliary controls last.
	//

	tstacked_widget& pager
			= find_widget<tstacked_widget>(&window, "tabs_container", false);
	pager.select_layer(0);

	tlistbox& tab_bar
			= find_widget<tlistbox>(&window, "tab_bar", false);

	window.keyboard_capture(&tab_bar);

	const unsigned tab_count = tab_bar.get_item_count();
	VALIDATE(tab_count == pager.get_layer_count(), "Tab bar and container size mismatch");

#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(tab_bar,
		std::bind(&tgame_version::tab_switch_callback, *this, std::ref(window)));
#else
	tab_bar.set_callback_value_change(
		dialog_callback<tgame_version, &tgame_version::tab_switch_callback>);
#endif
}
Exemplo n.º 18
0
void tcampaign_selection::pre_show(twindow& window)
{
	if(new_widgets || true) {
		/***** Setup campaign tree. *****/
		ttree_view& tree
				= find_widget<ttree_view>(&window, "campaign_tree", false);

		tree.set_selection_change_callback(
				std::bind(&tcampaign_selection::campaign_selected,
							this,
							std::ref(window)));

		window.keyboard_capture(&tree);

		string_map tree_group_field;
		std::map<std::string, string_map> tree_group_item;
		/***** Setup campaign details. *****/
		tmulti_page& multi_page
				= find_widget<tmulti_page>(&window, "campaign_details", false);

		unsigned id = 0;
		for(const auto & level : engine_.get_levels_by_type_unfiltered(ng::level::TYPE::SP_CAMPAIGN))
		{
			const config& campaign = level->data();

			/*** Add tree item ***/
			tree_group_field["label"] = campaign["icon"];
			tree_group_item["icon"] = tree_group_field;

			tree_group_field["label"] = campaign["name"];
			tree_group_item["name"] = tree_group_field;

			tree_group_field["label"] = campaign["completed"].to_bool() ? "misc/laurel.png" : "misc/blank-hex.png";
			tree_group_item["victory"] = tree_group_field;

			tree.add_node("campaign", tree_group_item).set_id(std::to_string(id++));

			/*** Add detail item ***/
			string_map detail_item;
			std::map<std::string, string_map> detail_page;

			detail_item["label"] = campaign["description"];
			detail_item["use_markup"] = "true";

			if(!campaign["description_alignment"].empty()) {
				detail_item["text_alignment"] = campaign["description_alignment"];
			}

			detail_page.emplace("description", detail_item);

			detail_item["label"] = campaign["image"];
			detail_page.emplace("image", detail_item);

			multi_page.add_page(detail_page);
		}
		if (!engine_.get_const_extras_by_type(ng::create_engine::MOD).empty()) {

			tree_group_field["label"] = "Modifications";
			tree_group_item["tree_view_node_label"] = tree_group_field;
			//tree_group_item["tree_view_node_label"] = tree_group_field;
			ttree_view_node& mods_node = tree.add_node("campaign_group", tree_group_item);
			std::vector<std::string> enabled = engine_.active_mods();

			id = 0;
			tree_group_item.clear();
			for(const auto& mod : engine_.get_const_extras_by_type(ng::create_engine::MOD))
			{
				bool active = std::find(enabled.begin(), enabled.end(), mod->id) != enabled.end();
				/*** Add tree item ***/
				tree_group_field["label"] = mod->name;
				tree_group_item["checkb"] = tree_group_field;

				ttree_view_node & node = mods_node.add_child("modification", tree_group_item);
				ttoggle_button* checkbox = dynamic_cast<ttoggle_button*>(node.find("checkb", true));
				VALIDATE(checkbox, missing_widget("checkb"));
				checkbox->set_value(active);
				checkbox->set_label(mod->name);
				checkbox->set_callback_state_change(std::bind(&tcampaign_selection::mod_toggled, this, id, _1));
				++id;
			}
		}
	} else {
		/***** Hide the tree view. *****/
		if(ttree_view* tree
		   = find_widget<ttree_view>(&window, "campaign_tree", false, false)) {

			tree->set_visible(twidget::tvisible::invisible);
		}

		/***** Setup campaign list. *****/
		tlistbox& list = find_widget<tlistbox>(&window, "campaign_list", false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
		connect_signal_notify_modified(
				list,
				std::bind(&tcampaign_selection::campaign_selected,
							this,
							std::ref(window)));
#else
		list.set_callback_value_change(
				dialog_callback<tcampaign_selection,
								&tcampaign_selection::campaign_selected>);
#endif
		window.keyboard_capture(&list);

		/***** Setup campaign details. *****/
		tmulti_page& multi_page
				= find_widget<tmulti_page>(&window, "campaign_details", false);

		for(const auto & level : engine_.get_levels_by_type_unfiltered(ng::level::TYPE::SP_CAMPAIGN))
		{
			const config& campaign = level->data();

			/*** Add list item ***/
			string_map list_item;
			std::map<std::string, string_map> list_item_item;

			list_item["label"] = campaign["icon"];
			list_item_item.emplace("icon", list_item);

			list_item["label"] = campaign["name"];
			list_item_item.emplace("name", list_item);

			tgrid* grid = &list.add_row(list_item_item);
			assert(grid);

			twidget* widget = grid->find("victory", false);
			if(widget && !campaign["completed"].to_bool()) {
				widget->set_visible(twidget::tvisible::hidden);
			}

			/*** Add detail item ***/
			string_map detail_item;
			std::map<std::string, string_map> detail_page;

			detail_item["use_markup"] = "true";

			detail_item["label"] = campaign["description"];
			detail_page.emplace("description", detail_item);

			detail_item["label"] = campaign["image"];
			detail_page.emplace("image", detail_item);

			multi_page.add_page(detail_page);
		}
	}
	campaign_selected(window);

	/***** Setup advanced settings button *****/
	tbutton* advanced_settings_button =
			find_widget<tbutton>(&window, "advanced_settings", false, false);
	if(advanced_settings_button) {
		advanced_settings_button->connect_click_handler(
			std::bind(&tcampaign_selection::show_settings, this, std::ref(window.video())));
	}
}
Exemplo n.º 19
0
void teditor_settings::pre_show(CVideo& /*video*/, twindow& window)
{
	assert(!tods_.empty());
	current_tod_label_ = find_widget<tlabel>(
			&window, "current_tod", false, true);
	current_tod_image_ = find_widget<tlabel>(
			&window, "current_tod_image", false, true);
	custom_tod_toggle_ = find_widget<ttoggle_button>(
			&window, "custom_tod_toggle", false, true);
	custom_tod_auto_refresh_ = find_widget<ttoggle_button>(
			&window, "custom_tod_auto_refresh", false, true);

	tbutton& next_tod_button = find_widget<tbutton>(
			&window, "next_tod", false);
	connect_signal_mouse_left_click(next_tod_button, boost::bind(
			  &teditor_settings::do_next_tod
			, this
			, boost::ref(window)));


	tbutton& apply_button = find_widget<tbutton>(
			&window, "apply", false);
	connect_signal_mouse_left_click(apply_button, boost::bind(
			  &teditor_settings::update_tod_display
			, this
			, boost::ref(window)));

	custom_tod_toggle_->set_callback_state_change(
			dialog_callback<teditor_settings
				, &teditor_settings::update_selected_tod_info>);

	connect_signal_notify_modified(*(custom_tod_red_field_->widget())
			, boost::bind(
				  &teditor_settings::slider_update_callback
				, this
				, boost::ref(window)));

	connect_signal_notify_modified(*(custom_tod_green_field_->widget())
			, boost::bind(
				  &teditor_settings::slider_update_callback
				, this
				, boost::ref(window)));

	connect_signal_notify_modified(*(custom_tod_blue_field_->widget())
			, boost::bind(
				  &teditor_settings::slider_update_callback
				, this
				, boost::ref(window)));

	for (size_t i = 0; i < tods_.size(); ++i) {

		time_of_day& tod = tods_[i];
		const int r = custom_tod_red_field_->get_widget_value(window);
		const int g = custom_tod_green_field_->get_widget_value(window);
		const int b = custom_tod_blue_field_->get_widget_value(window);
		if (tod.color.r == r && tod.color.g == g && tod.color.b == b) {
			current_tod_ = i;
			custom_tod_toggle_->set_value(false);
			update_selected_tod_info(window);
			can_update_display_ = true;
			return;
		}
	}

	/* custom tod */
	custom_tod_toggle_->set_value(true);

	update_selected_tod_info(window);

	can_update_display_ = true;
}
Exemplo n.º 20
0
void tunit_create::pre_show(twindow& window)
{
	ttoggle_button& male_toggle
			= find_widget<ttoggle_button>(&window, "male_toggle", false);
	ttoggle_button& female_toggle
			= find_widget<ttoggle_button>(&window, "female_toggle", false);

	gender_toggle.add_member(&male_toggle, unit_race::MALE);
	gender_toggle.add_member(&female_toggle, unit_race::FEMALE);

	gender_toggle.set_member_states(last_gender);

	gender_toggle.set_callback_on_value_change(
			dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>);

	tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false);

	ttext_box* filter
			= find_widget<ttext_box>(&window, "filter_box", false, true);

	filter->set_text_changed_callback(
			std::bind(&tunit_create::filter_text_changed, this, _1, _2));

	window.keyboard_capture(filter);
	window.add_to_keyboard_chain(&list);

#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(*list,
								   std::bind(&tunit_create::list_item_clicked,
											   *this,
											   std::ref(window)));
#else
	list.set_callback_value_change(
			dialog_callback<tunit_create, &tunit_create::list_item_clicked>);
#endif

	list.clear();

	for(const auto & i : unit_types.types())
	{
		if(i.second.do_not_list())
			continue;

		// Make sure this unit type is built with the data we need.
		unit_types.build_unit_type(i.second, unit_type::FULL);

		units_.push_back(&i.second);

		std::map<std::string, string_map> row_data;
		string_map column;

		column["label"] = units_.back()->race()->plural_name();
		row_data.emplace("race", column);

		column["label"] = units_.back()->type_name();
		row_data.emplace("unit_type", column);

		list.add_row(row_data);

		// Select the previous choice, if any.
		if(choice_.empty() != true && choice_ == i.first) {
			list.select_row(list.get_item_count() - 1);
		}
	}

	if(units_.empty()) {
		ERR_GUI_G << "no unit types found for unit create dialog; not good"
				  << std::endl;
	}

	list.register_sorting_option(0, [this](const int i) { return (*units_[i]).race()->plural_name().str(); });
	list.register_sorting_option(1, [this](const int i) { return (*units_[i]).type_name().str(); });

	list_item_clicked(window);
}
Exemplo n.º 21
0
void unit_recall::pre_show(window& window)
{
	label& title = find_widget<label>(&window, "title", true);
	title.set_label(title.get_label() + get_title_suffix(team_.side()));

	text_box* filter
			= find_widget<text_box>(&window, "filter_box", false, true);

	filter->set_text_changed_callback(
			std::bind(&unit_recall::filter_text_changed, this, _1, _2));

	listbox& list = find_widget<listbox>(&window, "recall_list", false);

	connect_signal_notify_modified(list, std::bind(&unit_recall::list_item_clicked, this, std::ref(window)));

	list.clear();

	window.keyboard_capture(filter);
	window.add_to_keyboard_chain(&list);

	connect_signal_mouse_left_click(
		find_widget<button>(&window, "rename", false),
		std::bind(&unit_recall::rename_unit, this, std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<button>(&window, "dismiss", false),
		std::bind(&unit_recall::dismiss_unit, this, std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<button>(&window, "show_help", false),
		std::bind(&unit_recall::show_help, this));

	for(const unit_const_ptr& unit : recall_list_) {
		std::map<std::string, string_map> row_data;
		string_map column;

		std::string mods = unit->image_mods();

		if(unit->can_recruit()) {
			mods += "~BLIT(" + unit::leader_crown() + ")";
		}

		for(const std::string& overlay : unit->overlays()) {
			mods += "~BLIT(" + overlay + ")";
		}

		column["use_markup"] = "true";

		column["label"] = unit->absolute_image() + mods;
		row_data.emplace("unit_image", column);

		column["label"] = unit->type_name();
		row_data.emplace("unit_type", column);

		column["label"] = format_cost_string(unit->recall_cost(), team_.recall_cost());
		row_data.emplace("unit_recall_cost", column);

		const std::string& name = !unit->name().empty() ? unit->name().str() : font::unicode_en_dash;
		column["label"] = name;
		row_data.emplace("unit_name", column);

		column["label"] = format_level_string(unit->level());
		row_data.emplace("unit_level", column);

		std::stringstream exp_str;
		exp_str << font::span_color(unit->xp_color());
		if(unit->can_advance()) {
			exp_str << unit->experience() << "/" << unit->max_experience();
		} else {
			exp_str << font::unicode_en_dash;
		}
		exp_str << "</span>";

		column["label"] = exp_str.str();
		row_data.emplace("unit_experience", column);

		// Since the table widgets use heavy formatting, we save a bare copy
		// of certain options to filter on.
		std::string filter_text = unit->type_name() + " " + name + " " + std::to_string(unit->level());

		std::string traits;
		for(const std::string& trait : unit->trait_names()) {
			traits += (traits.empty() ? "" : "\n") + trait;
			filter_text += " " + trait;
		}

		column["label"] = !traits.empty() ? traits : font::unicode_en_dash;
		row_data.emplace("unit_traits", column);

		list.add_row(row_data);
		filter_options_.push_back(filter_text);
	}

	list.register_translatable_sorting_option(0, [this](const int i) { return recall_list_[i]->type_name().str(); });
	list.register_translatable_sorting_option(1, [this](const int i) { return recall_list_[i]->name().str(); });
	list.register_sorting_option(2, [this](const int i) {
		const unit& u = *recall_list_[i];
		return std::make_tuple(u.level(), -static_cast<int>(u.experience_to_advance()));
	});
	list.register_sorting_option(3, [this](const int i) { return recall_list_[i]->experience(); });
	list.register_translatable_sorting_option(4, [this](const int i) {
		return !recall_list_[i]->trait_names().empty() ? recall_list_[i]->trait_names().front().str() : "";
	});

	list.set_active_sorting_option(sort_last.first >= 0 ? sort_last	: sort_default, true);

	list_item_clicked(window);
}
Exemplo n.º 22
0
void tlobby_main::pre_show(twindow& window)
{
	SCOPE_LB;
	roomlistbox_ = find_widget<tlistbox>(&window, "room_list", false, true);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(
			*roomlistbox_,
			std::bind(&tlobby_main::room_switch_callback,
						*this,
						std::ref(window)));
#else
	roomlistbox_->set_callback_value_change(
			dialog_callback<tlobby_main, &tlobby_main::room_switch_callback>);
#endif

	gamelistbox_ = find_widget<tlistbox>(&window, "game_list", false, true);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(
			*gamelistbox_,
			std::bind(&tlobby_main::gamelist_change_callback,
						*this,
						std::ref(window)));
#else
	gamelistbox_->set_callback_value_change(
			dialog_callback<tlobby_main,
							&tlobby_main::gamelist_change_callback>);
#endif

	window.keyboard_capture(gamelistbox_);

	player_list_.init(window);

	player_list_.sort_by_name->set_value(preferences::playerlist_sort_name());
	player_list_.sort_by_relation->set_value(preferences::playerlist_sort_relation());
	player_list_.update_sort_icons();

	player_list_.sort_by_name->set_callback_state_change(
			std::bind(&tlobby_main::player_filter_callback, this, _1));
	player_list_.sort_by_relation->set_callback_state_change(
			std::bind(&tlobby_main::player_filter_callback, this, _1));

	chat_log_container_ = find_widget<tmulti_page>(&window, "chat_log_container", false, true);

	window.set_enter_disabled(true);

	window_ = &window;

	chat_input_ = find_widget<ttext_box>(&window, "chat_input", false, true);
	assert(chat_input_);
	connect_signal_pre_key_press(
		*chat_input_,
		std::bind(&tlobby_main::chat_input_keypress_callback,
				this,
				_3,
				_4,
				_5,
				std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "create", false),
		std::bind(&tlobby_main::create_button_callback,
				this,
				std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "refresh", false),
		std::bind(&tlobby_main::refresh_button_callback,
				this,
				std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "show_preferences", false),
		std::bind(&tlobby_main::show_preferences_button_callback,
				this,
				std::ref(window)));

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "join_global", false),
		std::bind(&tlobby_main::join_global_button_callback,
				this,
				std::ref(window)));
	find_widget<tbutton>(&window, "join_global", false).set_active(false);

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "observe_global", false),
		std::bind(&tlobby_main::observe_global_button_callback,
				this,
				std::ref(window)));

	find_widget<tbutton>(&window, "observe_global", false).set_active(false);

	ttoggle_button& skip_replay
			= find_widget<ttoggle_button>(&window, "skip_replay", false);
	skip_replay.set_value(preferences::skip_mp_replay());
	skip_replay.set_callback_state_change(
			std::bind(&tlobby_main::skip_replay_changed_callback, this, _1));

	filter_friends_ = find_widget<ttoggle_button>(&window, "filter_with_friends", false, true);
	filter_ignored_ = find_widget<ttoggle_button>(&window, "filter_without_ignored", false, true);
	filter_slots_   = find_widget<ttoggle_button>(&window, "filter_vacant_slots", false, true);
	filter_invert_  = find_widget<ttoggle_button>(&window, "filter_invert", false, true);
	filter_text_    = find_widget<ttext_box>(&window, "filter_text", false, true);

	filter_friends_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	filter_ignored_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	filter_slots_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	filter_invert_->set_callback_state_change(
			std::bind(&tlobby_main::game_filter_change_callback, this, _1));
	connect_signal_pre_key_press(
			*filter_text_,
			std::bind(&tlobby_main::game_filter_keypress_callback, this, _5));

	room_window_open("lobby", true);
	active_window_changed();
	game_filter_reload();

	// Force first update to be directly.
	tlobby_main::network_handler();
	lobby_update_timer_ = add_timer(
		game_config::lobby_network_timer, std::bind(&tlobby_main::network_handler, this), true);
}
Exemplo n.º 23
0
void tscrollbar_container::finalize_setup()
{
	/***** Setup vertical scrollbar *****/

	vertical_scrollbar_grid_
			= find_widget<tgrid>(this, "_vertical_scrollbar_grid", false, true);

	vertical_scrollbar_ = find_widget<tscrollbar_>(
			vertical_scrollbar_grid_, "_vertical_scrollbar", false, true);

	connect_signal_notify_modified(
			*vertical_scrollbar_,
			std::bind(&tscrollbar_container::vertical_scrollbar_moved, this));

	/***** Setup horizontal scrollbar *****/
	horizontal_scrollbar_grid_ = find_widget<tgrid>(
			this, "_horizontal_scrollbar_grid", false, true);

	horizontal_scrollbar_ = find_widget<tscrollbar_>(
			horizontal_scrollbar_grid_, "_horizontal_scrollbar", false, true);

	connect_signal_notify_modified(
			*horizontal_scrollbar_,
			std::bind(&tscrollbar_container::horizontal_scrollbar_moved,
						this));

	/***** Setup the scrollbar buttons *****/
	for(const auto & item : scroll_lookup())
	{

		// Vertical.
		tclickable_* button = find_widget<tclickable_>(
				vertical_scrollbar_grid_, item.first, false, false);

		if(button) {
			button->connect_click_handler(std::bind(
					&tscrollbar_container::scroll_vertical_scrollbar,
					this,
					item.second));
		}

		// Horizontal.
		button = find_widget<tclickable_>(
				horizontal_scrollbar_grid_, item.first, false, false);

		if(button) {
			button->connect_click_handler(std::bind(
					&tscrollbar_container::scroll_horizontal_scrollbar,
					this,
					item.second));
		}
	}

	/***** Setup the content *****/
	content_ = new tspacer();
	content_->set_definition("default");

	content_grid_ = dynamic_cast<tgrid*>(
			grid().swap_child("_content_grid", content_, true));
	assert(content_grid_);

	content_grid_->set_parent(this);

	/***** Let our subclasses initialize themselves. *****/
	finalize_subclass();
}
Exemplo n.º 24
0
void mp_staging::add_side_node(window& window, ng::side_engine_ptr side)
{
	tree_view& tree = find_widget<tree_view>(&window, "side_list", false);
	static const std::map<std::string, string_map> empty_map;

	std::map<std::string, string_map> data;
	string_map item;

	item["label"] = std::to_string(side->index() + 1);
	data.emplace("side_number", item);

	// TODO: don't hardcode meganta?
	item["label"] = "units/unknown-unit.png~RC(magenta>" + std::to_string(side->color() + 1) + ")";
	data.emplace("leader_image", item);

	item["label"] = "icons/icon-random.png";
	data.emplace("leader_gender", item);

	// Check to see whether we've added a toplevel tree node for this team. If not, add one
	if(team_tree_map_.find(side->team_name()) == team_tree_map_.end()) {
		std::map<std::string, string_map> data;
		string_map item;

		item["label"] = (formatter() << _("Team:") << " " << side->user_team_name()).str();
		data.emplace("tree_view_node_label", item);

		tree_view_node& team_node = tree.add_node("team_header", data);
		team_node.add_sibling("side_spacer", empty_map);

		team_tree_map_[side->team_name()] = &team_node;
	}

	tree_view_node& node = team_tree_map_[side->team_name()]->add_child("side_panel", data);

	side_tree_map_[side] = &node;

	grid& row_grid = node.get_grid();

	update_leader_display(side, row_grid);

	// Status variables
	const bool fls = connect_engine_.force_lock_settings();
	const bool ums = connect_engine_.params().use_map_settings;

	const bool lock_gold   = side->cfg()["gold_lock"].to_bool(fls);
	const bool lock_income = side->cfg()["income_lock"].to_bool(fls);
	const bool lock_team   = side->cfg()["team_lock"].to_bool(fls);
	const bool lock_color  = side->cfg()["color_lock"].to_bool(fls);

	const bool saved_game = connect_engine_.params().saved_game;

	//
	// AI Algorithm
	//
	int selection = 0;

	// We use an index-based loop in order to get the index of the selected option
	std::vector<config> ai_options;
	for(unsigned i = 0; i < ai_algorithms_.size(); i++) {
		ai_options.push_back(config_of("label", ai_algorithms_[i]->text));

		if(ai_algorithms_[i]->id == side->ai_algorithm()) {
			selection = i;
		}
	}

	menu_button& ai_selection = find_widget<menu_button>(&row_grid, "ai_controller", false);

	ai_selection.set_values(ai_options, selection);
	ai_selection.connect_click_handler(std::bind(&mp_staging::on_ai_select, this, side, std::ref(ai_selection)));

	on_ai_select(side, ai_selection);

	//
	// Controller
	//
	std::vector<config> controller_names;
	for(const auto& controller : side->controller_options()) {
		controller_names.push_back(config_of("label", controller.second));
	}

	menu_button& controller_selection = find_widget<menu_button>(&row_grid, "controller", false);

	controller_selection.set_values(controller_names, side->current_controller_index());
	controller_selection.set_active(controller_names.size() > 1);
	controller_selection.connect_click_handler(std::bind(&mp_staging::on_controller_select, this, side, std::ref(row_grid)));

	on_controller_select(side, row_grid);

	//
	// Leader controls
	//
	button& leader_select = find_widget<button>(&row_grid, "select_leader", false);

	leader_select.set_active(!saved_game);

	connect_signal_mouse_left_click(leader_select,
		std::bind(&mp_staging::select_leader_callback, this, std::ref(window), side, std::ref(row_grid)));

	//
	// Team
	//
	std::vector<config> team_names;
	for(const auto& team : side->player_teams()) {
		team_names.push_back(config_of("label", team));
	}

	menu_button& team_selection = find_widget<menu_button>(&row_grid, "side_team", false);

	// HACK: side->team() does not get its index from side->player_teams(), but rather side->team_names().
	// As such, the index is off if there is only 1 playable team. This is a hack to make sure the menu_button
	// widget doesn't assert with the invalid initial selection. The connect_engine should be fixed once the GUI1
	// dialog is dropped
	team_selection.set_values(team_names, std::min<int>(team_names.size() - 1, side->team()));
	team_selection.set_active(!saved_game);
	team_selection.connect_click_handler(std::bind(&mp_staging::on_team_select, this, std::ref(window), side, std::ref(team_selection), _3, _4));

	//
	// Colors
	//
	std::vector<config> color_options;
	for(const auto& color : side->color_options()) {
		color_options.push_back(config_of
			("label", font::get_color_string_pango(color))
			("icon", (formatter() << "misc/status.png~RC(magenta>" << color << ")").str())
		);
	}

	menu_button& color_selection = find_widget<menu_button>(&row_grid, "side_color", false);

	color_selection.set_values(color_options, side->color());
	color_selection.set_active(!saved_game);
	color_selection.set_use_markup(true);
	color_selection.connect_click_handler(std::bind(&mp_staging::on_color_select, this, side, std::ref(row_grid)));

	//
	// Gold and Income
	//
	slider& slider_gold = find_widget<slider>(&row_grid, "side_gold_slider", false);
	slider_gold.set_value(side->cfg()["gold"].to_int(100));

	connect_signal_notify_modified(slider_gold, std::bind(
		&mp_staging::on_side_slider_change<&ng::side_engine::set_gold>, this, side, std::ref(slider_gold)));

	slider& slider_income = find_widget<slider>(&row_grid, "side_income_slider", false);
	slider_income.set_value(side->cfg()["income"]);

	connect_signal_notify_modified(slider_income, std::bind(
		&mp_staging::on_side_slider_change<&ng::side_engine::set_income>, this, side, std::ref(slider_income)));

	// TODO: maybe display the saved values
	if(saved_game) {
		slider_gold.set_visible(widget::visibility::invisible);
		slider_income.set_visible(widget::visibility::invisible);
	}

	//
	// Gold, income, team, and color are only suggestions unless explicitly locked
	//
	if(!saved_game && ums) {
		team_selection.set_active(!lock_team);
		color_selection.set_active(!lock_color);

		slider_gold.set_active(!lock_gold);
		slider_income.set_active(!lock_income);
	}
}
Exemplo n.º 25
0
void tunit_create::pre_show(CVideo& /*video*/, twindow& window)
{
	ttoggle_button& male_toggle
			= find_widget<ttoggle_button>(&window, "male_toggle", false);
	ttoggle_button& female_toggle
			= find_widget<ttoggle_button>(&window, "female_toggle", false);
	tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false);

	ttext_box* filter
			= find_widget<ttext_box>(&window, "filter_box", false, true);

	filter->set_text_changed_callback(
			boost::bind(&tunit_create::filter_text_changed, this, _1, _2));

#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(*list,
								   boost::bind(&tunit_create::list_item_clicked,
											   *this,
											   boost::ref(window)));
#else
	list.set_callback_value_change(
			dialog_callback<tunit_create, &tunit_create::list_item_clicked>);
#endif

	window.keyboard_capture(&list);

	connect_signal_mouse_left_click(
			find_widget<tbutton>(&window, "type_profile", false),
			boost::bind(&tunit_create::profile_button_callback,
						this,
						boost::ref(window)));

	male_toggle.set_callback_state_change(
			dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>);

	female_toggle.set_callback_state_change(
			dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>);

	update_male_female_toggles(male_toggle, female_toggle, gender_);

	list.clear();

	FOREACH(const AUTO & i, unit_types.types())
	{
		if(i.second.do_not_list())
			continue;

		// Make sure this unit type is built with the data we need.
		unit_types.build_unit_type(i.second, unit_type::WITHOUT_ANIMATIONS);

		units_.push_back(&i.second);

		std::map<std::string, string_map> row_data;
		string_map column;

		column["label"] = units_.back()->race()->plural_name();
		row_data.insert(std::make_pair("race", column));
		column["label"] = units_.back()->type_name();
		row_data.insert(std::make_pair("unit_type", column));

		list.add_row(row_data);

		// Select the previous choice, if any.
		if(choice_.empty() != true && choice_ == i.first) {
			list.select_row(list.get_item_count() - 1);
		}
	}

	if(units_.empty()) {
		ERR_GUI_G << "no unit types found for unit create dialog; not good"
				  << std::endl;
	}

	std::vector<tgenerator_::torder_func> order_funcs(2);
	order_funcs[0] = boost::bind(&tunit_create::compare_race, this, _1, _2);
	order_funcs[1] = boost::bind(&tunit_create::compare_race_rev, this, _1, _2);
	list.set_column_order(0, order_funcs);
	order_funcs[0] = boost::bind(&tunit_create::compare_type, this, _1, _2);
	order_funcs[1] = boost::bind(&tunit_create::compare_type_rev, this, _1, _2);
	list.set_column_order(1, order_funcs);

	list_item_clicked(window);
}
Exemplo n.º 26
0
void mp_options_helper::display_custom_options(const std::string& type, int node_position, const config& cfg)
{
	// Needed since some compilers don't like passing just {}
	static const std::map<std::string, string_map> empty_map;

	// This ensures that any game, era, or mod with no options doesn't get an entry in the visible_options_
	// vector and prevents invalid options from different games, era, or mods being created when the options
	// config is created.
	if(!cfg.has_child("options")) {
		return;
	}

	visible_options_.push_back({type, cfg["id"]});

	// Get the node vector for this specific source type
	node_vector& type_node_vector = node_data_map_[type].nodes;

	for(const auto& options : cfg.child_range("options")) {
		std::map<std::string, string_map> data;
		string_map item;

		item["label"] = cfg["name"];
		data.emplace("tree_view_node_label", item);

		tree_view_node& option_node = options_tree_.add_node("option_node", data, node_position);
		type_node_vector.push_back(&option_node);

		for(const config::any_child& opt : options.all_children_range()) {
			data.clear();
			item.clear();

			const config& option_cfg = opt.cfg;

			const auto add_name = [&](const std::string& id) {
				item["label"] = option_cfg["name"];
				data.emplace(id, item);
			};

			config::attribute_value val;

			if(opt.key == "checkbox") {
				add_name("option_checkbox");

				toggle_button* checkbox;
				std::tie(checkbox, val) = add_node_and_get_widget<toggle_button>(option_node, "option_checkbox", data, option_cfg);

				checkbox->set_value(val.to_bool());

				connect_signal_notify_modified(*checkbox,
					std::bind(&mp_options_helper::update_options_data_map<toggle_button>, this, checkbox, visible_options_.back()));

			} else if(opt.key == "spacer") {
				option_node.add_child("options_spacer_node", empty_map);

			} else if(opt.key == "choice" || opt.key == "combo") {
				if(opt.key == "combo") {
					deprecated_message("combo", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use [choice] instead.");
				}

				if(!option_cfg.has_child("item")) {
					continue;
				}

				add_name("menu_button_label");

				std::vector<config> combo_items;
				std::vector<std::string> combo_values;

				for(auto i : option_cfg.child_range("item")) {
					// Comboboxes expect this key to be 'label' not 'name'
					i["label"] = i["name"];

					combo_items.push_back(i);
					combo_values.push_back(i["value"]);
				}

				menu_button* menu;
				std::tie(menu, val) = add_node_and_get_widget<menu_button>(option_node, "option_menu_button", data, option_cfg);

				// Needs to be called before set_selected
				menu->set_values(combo_items);

				auto iter = std::find(combo_values.begin(), combo_values.end(), val.str());

				if(iter != combo_values.end()) {
					menu->set_selected(std::distance(combo_values.begin(), iter));
				}

				connect_signal_notify_modified(*menu,
					std::bind(&mp_options_helper::update_options_data_map_menu_button, this, menu, visible_options_.back(), option_cfg));

			} else if(opt.key == "slider") {
				add_name("slider_label");

				slider* slide;
				std::tie(slide, val) = add_node_and_get_widget<slider>(option_node, "option_slider", data, option_cfg);

				slide->set_value_range(option_cfg["min"].to_int(), option_cfg["max"].to_int());
				slide->set_step_size(option_cfg["step"].to_int(1));
				slide->set_value(val.to_int());

				connect_signal_notify_modified(*slide,
					std::bind(&mp_options_helper::update_options_data_map<slider>, this, slide, visible_options_.back()));

			} else if(opt.key == "entry") {
				add_name("text_entry_label");

				text_box* textbox;
				std::tie(textbox, val) = add_node_and_get_widget<text_box>(option_node, "option_text_entry", data, option_cfg);

				textbox->set_value(val.str());
				textbox->set_text_changed_callback(
					std::bind(&mp_options_helper::update_options_data_map<text_box>, this, textbox, visible_options_.back()));
			}
		}

		// Add the Defaults button at the end
		tree_view_node& node = option_node.add_child("options_default_button", empty_map);

		connect_signal_mouse_left_click(find_widget<button>(&node, "reset_option_values", false),
			std::bind(&mp_options_helper::reset_options_data, this, visible_options_.back(),
				std::placeholders::_3, std::placeholders::_4));
	}
}
void tcampaign_selection::pre_show(CVideo& /*video*/, twindow& window)
{
	/***** Setup campaign list. *****/
	tlistbox& list =
			find_widget<tlistbox>(&window, "campaign_list", false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
	connect_signal_notify_modified(list, boost::bind(
			  &tcampaign_selection::campaign_selected
			, this
			, boost::ref(window)));
#else
	list.set_callback_value_change(dialog_callback
			<tcampaign_selection
			, &tcampaign_selection::campaign_selected>);
#endif
	window.keyboard_capture(&list);

	/***** Setup campaign details. *****/

	tmulti_page& multi_page = find_widget<tmulti_page>(
			&window, "campaign_details", false);

	size_t n = 0;
	foreach (const config &c, campaigns_) {
		if (c["id"] == "tutorial") {
			n ++;
			continue;
		}
		/*** Add list item ***/
		string_map list_item;
		std::map<std::string, string_map> list_item_item;

		list_item["label"] = c["icon"];
		list_item_item.insert(std::make_pair("icon", list_item));

		list_item["label"] = c["name"];
		list_item_item.insert(std::make_pair("name", list_item));

		list.add_row(list_item_item);

		tgrid* grid = list.get_row_grid(list.get_item_count() - 1);
		assert(grid);

		tcontrol* widget = dynamic_cast<tcontrol*>(grid->find("mode", false));
		if (widget) {
			const std::string& mode = c["mode"].str();
			if (mode == "rpg") {
				widget->set_label("misc/mode-rpg.png");
			} else if (mode == "tower") {
				widget->set_label("misc/mode-tower.png");
			}
		}

		ttoggle_panel* toggle = dynamic_cast<ttoggle_panel*>(grid->find("_toggle", true));
		toggle->set_data(n ++);

		/*** Add detail item ***/
		string_map detail_item;
		std::map<std::string, string_map> detail_page;

		detail_item["label"] = c["description"];
		detail_item["use_markup"] = "true";
		detail_page.insert(std::make_pair("description", detail_item));

		detail_item["label"] = c["image"];
		detail_page.insert(std::make_pair("image", detail_item));

		multi_page.add_page(detail_page);
	}

	campaign_selected(window);
}
Exemplo n.º 28
0
void mp_staging::add_side_node(window& window, ng::side_engine_ptr side)
{
	std::map<std::string, string_map> data;
	string_map item;

	item["label"] = std::to_string(side->index() + 1);
	data.emplace("side_number", item);

	// TODO: don't hardcode magenta?
	item["label"] = "units/unknown-unit.png~RC(magenta>" + side->color_id() + ")";
	data.emplace("leader_image", item);

	item["label"] = "icons/icon-random.png";
	data.emplace("leader_gender", item);

	tree_view_node& node = team_tree_map_[side->team_name()]->add_child("side_panel", data, get_side_node_position(side));

	side_tree_map_[side] = &node;

	grid& row_grid = node.get_grid();

	update_leader_display(side, row_grid);

	// Status variables
	const bool fls = connect_engine_.force_lock_settings();
	const bool ums = connect_engine_.params().use_map_settings;

	const bool lock_gold   = side->cfg()["gold_lock"].to_bool(fls);
	const bool lock_income = side->cfg()["income_lock"].to_bool(fls);
	const bool lock_team   = side->cfg()["team_lock"].to_bool(fls);
	const bool lock_color  = side->cfg()["color_lock"].to_bool(fls);

	const bool saved_game = connect_engine_.params().saved_game == mp_game_settings::SAVED_GAME_MODE::MIDGAME;

	//
	// AI Algorithm
	//
	int selection = 0;

	// We use an index-based loop in order to get the index of the selected option
	std::vector<config> ai_options;
	// If this is loading a saved game, we add an option at the beginning of the menu.
	// This results in a mismatch between the indices of ai_options and ai_algorithms_
	// that we need to account for later.
	if(saved_game) {
		ai_options.emplace_back("label", "Keep saved AI");
	}
	for(unsigned i = 0; i < ai_algorithms_.size(); ++i) {
		ai_options.emplace_back("label", ai_algorithms_[i]->text);

		if(ai_algorithms_[i]->id == side->ai_algorithm()) {
			selection = i;
		}
	}

	menu_button& ai_selection = find_widget<menu_button>(&row_grid, "ai_controller", false);

	ai_selection.set_values(ai_options, selection);

	connect_signal_notify_modified(ai_selection,
		std::bind(&mp_staging::on_ai_select, this, side, std::ref(ai_selection), saved_game));

	on_ai_select(side, ai_selection, saved_game);
	//
	// Controller
	//
	std::vector<config> controller_names;
	for(const auto& controller : side->controller_options()) {
		controller_names.emplace_back("label", controller.second);
	}

	menu_button& controller_selection = find_widget<menu_button>(&row_grid, "controller", false);

	controller_selection.set_values(controller_names, side->current_controller_index());
	controller_selection.set_active(controller_names.size() > 1);

	connect_signal_notify_modified(controller_selection,
		std::bind(&mp_staging::on_controller_select, this, side, std::ref(row_grid)));

	on_controller_select(side, row_grid);

	//
	// Leader controls
	//
	button& leader_select = find_widget<button>(&row_grid, "select_leader", false);

	//todo: shouldn't this also be disabled when the flg settings are locked.
	leader_select.set_active(!saved_game);

	connect_signal_mouse_left_click(leader_select,
		std::bind(&mp_staging::select_leader_callback, this, side, std::ref(row_grid)));

	//
	// Team
	//
	std::vector<config> team_names;
	unsigned initial_team_selection = 0;

	for(unsigned i = 0; i < connect_engine_.team_data().size(); ++i) {
		const ng::connect_engine::team_data_pod& tdata = connect_engine_.team_data()[i];

		if(!tdata.is_player_team && !game_config::debug) {
			continue;
		}

		config entry;
		entry["label"] = t_string::from_serialized(tdata.user_team_name);

		// Since we're not necessarily displaying every every team, we need to store the
		// index a displayed team has in the connect_engine's team_data vector. This is
		// then utilized in the click callback.
		entry["team_index"] = i;

		team_names.push_back(std::move(entry));

		// Since, again, every team might not be displayed, and side_engine::team() returns
		// an index into the team_data vector, get an initial selection index for the menu
		// adjusted for the displayed named.
		if(side->team() == i) {
			initial_team_selection = team_names.size() - 1;
		}
	}

	menu_button& team_selection = find_widget<menu_button>(&row_grid, "side_team", false);

	team_selection.set_values(team_names, initial_team_selection);
	//todo: shouldn't this also be disabled when team settings are locked.
	team_selection.set_active(!saved_game);

	connect_signal_notify_modified(team_selection,
		std::bind(&mp_staging::on_team_select, this, std::ref(window), side, std::ref(team_selection)));

	//
	// Colors
	//
	std::vector<config> color_options;
	for(const auto& color : side->color_options()) {
		color_options.emplace_back(
			"label", font::get_color_string_pango(color),
			"icon", (formatter() << "misc/status.png~RC(magenta>" << color << ")").str()
		);
	}

	menu_button& color_selection = find_widget<menu_button>(&row_grid, "side_color", false);

	color_selection.set_values(color_options, side->color());
	color_selection.set_active(!saved_game);
	color_selection.set_use_markup(true);

	connect_signal_notify_modified(color_selection,
		std::bind(&mp_staging::on_color_select, this, side, std::ref(row_grid)));

	//
	// Gold and Income
	//
	const auto slider_setup_helper = [](slider& slider, const int value) {
		// For the gold and income sliders, the usual min and max values are set in
		// the dialog WML. However, if a side specifies a value out of that range,
		// we adjust the bounds to accommodate it.
		slider.set_value_range(
			std::min(value, slider.get_minimum_value()),
			std::max(value, slider.get_maximum_value())
		);

		slider.set_value(value);
	};

	slider& slider_gold = find_widget<slider>(&row_grid, "side_gold_slider", false);
	slider_setup_helper(slider_gold, side->gold());

	connect_signal_notify_modified(slider_gold, std::bind(
		&mp_staging::on_side_slider_change<&ng::side_engine::set_gold>, this, side, std::ref(slider_gold)));

	slider& slider_income = find_widget<slider>(&row_grid, "side_income_slider", false);
	slider_setup_helper(slider_income, side->income());

	connect_signal_notify_modified(slider_income, std::bind(
		&mp_staging::on_side_slider_change<&ng::side_engine::set_income>, this, side, std::ref(slider_income)));

	// TODO: maybe display the saved values
	if(saved_game) {
		slider_gold.set_visible(widget::visibility::invisible);
		slider_income.set_visible(widget::visibility::invisible);
	}

	//
	// Gold, income, team, and color are only suggestions unless explicitly locked
	//
	if(!saved_game && ums) {
		team_selection.set_active(!lock_team);
		color_selection.set_active(!lock_color);

		slider_gold.set_active(!lock_gold);
		slider_income.set_active(!lock_income);
	}
}