GUI1 multi-selection menu widget.
This commit is contained in:
parent
116991f618
commit
daa214072b
5 changed files with 179 additions and 12 deletions
|
@ -1092,6 +1092,7 @@ set(libwesnoth-game_STAT_SRC
|
|||
widgets/label.cpp
|
||||
widgets/menu.cpp
|
||||
widgets/menu_style.cpp
|
||||
widgets/multimenu.cpp
|
||||
widgets/progressbar.cpp
|
||||
widgets/scrollarea.cpp
|
||||
widgets/scrollbar.cpp
|
||||
|
|
|
@ -137,6 +137,7 @@ libwesnoth_sources = Split("""
|
|||
widgets/label.cpp
|
||||
widgets/menu.cpp
|
||||
widgets/menu_style.cpp
|
||||
widgets/multimenu.cpp
|
||||
widgets/progressbar.cpp
|
||||
widgets/scrollarea.cpp
|
||||
widgets/scrollbar.cpp
|
||||
|
|
|
@ -182,7 +182,7 @@ public:
|
|||
// allows user to change_item while running (dangerous)
|
||||
void change_item(int pos1,int pos2,const std::string& str);
|
||||
|
||||
void erase_item(size_t index);
|
||||
virtual void erase_item(size_t index);
|
||||
|
||||
void set_heading(const std::vector<std::string>& heading);
|
||||
|
||||
|
@ -190,7 +190,7 @@ public:
|
|||
/// strip_spaces is false, spaces will remain at the item edges. If
|
||||
/// keep_viewport is true, the menu tries to keep the selection at
|
||||
/// the same position as it were before the items were set.
|
||||
void set_items(const std::vector<std::string>& items, bool strip_spaces=true,
|
||||
virtual void set_items(const std::vector<std::string>& items, bool strip_spaces=true,
|
||||
bool keep_viewport=false);
|
||||
|
||||
/// Set a new max height for this menu. Note that this does not take
|
||||
|
@ -228,6 +228,18 @@ protected:
|
|||
|
||||
style *style_;
|
||||
bool silent_;
|
||||
|
||||
int hit(int x, int y) const;
|
||||
|
||||
std::pair<int,int> hit_cell(int x, int y) const;
|
||||
int hit_column(int x) const;
|
||||
|
||||
int hit_heading(int x, int y) const;
|
||||
|
||||
void invalidate_row(size_t id);
|
||||
void invalidate_row_pos(size_t pos);
|
||||
void invalidate_heading();
|
||||
|
||||
private:
|
||||
size_t max_items_onscreen() const;
|
||||
|
||||
|
@ -268,12 +280,6 @@ private:
|
|||
void clear_item(int item);
|
||||
void draw_contents();
|
||||
void draw();
|
||||
int hit(int x, int y) const;
|
||||
|
||||
std::pair<int,int> hit_cell(int x, int y) const;
|
||||
int hit_column(int x) const;
|
||||
|
||||
int hit_heading(int x, int y) const;
|
||||
|
||||
mutable std::map<int,SDL_Rect> itemRects_;
|
||||
|
||||
|
@ -320,10 +326,6 @@ private:
|
|||
void move_selection_up(size_t dep);
|
||||
void move_selection_down(size_t dep);
|
||||
|
||||
void invalidate_row(size_t id);
|
||||
void invalidate_row_pos(size_t pos);
|
||||
void invalidate_heading();
|
||||
|
||||
std::set<int> invalid_;
|
||||
};
|
||||
|
||||
|
|
80
src/widgets/multimenu.cpp
Normal file
80
src/widgets/multimenu.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright (C) 2015 by Boldizsár Lipka <lipkab@zoho.com>
|
||||
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 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.
|
||||
*/
|
||||
|
||||
#include "multimenu.hpp"
|
||||
#include "image.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
namespace gui {
|
||||
multimenu::multimenu(CVideo &video, const std::vector<std::string> &items, bool click_selects, int max_height,
|
||||
int max_width, const menu::sorter *sorter_obj, menu::style *menu_style, const bool auto_join) :
|
||||
menu(video, items, click_selects, max_height, max_width, sorter_obj, menu_style, auto_join),
|
||||
active_items_(items.size(), false) {}
|
||||
|
||||
void multimenu::draw_row(const size_t row_index, const SDL_Rect &rect, menu::ROW_TYPE type) {
|
||||
surface img = image::get_image(active_items_[row_index]
|
||||
? "buttons/checkbox-pressed.png"
|
||||
: "buttons/checkbox.png");
|
||||
blit_surface(img, NULL, video().getSurface(), &rect);
|
||||
SDL_Rect newrect = {
|
||||
(Sint16) (rect.x + img->w + 2),
|
||||
rect.y,
|
||||
(Uint16) (rect.w - img->w - 2),
|
||||
rect.h
|
||||
};
|
||||
menu::draw_row(row_index, newrect, type);
|
||||
}
|
||||
|
||||
void multimenu::handle_event(const SDL_Event &event) {
|
||||
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
||||
int hit_box = hit_checkbox(event.button.x, event.button.y);
|
||||
if (hit_box != -1) {
|
||||
active_items_[hit_box] = !active_items_[hit_box];
|
||||
invalidate_row_pos(hit_box);
|
||||
last_changed_ = hit_box;
|
||||
return;
|
||||
}
|
||||
}
|
||||
menu::handle_event(event);
|
||||
}
|
||||
|
||||
int multimenu::hit_checkbox(int x, int y) const {
|
||||
int cb_width = image::get_image("buttons/checkbox-pressed.png")->w;
|
||||
return x > inner_location().x + cb_width ? -1 : hit(x, y);
|
||||
}
|
||||
|
||||
void multimenu::erase_item(size_t index) {
|
||||
active_items_.erase(active_items_.begin() + index);
|
||||
menu::erase_item(index);
|
||||
last_changed_ = -1;
|
||||
}
|
||||
|
||||
void multimenu::set_items(const std::vector<std::string> &items, bool strip_spaces, bool keep_viewport) {
|
||||
active_items_.resize(items.size());
|
||||
std::fill(active_items_.begin(), active_items_.end(), false);
|
||||
last_changed_ = -1;
|
||||
menu::set_items(items, strip_spaces, keep_viewport);
|
||||
}
|
||||
|
||||
void multimenu::set_active(size_t index, bool active) {
|
||||
active_items_[index] = active;
|
||||
invalidate_row_pos(index);
|
||||
}
|
||||
|
||||
int multimenu::last_changed() {
|
||||
int result = last_changed_;
|
||||
last_changed_ = -1;
|
||||
return result;
|
||||
}
|
||||
}
|
83
src/widgets/multimenu.hpp
Normal file
83
src/widgets/multimenu.hpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright (C) 2015 by Boldizsár Lipka <lipkab@zoho.com>
|
||||
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 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 WIDGETS_MULTIMENU_HPP_INCLUDED
|
||||
#define WIDGETS_MULTIMENU_HPP_INCLUDED
|
||||
|
||||
#include "menu.hpp"
|
||||
|
||||
namespace gui {
|
||||
|
||||
/**
|
||||
* A widget that additionally to the normal menu contents also displays a
|
||||
* checkbox in each row. An item is considered 'active' if its checkbox is checked,
|
||||
* 'inactive' otherwise.
|
||||
*/
|
||||
class multimenu : public menu {
|
||||
public:
|
||||
multimenu(CVideo& video, const std::vector<std::string>& items,
|
||||
bool click_selects=false, int max_height=-1, int max_width=-1,
|
||||
const sorter* sorter_obj=NULL, style *menu_style=NULL, const bool auto_join=true);
|
||||
|
||||
|
||||
void set_active(size_t index, bool active=true);
|
||||
|
||||
/**
|
||||
* Tells if an item is activated.
|
||||
*
|
||||
* @param index the item's index
|
||||
* @return true if the item is active, false if not
|
||||
*/
|
||||
bool is_active(size_t index) const { return active_items_[index]; }
|
||||
|
||||
/**
|
||||
* Tell each items status
|
||||
*
|
||||
* @return a vector of bools. The n-th item is active if the vector's n-th item is true
|
||||
*/
|
||||
const std::vector<bool> &active_items() const { return active_items_; }
|
||||
|
||||
virtual void erase_item(size_t index);
|
||||
virtual void set_items(const std::vector<std::string>& items, bool strip_spaces=true,
|
||||
bool keep_viewport=false);
|
||||
|
||||
/**
|
||||
* Returns the item last activated/deactivated. Items changed via set_active
|
||||
* don't count, Invoking this function will set the last changed index to -1.
|
||||
*
|
||||
* @return the item's index, or -1 if no item was changed since the last
|
||||
* invokation
|
||||
*/
|
||||
int last_changed();
|
||||
|
||||
protected:
|
||||
virtual void draw_row(const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
|
||||
virtual void handle_event(const SDL_Event& event);
|
||||
|
||||
/**
|
||||
* Determine which checkbox was hit by a mouse click.
|
||||
*
|
||||
* @param x the x coordinate of the click
|
||||
* @param y the y coordinate of the click
|
||||
* @return the row whose checkbox was clicked on, or -1 if the click didn't hit a checkbox
|
||||
*/
|
||||
int hit_checkbox(int x, int y) const;
|
||||
|
||||
private:
|
||||
std::vector<bool> active_items_;
|
||||
int last_changed_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue