Add a proof of concept new container class.

With the change of the drawing engine a rewrite of the containers is
needed as well. This adds a new container class which the scroll_label
uses. The class can't forward events and also the scrollbars are
always visible.
This commit is contained in:
Mark de Wever 2008-12-08 21:26:35 +00:00
parent 8bf7cbad4a
commit fba341cd49
12 changed files with 1049 additions and 9 deletions

View file

@ -151,3 +151,227 @@
[/scroll_label_definition]
#undef _GUI_RESOLUTION
#ifdef NEW_DRAW
#define _GUI_VERTICAL_SCROLLBAR_GRID
vertical_grow = "true"
[grid]
id = "_vertical_scrollbar_grid"
[row]
[column]
# note we want a special button definition for this later.
[button]
id = "_half_page_up"
definition = "up_arrow"
[/button]
[/column]
[/row]
[row]
grow_factor = 1
[column]
vertical_grow = "true"
[vertical_scrollbar]
id = "_vertical_scrollbar"
definition = "default"
[/vertical_scrollbar]
[/column]
[/row]
[row]
[column]
# note we want a special button definition for this later.
[button]
id = "_half_page_down"
definition = "down_arrow"
[/button]
[/column]
[/row]
[/grid]
#enddef
#define _GUI_HORIZONTAL_SCROLLBAR_GRID
horizontal_grow = "true"
[grid]
id = "_horizontal_scrollbar_grid"
[row]
[column]
# note we want a special button definition for this later.
[button]
id = "_half_page_left"
definition = "left_arrow"
[/button]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
[horizontal_scrollbar]
id = "_horizontal_scrollbar"
definition = "default"
[/horizontal_scrollbar]
[/column]
[column]
# note we want a special button definition for this later.
[button]
id = "_half_page_right"
definition = "right_arrow"
[/button]
[/column]
[/row]
[/grid]
#enddef
#define _GUI_RESOLUTION RESOLUTION FONT_SIZE FONT_STYLE FONT_COLOUR_ENABLED FONT_COLOUR_DISABLED
[resolution]
{RESOLUTION}
min_width = 0
min_height = 0
default_width = 0
default_height = 0
max_width = 0
max_height = 0
text_font_size = {FONT_SIZE}
text_font_style = {FONT_STYLE}
[state_enabled]
full_redraw = "true"
[draw]
[/draw]
[/state_enabled]
[state_disabled]
full_redraw = "true"
[draw]
[/draw]
[/state_disabled]
[grid]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = "true" # needed ?
vertical_grow = "true" # needed ?
[grid]
id = "_content_grid"
[row]
[column]
horizontal_grow = "true"
vertical_grow = "true"
[label]
id = "_label"
definition = "default"
[/label]
[/column]
[/row]
[/grid]
[/column]
[column]
{_GUI_VERTICAL_SCROLLBAR_GRID}
[/column]
[/row]
[row]
[column]
{_GUI_HORIZONTAL_SCROLLBAR_GRID}
[/column]
[column]
[spacer]
[/spacer]
[/column]
[/row]
[/grid]
[/resolution]
#enddef
[scroll_label_definition]
id = "test"
description = "Testing version."
{_GUI_RESOLUTION
({GUI_TINY__RESOLUTION})
({GUI_TINY__FONT_SIZE__DEFAULT})
()
({GUI__FONT_COLOUR_ENABLED__DEFAULT})
({GUI__FONT_COLOUR_DISABLED__DEFAULT})
}
{_GUI_RESOLUTION
({GUI_NORMAL__RESOLUTION})
({GUI_NORMAL__FONT_SIZE__DEFAULT})
()
({GUI__FONT_COLOUR_ENABLED__DEFAULT})
({GUI__FONT_COLOUR_DISABLED__DEFAULT})
}
[/scroll_label_definition]
#undef _GUI_VERTICAL_SCROLLBAR_GRID
#undef _GUI_HORIZONTAL_SCROLLBAR_GRID
#undef _GUI_RESOLUTION
#endif

View file

