wesnoth/src/gui/widgets/listbox.hpp
2009-07-04 12:04:37 +00:00

247 lines
7.7 KiB
C++

/* $Id$ */
/*
Copyright (C) 2008 - 2009 by Mark de Wever <koraq@xs4all.nl>
Part of 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 version 2
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_LISTBOX_HPP_INCLUDED
#define GUI_WIDGETS_LISTBOX_HPP_INCLUDED
#include "gui/widgets/generator.hpp"
#include "gui/widgets/scrollbar_container.hpp"
namespace gui2 {
namespace implementation {
struct tbuilder_listbox;
}
/** The listbox class. */
class tlistbox
: public tscrollbar_container
{
friend struct implementation::tbuilder_listbox;
friend class tdebug_layout_graph;
public:
/**
* Constructor.
*
* @param has_minimum Does the listbox need to have one item
* selected.
* @param has_maximum Can the listbox only have one item
* selected.
* @param placement How are the items placed.
* @param select Select an item when selected, if false it
* changes the visible state instead.
*/
tlistbox(const bool has_minimum, const bool has_maximum,
const tgenerator_::tplacement placement, const bool select);
/***** ***** ***** ***** Row handling. ***** ***** ****** *****/
/**
* When an item in the list is selected by the user we need to
* update the state. We installed a callback handler which
* calls us.
*/
void add_row(const string_map& item);
/**
* Adds single row to the grid.
*
* This function expect a row to have multiple widgets (either multiple
* columns or one column with multiple widgets).
*
*
* @param data The data to send to the set_members of the
* widgets. If the member id is not an empty
* string it is only send to the widget that has
* the wanted id (if any). If the member id is an
* empty string, it is send to all members.
* Having both empty and non-empty id's gives
* undefined behaviour.
*/
void add_row(const std::map<std::string /* widget id */,
string_map>& data);
/** Returns the number of items in the listbox. */
unsigned get_item_count() const;
/**
* Makes a row active or inactive.
*
* NOTE this doesn't change the select status of the row.
*
* @param row The row to (de)activate.
* @param select true activate, false deactivate.
*/
void set_row_active(const unsigned row, const bool active);
/**
* Returns the grid of the wanted row.
*
* There's only a const version since allowing callers to modify the grid
* behind our backs might give problems. We return a pointer instead of a
* reference since dynamic casting of pointers is easier (no try catch
* needed).
*
* @param row The row to get the grid from, the caller has
* to make sure the row is a valid row.
* @returns The grid of the wanted row.
*/
const tgrid* get_row_grid(const unsigned row) const;
/**
* The possibly-giving-problems nonconst version of get_row_grid
*
* @param row The row to get the grid from, the caller has
* to make sure the row is a valid row.
* @returns The grid of the wanted row.
*/
tgrid* get_row_grid(const unsigned row);
/**
* Selectes a row.
*
* @param row The row to select.
* @param select Select or deselect the row.
*/
bool select_row(const unsigned row, const bool select = true);
/**
* Returns the first selected row
*
* @returns The first selected row.
* @retval -1 No row selected.
*/
int get_selected_row() const;
/** Function to call after the user clicked on a row. */
void list_item_clicked(twidget* caller);
/** Inherited from tcontainer_. */
void set_self_active(const bool /*active*/) {}
// { state_ = active ? ENABLED : DISABLED; }
//
/***** ***** ***** ***** inherited ***** ***** ****** *****/
/** Inherited from tscrollbar_container. */
void child_populate_dirty_list(twindow& caller,
const std::vector<twidget*>& call_stack);
/***** ***** ***** setters / getters for members ***** ****** *****/
void set_callback_value_change(void (*callback) (twidget* caller))
{ callback_value_changed_ = callback; }
void set_list_builder(tbuilder_grid_ptr list_builder)
{ list_builder_ = list_builder; }
protected:
/***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
/** Inherited from tscrollbar_container. */
void handle_key_up_arrow(SDLMod modifier, bool& handled);
/** Inherited from tscrollbar_container. */
void handle_key_down_arrow(SDLMod modifier, bool& handled);
/** Inherited from tscrollbar_container. */
void handle_key_left_arrow(SDLMod modifier, bool& handled);
/** Inherited from tscrollbar_container. */
void handle_key_right_arrow(SDLMod modifier, bool& handled);
private:
/**
* @todo A listbox must have the following config parameters in the
* instanciation:
* - fixed row height?
* - fixed column width?
* and if so the following ways to set them
* - fixed depending on header ids
* - fixed depending on footer ids
* - fixed depending on first row ids
* - fixed depending on list (the user has to enter a list of ids)
*
* For now it's always fixed width depending on the first row.
*/
/**
* Initializes the linked size list.
*
* The routine goes from begin to end through the widgets and if the widget
* has an id it's used to initialize the linked size list of the parent
* window. If the widget is a container all it's children are also
* initialized.
*
* @param window The parent window.
* @param begin Begin iterator.
* @param end End iterator.
*/
void init_linked_size_widets(twindow& window,
const tgrid::iterator& begin, const tgrid::iterator& end);
/**
* Adds widgets to the linked size list.
*
* The routine goes from begin to end through the widgets and if the widget
* has an id it's added to the linked size list of the parent window. If
* the widget is a container all it's children are also added.
*
* @param window The parent window.
* @param begin Begin iterator.
* @param end End iterator.
*/
void add_linked_size_widgets(twindow& window,
const tgrid::iterator& begin, const tgrid::iterator& end);
/**
* Finishes the building initialization of the widget.
*
* @param header Builder for the header.
* @param footer Builder for the footer.
* @param list_data The initial data to fill the listbox with.
*/
void finalize(
tbuilder_grid_const_ptr header,
tbuilder_grid_const_ptr footer,
const std::vector<string_map>& list_data);
/**
* Contains a pointer to the generator.
*
* The pointer is not owned by this variable.
*/
tgenerator_* generator_;
/** Contains the builder for the new items. */
tbuilder_grid_const_ptr list_builder_;
/**
* This callback is called when the value in the listbox changes.
*
* @todo the implementation of the callback hasn't been tested a lot and
* there might be too many calls. That might happen if an arrow up didn't
* change the selected item.
*/
void (*callback_value_changed_) (twidget*);
/** Inherited from tcontrol. */
const std::string& get_control_type() const
{ static const std::string type = "listbox"; return type; }
};
} // namespace gui2
#endif