@ -393,7 +393,11 @@
[scroll_label] # NOTE maybe change the code to use message instead of label as id
id = "label"
#ifdef NEW_DRAW
definition = "test"
#else
definition = "default"
#endif
[/scroll_label]
[/column]
@ -607,7 +611,11 @@
[scroll_label]
id = "label"
definition = "default"
#ifdef NEW_DRAW
definition = "test"
#else
definition = "default"
#endif
[/scroll_label]
[/column]

View file

@ -29,6 +29,7 @@ src/gui/widgets/menubar.cpp
src/gui/widgets/minimap.cpp
src/gui/widgets/panel.cpp
src/gui/widgets/scroll_label.cpp
src/gui/widgets/scrollbar_container.cpp
src/gui/widgets/scrollbar.cpp
src/gui/widgets/settings.cpp
src/gui/widgets/slider.cpp

View file

@ -249,6 +249,7 @@ SET(wesnoth-main_SRC
gui/widgets/slider.cpp
gui/widgets/spacer.cpp
gui/widgets/scroll_label.cpp
gui/widgets/scrollbar_container.cpp
gui/widgets/scrollbar.cpp
gui/widgets/text.cpp
gui/widgets/text_box.cpp

View file

@ -95,6 +95,7 @@ wesnoth_source = \
gui/widgets/settings.cpp \
gui/widgets/scroll_label.cpp \
gui/widgets/scrollbar.cpp \
gui/widgets/scrollbar_container.cpp \
gui/widgets/slider.cpp \
gui/widgets/spacer.cpp \
gui/widgets/text.cpp \

View file

@ -236,6 +236,7 @@ wesnoth_sources = Split("""
gui/widgets/panel.cpp
gui/widgets/settings.cpp
gui/widgets/scroll_label.cpp
gui/widgets/scrollbar_container.cpp
gui/widgets/scrollbar.cpp
gui/widgets/slider.cpp
gui/widgets/spacer.cpp

View file

@ -19,6 +19,9 @@
#include "foreach.hpp"
#include "formatter.hpp"
#include "gui/widgets/vertical_scrollbar_container.hpp"
#ifdef NEW_DRAW
#include "gui/widgets/scrollbar_container.hpp"
#endif
#include "gui/widgets/window.hpp"
#include "serialization/string_utils.hpp"
@ -209,6 +212,18 @@ void tdebug_layout_graph::widget_generate_info(std::ostream& out,
<< id << "_G"
<< " [label=\"(grid)\"];\n";
}
#ifdef NEW_DRAW
const tscrollbar_container* scrollbar_container =
dynamic_cast<const tscrollbar_container*>(widget);
if(scrollbar_container) {
widget_generate_info(out, scrollbar_container->content_grid_, id + "_C", true);
out << "\t" << id << " -> "
<< id << "_C"
<< " [label=\"(content)\"];\n";
}
#endif
}
if(grid) {
grid_generate_info(out, grid, id);
@ -281,7 +296,21 @@ void tdebug_layout_graph::widget_generate_state_info(
<< vertical_scrollbar_container->scrollbar_mode_ << '\n'
<< "</td></tr>\n";
}
#ifdef NEW_DRAW
const tscrollbar_container* scrollbar_container =
dynamic_cast<const tscrollbar_container*>(widget);
if(scrollbar_container) {
out << "<tr><td>\n"
<< "vertical_scrollbar_mode_="
<< scrollbar_container->vertical_scrollbar_mode_ << '\n'
<< "</td></tr>\n"
<< "<tr><td>\n"
<< "horizontal_scrollbar_mode_="
<< scrollbar_container->horizontal_scrollbar_mode_ << '\n'
<< "</td></tr>\n";
}
#endif
}
void tdebug_layout_graph::widget_generate_size_info(

View file

@ -19,30 +19,45 @@
#include "gui/widgets/spacer.hpp"
namespace gui2 {
tscroll_label::tscroll_label()
#ifndef NEW_DRAW
: tvertical_scrollbar_container_(COUNT)
#else
: tscrollbar_container(COUNT)
#endif
, state_(ENABLED)
#ifndef NEW_DRAW
, label_(NULL)
#endif
{
}
tscroll_label::~tscroll_label()
{
#ifndef NEW_DRAW
delete label_;
#endif
}
void tscroll_label::set_label(const t_string& label)
{
// Inherit.
tcontrol::set_label(label);
#ifndef NEW_DRAW
tlabel* widget = find_label(false);
if(widget) {
widget->set_label(label);
}
#else
if(content_grid()) {
tlabel* widget = content_grid()->
find_widget<tlabel>("_label", false, true);
widget->set_label(label);
}
#endif
}
#ifndef NEW_DRAW
tlabel* tscroll_label::find_label(const bool must_exist)
{
if(label_) {
@ -85,7 +100,25 @@ void tscroll_label::finalize()
label_->set_label(label());
label_->set_can_wrap(true);
}
#else
void tscroll_label::finalize_subclass()
{
assert(content_grid());
tlabel* lbl = dynamic_cast<tlabel*>(
content_grid()->find_widget("_label", false));
assert(lbl);
lbl->set_label(label());
/**
* @todo wrapping should be a label setting.
* This setting shoul be mutual exclusive with the horizontal scrollbar.
* Also the scroll_grid needs to set the status for the scrollbars.
*/
lbl->set_can_wrap(false);
}
#endif
#ifndef NEW_DRAW
tpoint tscroll_label::content_calculate_best_size() const
{
assert(label_);
@ -104,7 +137,6 @@ void tscroll_label::content_layout_wrap(const unsigned maximum_width)
}
label_->layout_wrap(maximum_width);
set_content_layout_size(label_->get_best_size());
DBG_G_L << "tscroll_label " << __func__ << ":"
@ -140,6 +172,7 @@ void tscroll_label::content_set_size(const SDL_Rect& rect)
scrollbar->set_visible_items(rect.h);
}
}
#endif
#ifndef NEW_DRAW
void tscroll_label::draw_content(surface& surf, const bool force,
const bool invalidate_background)
@ -165,7 +198,21 @@ void tscroll_label::draw_content(surface& surf, const bool force,
blit_surface(label_surf, &src_rect , surf, &dst_rect);
}
#else
void tscroll_label::content_draw_background(surface& /*frame_buffer*/)
{
assert(false); //fixme implement
}
void tscroll_label::
content_populate_dirty_list(twindow& /*caller*/,
const std::vector<twidget*>& /*call_stack*/)
{
assert(false); //fixme implement
}
#endif
#ifndef NEW_DRAW
twidget* tscroll_label::content_find_widget(
const tpoint& /*coordinate*/, const bool /*must_be_active*/)
{
@ -177,6 +224,7 @@ const twidget* tscroll_label::content_find_widget(const tpoint& /*coordinate*/,
{
return label_;
}
#endif
} // namespace gui2

View file

@ -15,7 +15,11 @@
#ifndef GUI_WIDGETS_SCROLL_LABEL_HPP_INCLUDED
#define GUI_WIDGETS_SCROLL_LABEL_HPP_INCLUDED
#ifndef NEW_DRAW
#include "gui/widgets/vertical_scrollbar_container.hpp"
#else
#include "gui/widgets/scrollbar_container.hpp"
#endif
namespace gui2 {
@ -29,7 +33,11 @@ class tspacer;
* scrolling features. In general this widget is slower as the normal label so
* the normal label should be preferred.
*/
#ifndef NEW_DRAW
class tscroll_label : public tvertical_scrollbar_container_
#else
class tscroll_label : public tscrollbar_container
#endif
{
friend class tbuilder_scroll_label;
public:
@ -70,6 +78,7 @@ private:
*/
tstate state_;
#ifndef NEW_DRAW
/**
* Helper label.
*
@ -94,9 +103,12 @@ private:
const tspacer* find_spacer(const bool must_exist = true) const;
void finalize();
#else
void finalize_subclass();
#endif
/***** ***** ***** ***** layout functions ***** ***** ***** *****/
#ifndef NEW_DRAW
/** Inherited from tvertical_scrollbar_container_. */
tpoint content_calculate_best_size() const;
@ -111,19 +123,25 @@ private:
/** Inherited from tvertical_scrollbar_container_. */
void content_set_size(const SDL_Rect& rect);
#endif
/***** ***** ***** inherited ****** *****/
/** Inherited from tcontrol. */
const std::string& get_control_type() const
{ static const std::string type = "scroll_label"; return type; }
#ifndef NEW_DRAW
#ifndef NEW_DRAW
/** Inherited from tvertical_scrollbar_container_. */
void draw_content(surface& surface, const bool force = false,
const bool invalidate_background = false);
#else
//FIXME we can't draw yet.
void content_draw_background(surface& frame_buffer);
void content_populate_dirty_list(twindow& caller,
const std::vector<twidget*>& call_stack);
#endif
#ifndef NEW_DRAW
/** Inherited from tvertical_scrollbar_container_. */
twidget* content_find_widget(
const tpoint& coordinate, const bool must_be_active);
@ -131,6 +149,7 @@ private:
/** Inherited from tvertical_scrollbar_container_. */
const twidget* content_find_widget(const tpoint& coordinate,
const bool must_be_active) const;
#endif
};
} // namespace gui2

View file

@ -0,0 +1,448 @@
/* $Id$ */
/*
copyright (C) 2008 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.
*/
#ifdef NEW_DRAW
#include "gui/widgets/scrollbar_container.hpp"
#include "foreach.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/scrollbar.hpp"
#include "gui/widgets/spacer.hpp"
#include "gui/widgets/window.hpp"
namespace gui2 {
namespace {
static const std::string button_up_names[] = {
"_begin", "_line_up", "_half_page_up", "_page_up" };
static const std::string button_down_names[] = {
"_end", "_line_down", "_half_page_down", "_page_down" };
/**
* Returns a map with the names of all buttons and the scrollbar jump they're
* supposed to execute.
*/
const std::map<std::string, tscrollbar_::tscroll>& scroll_lookup()
{
static std::map<std::string, tscrollbar_::tscroll> lookup;
if(lookup.empty()) {
lookup["_begin"] = tscrollbar_::BEGIN;
lookup["_line_up"] = tscrollbar_::ITEM_BACKWARDS;
lookup["_half_page_up"] = tscrollbar_::HALF_JUMP_BACKWARDS;
lookup["_page_up"] = tscrollbar_::JUMP_BACKWARDS;
lookup["_end"] = tscrollbar_::END;
lookup["_line_down"] = tscrollbar_::ITEM_FORWARD;
lookup["_half_page_down"] = tscrollbar_::HALF_JUMP_FORWARD;
lookup["_page_down"] = tscrollbar_::JUMP_FORWARD;
}
return lookup;
}
void callback_vertical_scrollbar_button(twidget* caller)
{
gui2::get_parent<gui2::tscrollbar_container>
(caller)->vertical_scrollbar_click(caller);
}
void callback_horizontal_scrollbar_button(twidget* caller)
{
gui2::get_parent<gui2::tscrollbar_container>
(caller)->horizontal_scrollbar_click(caller);
}
void callback_vertical_scrollbar(twidget* caller)
{
gui2::get_parent<gui2::tscrollbar_container>
(caller)->vertical_scrollbar_moved(caller);
}
void callback_horizontal_scrollbar(twidget* caller)
{
gui2::get_parent<gui2::tscrollbar_container>
(caller)->horizontal_scrollbar_moved(caller);
}
} // namespace
tscrollbar_container::tscrollbar_container(const unsigned canvas_count)
: tcontainer_(canvas_count)
, state_(ENABLED)
, vertical_scrollbar_mode_(SHOW_WHEN_NEEDED)
, horizontal_scrollbar_mode_(SHOW_WHEN_NEEDED)
, vertical_scrollbar_grid_(NULL)
, horizontal_scrollbar_grid_(NULL)
, vertical_scrollbar_(NULL)
, horizontal_scrollbar_(NULL)
, content_grid_(NULL)
, content_(NULL)
{
}
void tscrollbar_container::layout_init()
{
// Inherited.
tcontainer_::layout_init();
assert(content_grid_);
content_grid_->layout_init();
}
void tscrollbar_container::layout_wrap(const unsigned maximum_width)
{
// Inherited.
twidget::layout_wrap(maximum_width);
assert(content_grid_ && vertical_scrollbar_grid_);
const unsigned offset = vertical_scrollbar_mode_ == HIDE
? 0
: vertical_scrollbar_grid_->get_best_size().x;
content_grid_->layout_wrap(maximum_width - offset);
}
void tscrollbar_container::
layout_use_vertical_scrollbar(const unsigned maximum_height)
{
// Inherited.
twidget::layout_use_vertical_scrollbar(maximum_height);
tpoint size = get_best_size();
size.y = maximum_height;
// FIXME adjust for the step size of the scrollbar
set_layout_size(size);
}
void tscrollbar_container::
layout_use_horizontal_scrollbar(const unsigned maximum_width)
{
// Inherited.
twidget::layout_use_horizontal_scrollbar(maximum_width);
tpoint size = get_best_size();
size.x = maximum_width;
set_layout_size(size);
}
tpoint tscrollbar_container::calculate_best_size() const
{
log_scope2(gui_layout,
std::string("tscrollbar_container ") + __func__);
/***** get vertical scrollbar size *****/
const tpoint vertical_scrollbar =
vertical_scrollbar_mode_ == HIDE
? tpoint(0, 0)
: vertical_scrollbar_grid_->get_best_size();
/***** get horizontal scrollbar size *****/
const tpoint horizontal_scrollbar =
horizontal_scrollbar_mode_ == HIDE
? tpoint(0, 0)
: horizontal_scrollbar_grid_->get_best_size();
/***** get content size *****/
assert(content_grid_);
const tpoint content = content_grid_->get_best_size();
const tpoint result(
vertical_scrollbar.x +
std::max(horizontal_scrollbar.x, content.x),
horizontal_scrollbar.y +
std::max(vertical_scrollbar.y, content.y));
DBG_G_L << "tscrollbar_container"
<< " vertical_scrollbar " << vertical_scrollbar
<< " horizontal_scrollbar " << horizontal_scrollbar
<< " content " << content
<< " result " << result
<< ".\n";
return result;
}
void tscrollbar_container::
set_size(const tpoint& origin, const tpoint& size)
{
// Inherited.
tcontainer_::set_size(origin, size);
// Set content size
assert(content_ && content_grid_);
const tpoint content_origin = tpoint(
content_->get_screen_x(),
content_->get_screen_y());
const tpoint content_size = content_grid_->get_best_size();
content_grid_->set_size(content_origin, content_size);
// Set vertical scrollbar
assert(vertical_scrollbar_);
if(vertical_scrollbar_mode_ != HIDE) {
vertical_scrollbar_->set_item_count(content_size.y);
vertical_scrollbar_->set_visible_items(content_->get_height());
}
// Set horizontal scrollbar
assert(horizontal_scrollbar_);
if(horizontal_scrollbar_mode_ != HIDE) {
horizontal_scrollbar_->set_item_count(content_size.x);
horizontal_scrollbar_->set_visible_items(content_->get_width());
}
}
void tscrollbar_container::draw_background(surface& frame_buffer)
{
// Inherited.
tcontainer_::draw_background(frame_buffer);
/***** **** Draw content ***** *****/
assert(content_ && content_grid_);
// Update the location depending on the scrollbars.
if(vertical_scrollbar_mode_ != HIDE
|| horizontal_scrollbar_mode_ != HIDE) {
assert(vertical_scrollbar_ && horizontal_scrollbar_);
const int x_offset = horizontal_scrollbar_mode_ == HIDE
? 0
: horizontal_scrollbar_->get_item_position() *
horizontal_scrollbar_->get_step_size();
const int y_offset = vertical_scrollbar_mode_ == HIDE
? 0
: vertical_scrollbar_->get_item_position() *
vertical_scrollbar_->get_step_size();
const tpoint content_size = content_grid_->get_best_size();
const tpoint content_origin = tpoint(
content_->get_screen_x() - x_offset,
content_->get_screen_y() - y_offset);
content_grid_->set_size(content_origin, content_size);
}
// Make sure the content can't draw outside its canvas.
clip_rect_setter clip_rect(frame_buffer, ::create_rect(
content_->get_screen_x(),
content_->get_screen_y(),
content_->get_width(),
content_->get_height()));
// Draw.
content_grid_->draw_children(frame_buffer);
}
void tscrollbar_container::draw_foreground(surface& frame_buffer)
{
// Inherited.
tcontainer_::draw_foreground(frame_buffer);
}
void tscrollbar_container::vertical_scrollbar_click(twidget* caller)
{
/** @todo Hack to capture the keyboard focus. */
get_window()->keyboard_capture(this);
const std::map<std::string, tscrollbar_::tscroll>::const_iterator
itor = scroll_lookup().find(caller->id());
assert(itor != scroll_lookup().end());
vertical_scrollbar_->scroll(itor->second);
set_scrollbar_button_status();
set_dirty();
}
void tscrollbar_container::horizontal_scrollbar_click(twidget* caller)
{
/** @todo Hack to capture the keyboard focus. */
get_window()->keyboard_capture(this);
const std::map<std::string, tscrollbar_::tscroll>::const_iterator
itor = scroll_lookup().find(caller->id());
assert(itor != scroll_lookup().end());
horizontal_scrollbar_->scroll(itor->second);
set_scrollbar_button_status();
set_dirty();
}
void tscrollbar_container::finalize_setup()
{
/***** Setup vertical scrollbar *****/
vertical_scrollbar_grid_ =
find_widget<tgrid>("_vertical_scrollbar_grid", false, true);
vertical_scrollbar_ = vertical_scrollbar_grid_->
find_widget<tscrollbar_>("_vertical_scrollbar", false, true);
vertical_scrollbar_->
set_callback_positioner_move(callback_vertical_scrollbar);
/***** Setup horizontal scrollbar *****/
horizontal_scrollbar_grid_ =
find_widget<tgrid>("_horizontal_scrollbar_grid", false, true);
horizontal_scrollbar_ = horizontal_scrollbar_grid_->
find_widget<tscrollbar_>("_horizontal_scrollbar", false, true);
horizontal_scrollbar_->
set_callback_positioner_move(callback_horizontal_scrollbar);
/***** Setup the scrollbar buttons *****/
typedef std::pair<std::string, tscrollbar_::tscroll> hack;
foreach(const hack& item, scroll_lookup()) {
// Vertical.
tbutton* button = vertical_scrollbar_grid_->
find_widget<tbutton>(item.first, false, false);
if(button) {
button->set_callback_mouse_left_click(
callback_vertical_scrollbar_button);
}
// Horizontal.
button = horizontal_scrollbar_grid_->
find_widget<tbutton>(item.first, false, false);
if(button) {
button->set_callback_mouse_left_click(
callback_horizontal_scrollbar_button);
}
}
/***** 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_);
/***** Set the easy close status. *****/
/** @todo needs more testing. */
set_block_easy_close(get_visible()
&& get_active() && does_block_easy_close());
/***** Let our subclasses initialize themselves. *****/
finalize_subclass();
}
void tscrollbar_container::
set_vertical_scrollbar_mode(const tscrollbar_mode scrollbar_mode)
{
if(vertical_scrollbar_mode_ != scrollbar_mode) {
vertical_scrollbar_mode_ = scrollbar_mode;
show_vertical_scrollbar(vertical_scrollbar_mode_ != HIDE);
}
}
void tscrollbar_container::
set_horizontal_scrollbar_mode(const tscrollbar_mode scrollbar_mode)
{
if(horizontal_scrollbar_mode_ != scrollbar_mode) {
horizontal_scrollbar_mode_ = scrollbar_mode;
show_horizontal_scrollbar(horizontal_scrollbar_mode_ != HIDE);
}
}
void tscrollbar_container::show_vertical_scrollbar(const bool /*show*/)
{
/** @todo implement the new visibility. */
// vertical_scrollbar_grid_->set_visible(show);
}
void tscrollbar_container::show_horizontal_scrollbar(const bool /*show*/)
{
/** @todo implement the new visibility. */
// horizontal_scrollbar_grid_->set_visible(show);
}
void tscrollbar_container::set_scrollbar_button_status()
{
if(true) { /** @todo scrollbar visibility. */
/***** set scroll up button status *****/
foreach(const std::string& name, button_up_names) {
tbutton* button = vertical_scrollbar_grid_->
find_widget<tbutton>(name, false, false);
if(button) {
button->set_active(!vertical_scrollbar_->at_begin());
}
}
/***** set scroll down status *****/
foreach(const std::string& name, button_down_names) {
tbutton* button = vertical_scrollbar_grid_->
find_widget<tbutton>(name, false, false);
if(button) {
button->set_active(vertical_scrollbar_->at_end());
}
}
/***** Set the status if the scrollbars *****/
vertical_scrollbar_->set_active( !(vertical_scrollbar_->at_begin()
&& vertical_scrollbar_->at_end()));
}
if(true) { /** @todo scrollbar visibility. */
/***** Set scroll left button status *****/
foreach(const std::string& name, button_up_names) {
tbutton* button = horizontal_scrollbar_grid_->
find_widget<tbutton>(name, false, false);
if(button) {
button->set_active(!horizontal_scrollbar_->at_begin());
}
}
/***** Set scroll right button status *****/
foreach(const std::string& name, button_down_names) {
tbutton* button = horizontal_scrollbar_grid_->
find_widget<tbutton>(name, false, false);
if(button) {
button->set_active(horizontal_scrollbar_->at_end());
}
}
/***** Set the status if the scrollbars *****/
horizontal_scrollbar_->set_active( !(horizontal_scrollbar_->at_begin()
&& horizontal_scrollbar_->at_end()));
}
}
} // namespace gui2
#endif

View file

@ -0,0 +1,257 @@
/* $Id$ */
/*
copyright (C) 2008 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_SCROLLBAR_CONTAINER_HPP_INCLUDED
#define GUI_WIDGETS_SCROLLBAR_CONTAINER_HPP_INCLUDED
#ifdef NEW_DRAW
#include "gui/widgets/container.hpp"
#include <boost/noncopyable.hpp>
namespace gui2 {
class tscrollbar_;
class tspacer;
/**
* Base class for creating containers with one or two scrollbar(s).
*
* For now users can't instanciate this class directly and needs to use small
* wrapper classes. Maybe in the future users can use the class directly.
*
* @todo events are not yet send to the content grid.
*/
class tscrollbar_container
: public tcontainer_
, private boost::noncopyable
{
friend class tdebug_layout_graph;
friend class tbuilder_scroll_label;
public:
tscrollbar_container(const unsigned canvas_count);
~tscrollbar_container() { delete content_grid_; }
/** The way to handle the showing or hiding of the scrollbar. */
enum tscrollbar_mode {
SHOW, /**<
* The scrollbar is always shown, whether
* needed or not.
*/
HIDE, /**<
* The scrollbar is never shown even not when
* needed. There's also no space reserved for
* the scrollbar.
*/
SHOW_WHEN_NEEDED /**<
* The scrollbar is shown when the number of
* items is larger as the visible items. The
* space for the scrollbar is always
* reserved, just in case it's needed after
* the initial sizing (due to adding items).
*/
};
/***** ***** ***** ***** layout functions ***** ***** ***** *****/
/** Inherited from tcontainer_. */
void layout_init();
/** Inherited from tcontainer_. */
bool can_wrap() const
{
// Note this function is called before the object is finalized.
return content_grid_
? content_grid_->can_wrap()
: false;
}
/** Inherited from twidget (not tcontainer_). */
void layout_wrap(const unsigned maximum_width);
/** Inherited from twidget (not tcontainer_). */
bool has_vertical_scrollbar() const
{ return vertical_scrollbar_mode_ != HIDE; }
/** Inherited from tcontainer_. */
void layout_use_vertical_scrollbar(const unsigned maximum_height);
/** Inherited from twidget (not tcontainer_). */
bool has_horizontal_scrollbar() const
{ return horizontal_scrollbar_mode_ != HIDE; }
/** Inherited from tcontainer_. */
void layout_use_horizontal_scrollbar(const unsigned maximum_width);
private:
/** Inherited from tcontainer_. */
tpoint calculate_best_size() const;
public:
/** Inherited from tcontainer_. */
void set_size(const tpoint& origin, const tpoint& size);
/***** ***** ***** inherited ****** *****/
/** Inherited from tcontainer_. */
bool get_active() const { return state_ != DISABLED; }
/** Inherited from tcontainer_. */
unsigned get_state() const { return state_; }
/** Inherited from tcontainer_. */
void draw_background(surface& frame_buffer);
/** Inherited from tcontainer_. */
void draw_foreground(surface& frame_buffer);
/***** ***** ***** setters / getters for members ***** ****** *****/
void set_vertical_scrollbar_mode(const tscrollbar_mode scrollbar_mode);
tscrollbar_mode get_vertical_scrollbar_mode() const
{ return vertical_scrollbar_mode_; }
void set_horizontal_scrollbar_mode(const tscrollbar_mode scrollbar_mode);
tscrollbar_mode get_horizontal_scrollbar_mode() const
{ return horizontal_scrollbar_mode_; }
void vertical_scrollbar_click(twidget* caller);
void horizontal_scrollbar_click(twidget* caller);
tgrid *content_grid() { return content_grid_; }
const tgrid *content_grid() const { return content_grid_; }
/**
* Callback when the scrollbar moves (NOTE maybe only one callback needed).
* Maybe also make protected or private and add a friend.
*/
void vertical_scrollbar_moved(twidget* /*caller*/)
{ set_scrollbar_button_status(); set_dirty(); }
void horizontal_scrollbar_moved(twidget* /*caller*/)
{ set_scrollbar_button_status(); set_dirty(); }
protected:
/*
* The widget contains the following three grids.
*
* * _vertical_scrollbar_grid containing at least a widget named
* _vertical_scrollbar
*
* * _horizontal_scrollbar_grid containing at least a widget named
* _horizontal_scrollbar
*
* * _content_grid a grid which holds the contents of the area.
*
* NOTE maybe just hardcode these in the finalize phase...
*
*/
/**
* Sets the status of the scrollbar buttons.
*
* This is needed after the scrollbar moves so the status of the buttons
* will be active or inactive as needed.
*/
void set_scrollbar_button_status();
private:
/**
* Possible states of the widget.
*
* Note the order of the states must be the same as defined in settings.hpp.
*/
enum tstate { ENABLED, DISABLED, COUNT };
/**
* Current state of the widget.
*
* The state of the widget determines what to render and how the widget
* reacts to certain 'events'.
*/
tstate state_;
/**
* The mode of how to show the scrollbar.
*
* This value should only be modified before showing, doing it while
* showing results in UB.
*/
tscrollbar_mode
vertical_scrollbar_mode_,
horizontal_scrollbar_mode_;
/** These are valid after finalize_setup(). */
tgrid
*vertical_scrollbar_grid_,
*horizontal_scrollbar_grid_;
/** These are valid after finalize_setup(). */
tscrollbar_
*vertical_scrollbar_,
*horizontal_scrollbar_;
/** The grid that holds the content. */
tgrid *content_grid_;
/** Dummy spacer to hold the contents location. */
tspacer *content_;
/** The builder needs to call us so we do our setup. */
void finalize_setup();
/**
* Function for the subclasses to do their setup.
*
* This function is called at the end of finalize_setup().
*/
virtual void finalize_subclass() {}
/**
* Shows the vertical scrollbar.
*
* @param show If true the scrollbar is shown, hidden
* otherwise.
*/
void show_vertical_scrollbar(const bool show);
/**
* Shows the horizontal scrollbar.
*
* @param show If true the scrollbar is shown, hidden
* otherwise.
*/
void show_horizontal_scrollbar(const bool show);
/** Inherited from tcontrol. */
const std::string& get_control_type() const
{
static const std::string type = "scrollbar_container";
return type;
}
};
} // namespace gui2
#endif
#endif

View file

@ -1013,6 +1013,9 @@ twidget* tbuilder_scroll_label::build() const
<const tscroll_label_definition::tresolution>(widget->config());
assert(conf);
#ifdef NEW_DRAW
conf->grid->build(&widget->grid());
#else
tgrid* grid = dynamic_cast<tgrid*>(conf->grid->build());
assert(grid);
@ -1021,7 +1024,7 @@ twidget* tbuilder_scroll_label::build() const
tgrid::VERTICAL_GROW_SEND_TO_CLIENT
| tgrid::HORIZONTAL_GROW_SEND_TO_CLIENT
, 0);
#endif
widget->finalize_setup();
DBG_GUI << "Window builder: placed scroll label '" << id << "' with defintion '"