Add a scrollbar base class and a vertical scrollbar class.

The class isn't used since some extra helper classes are needed for
that.  Note there is debug code left since not everything is tested
yet.
This commit is contained in:
Mark de Wever 2008-05-03 14:59:38 +00:00
parent 8c202d9f8d
commit 861ff2da3b
11 changed files with 842 additions and 3 deletions

View file

@ -0,0 +1,111 @@
###
### Definition of a vertical scrollbar.
###
#define STATE IMAGE_SUFFIX
full_redraw = "true"
[draw]
#
# Groove
#
[image]
# 4 pixels high
x = 0
y = 0
name = "buttons/scrollgroove-top.png"
[/image]
[image]
x = 0
y = 4
h = "(height - 9)"
stretch = true
name = "buttons/scrollgroove-mid.png"
[/image]
[image]
# 5 pixels high
x = 0
y = "(height - 5)"
name = "buttons/scrollgroove-bottom.png"
[/image]
[image]
# 5 pixels high
x = 0
y = "(positioner_offset)"
name = "buttons/scrolltop" + {IMAGE_SUFFIX}
[/image]
#
# Positioner
#
[image]
x = 0
y = "(positioner_offset + 5)"
h = "(positioner_length - 10)"
stretch = true
name = "buttons/scrollmid"+ {IMAGE_SUFFIX}
[/image]
[image]
# 5 pixels high
x = 0
y = "(positioner_offset + positioner_length - 5)"
name = "buttons/scrollbottom" + {IMAGE_SUFFIX}
[/image]
[/draw]
#enddef
[vertical_scrollbar_definition]
id = "default"
description = "a vertical scrollbar"
[resolution]
# Note a scrollbar is normally sized by the item that "masters" it
# that's why the default height is rather low.
min_width = 25
min_height = 20
default_width = 25
default_height = 20
max_width = 25
max_height = 0
text_font_size = 16
minimum_positioner_length = 11
top_offset = 0
bottom_offset = 0
[state_enabled]
{STATE ".png"}
[/state_enabled]
# FIXME we need another suffix
[state_disabled]
{STATE ".png"}
[/state_disabled]
# FIXME we need another suffix
[state_pressed]
{STATE ".png"}
[/state_pressed]
[state_focussed]
{STATE "-active.png"}
[/state_focussed]
[/resolution]
[/vertical_scrollbar_definition]
#undef STATE

View file

@ -140,14 +140,16 @@ SET(wesnoth-main_SRC
gui/widgets/control.cpp
gui/widgets/event_handler.cpp
gui/widgets/grid.cpp
gui/widgets/helper.cpp
gui/widgets/label.cpp
gui/widgets/panel.cpp
gui/widgets/settings.cpp
gui/widgets/spacer.cpp
gui/widgets/scrollbar.cpp
gui/widgets/text.cpp
gui/widgets/text_box.cpp
gui/widgets/tooltip.cpp
gui/widgets/helper.cpp
gui/widgets/vertical_scrollbar.cpp
gui/widgets/widget.cpp
gui/widgets/window.cpp
gui/widgets/window_builder.cpp

View file

@ -73,14 +73,16 @@ wesnoth_source = \
gui/widgets/control.cpp \
gui/widgets/event_handler.cpp \
gui/widgets/grid.cpp \
gui/widgets/helper.cpp \
gui/widgets/label.cpp \
gui/widgets/panel.cpp \
gui/widgets/settings.cpp \
gui/widgets/scrollbar.cpp \
gui/widgets/spacer.cpp \
gui/widgets/text.cpp \
gui/widgets/text_box.cpp \
gui/widgets/tooltip.cpp \
gui/widgets/helper.cpp \
gui/widgets/vertical_scrollbar.cpp \
gui/widgets/widget.cpp \
gui/widgets/window.cpp \
gui/widgets/window_builder.cpp \

View file

@ -86,14 +86,16 @@ libwesnoth_sources = Split("""
gui/widgets/control.cpp
gui/widgets/event_handler.cpp
gui/widgets/grid.cpp
gui/widgets/helper.cpp
gui/widgets/label.cpp
gui/widgets/panel.cpp
gui/widgets/settings.cpp
gui/widgets/scrollbar.cpp
gui/widgets/spacer.cpp
gui/widgets/text.cpp
gui/widgets/text_box.cpp
gui/widgets/helper.cpp
gui/widgets/tooltip.cpp
gui/widgets/vertical_scrollbar.cpp
gui/widgets/widget.cpp
gui/widgets/window.cpp
gui/widgets/window_builder.cpp

View file

@ -0,0 +1,260 @@
/* $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.
*/
#include "gui/widgets/scrollbar.hpp"
#include "foreach.hpp"
#include "gui/widgets/event_handler.hpp"
#include "log.hpp"
#include <cassert>
#define DBG_G LOG_STREAM_INDENT(debug, gui)
#define LOG_G LOG_STREAM_INDENT(info, gui)
#define WRN_G LOG_STREAM_INDENT(warn, gui)
#define ERR_G LOG_STREAM_INDENT(err, gui)
#define DBG_G_D LOG_STREAM_INDENT(debug, gui_draw)
#define LOG_G_D LOG_STREAM_INDENT(info, gui_draw)
#define WRN_G_D LOG_STREAM_INDENT(warn, gui_draw)
#define ERR_G_D LOG_STREAM_INDENT(err, gui_draw)
#define DBG_G_E LOG_STREAM_INDENT(debug, gui_event)
#define LOG_G_E LOG_STREAM_INDENT(info, gui_event)
#define WRN_G_E LOG_STREAM_INDENT(warn, gui_event)
#define ERR_G_E LOG_STREAM_INDENT(err, gui_event)
#define DBG_G_P LOG_STREAM_INDENT(debug, gui_parse)
#define LOG_G_P LOG_STREAM_INDENT(info, gui_parse)
#define WRN_G_P LOG_STREAM_INDENT(warn, gui_parse)
#define ERR_G_P LOG_STREAM_INDENT(err, gui_parse)
namespace gui2 {
void tscrollbar_::mouse_move(tevent_handler& event)
{
tpoint mouse = event.get_mouse();
mouse.x -= get_x();
mouse.y -= get_y();
DBG_G_E << "Scrollbar: mouse move at " << mouse << ".\n";
switch(state_) {
case ENABLED :
if(on_positioner(mouse)) {
set_state(FOCUSSED);
}
break;
case DISABLED :
// do nothing
break;
case PRESSED : {
const int distance = get_length_difference(mouse_, mouse);
mouse_ = mouse;
move_positioner(distance);
}
break;
case FOCUSSED :
if(!on_positioner(mouse)) {
set_state(ENABLED);
}
break;
default :
assert(false);
}
}
void tscrollbar_::mouse_leave(tevent_handler&)
{
if(state_ == FOCUSSED) {
set_state(ENABLED);
}
}
void tscrollbar_::mouse_left_button_down(tevent_handler& event)
{
tpoint mouse = event.get_mouse();
mouse.x -= get_x();
mouse.y -= get_y();
DBG_G_E << "Scrollbar: mouse down at " << mouse << ".\n";
if(on_positioner(mouse)) {
mouse_ = mouse;
event.mouse_capture();
set_state(PRESSED);
}
}
void tscrollbar_::mouse_left_button_up(tevent_handler& event)
{
tpoint mouse = event.get_mouse();
mouse.x -= get_x();
mouse.y -= get_y();
DBG_G_E << "Scrollbar: mouse up at " << mouse << ".\n";
if(state_ != PRESSED) {
return;
}
event.mouse_capture(false);
if(on_positioner(mouse)) {
set_state(FOCUSSED);
} else {
set_state(ENABLED);
}
}
void tscrollbar_::set_size(const SDL_Rect& rect)
{
// Inherited.
tcontrol::set_size(rect);
recalculate();
}
void tscrollbar_::set_item_position(const unsigned item_position)
{
// Adjust the item position.
if(item_position_ >= item_count_) {
item_position_ = item_count_ - 1;
}
item_position_ = (item_position_ + step_size_ - 1) / step_size_;
std::cerr << "Item position: " << item_position_ << ".\n";
// Determine the pixel offset of the item position.
positioner_offset_ = static_cast<unsigned>(item_position_ * pixels_per_step_);
std::cerr << "Positioner offset: " << positioner_offset_ << ".\n";
update_canvas();
}
void tscrollbar_::set_state(const tstate state)
{
if(state != state_) {
state_ = state;
set_dirty(true);
}
}
//! Inherited from tcontrol.
void tscrollbar_::load_config_extra()
{
// These values won't change so set them here.
foreach(tcanvas& tmp, canvas()) {
tmp.set_variable("offset_before", variant(offset_before()));
tmp.set_variable("offset_after", variant(offset_after()));
}
}
//! Updates the size of the scroll bar.
void tscrollbar_::recalculate()
{
// Get the available size for the slider to move.
int available_length =
get_length() - offset_before() - minimum_positioner_length() - offset_after();
std::cerr << "Available length: " << available_length << ".\n";
assert(available_length > 0);
// All visible.
if(item_count_ <= visible_items_) {
std::cerr << "Show all.\n";
positioner_offset_ = offset_before();
positioner_length_ = available_length + minimum_positioner_length();
item_position_ = 0;
update_canvas();
return;
}
assert(step_size_);
assert(visible_items_);
const unsigned steps =
(item_count_ + step_size_ - 1) / step_size_;
std::cerr << "Steps: " << steps << "\n";
std::cerr << "Step size: " << step_size_ << ".\n";
if(steps < available_length) {
// We can show them all.
std::cerr << "All steps can be shown.\n";
available_length += minimum_positioner_length();
pixels_per_step_ = available_length / steps;
std::cerr << "Pixels per step: " << pixels_per_step_ << ".\n";
positioner_length_ = static_cast<unsigned>(pixels_per_step_ * visible_items_) + available_length % steps;
std::cerr << "Positioner length: " << positioner_length_ << ".\n";
} else {
// We'll skip some.
std::cerr << "Some steps will be skipped.\n";
WRN_G << "The scrollbar is too small for the"
" number of items, movement might seem jerky.\n";
pixels_per_step_ = available_length / steps;
std::cerr << "Pixels per step: " << pixels_per_step_ << ".\n";
positioner_length_ = minimum_positioner_length();
std::cerr << "Positioner length: " << positioner_length_ << ".\n";
}
set_item_position(item_position_);
}
void tscrollbar_::update_canvas() {
foreach(tcanvas& tmp, canvas()) {
tmp.set_variable("positioner_offset", variant(positioner_offset_));
tmp.set_variable("positioner_length", variant(positioner_length_));
}
set_dirty();
}
void tscrollbar_::move_positioner(const int distance)
{
std::cerr << "Positioner at " << positioner_offset_ << " move for " << distance;
if(distance < 0 && -distance > positioner_offset_) {
positioner_offset_ = 0;
} else {
positioner_offset_ += distance;
}
const unsigned length = get_length() - offset_before() - offset_after();
if(positioner_offset_ + positioner_length_ > length) {
positioner_offset_ = length - positioner_length_;
}
std::cerr << " sets positioner at " << positioner_offset_ << ".\n";
update_canvas();
}
} // namespace gui2

View file

@ -0,0 +1,199 @@
/* $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_HPP_INCLUDED__
#define __GUI_WIDGETS_SCROLLBAR_HPP_INCLUDED__
#include "gui/widgets/control.hpp"
#include "gui/widgets/settings.hpp"
namespace gui2 {
//! Base class for a scroll bar.
//!
//! class will be subclassed for the horizontal and vertical scroll bar.
//! It might be subclassed for a slider class.
//!
//! To make this class generic we talk a lot about offset and length and use
//! pure virtual functions. The classes implementing us can use the heights or
//! widths, whichever is applicable.
class tscrollbar_ : public tcontrol
{
public:
tscrollbar_() :
tcontrol(COUNT),
state_(ENABLED),
item_count_(0),
item_position_(0),
visible_items_(1),
step_size_(1),
pixels_per_step_(0.0),
mouse_(0, 0),
positioner_offset_(0),
positioner_length_(0)
{
}
//! Inherited from twidget.
//! We only need to track the mouse if it's on the positioner so the normal
//! enter doesn't help so transfer the control.
void mouse_enter(tevent_handler& event) { mouse_move(event); }
//! Inherited from twidget.
void mouse_move(tevent_handler& event);
//! Inherited from twidget.
//! Leave doesn't have the problem which mouse_enter has so it does it's own
//! job.
void mouse_leave(tevent_handler&);
//! Inherited from twidget.
void mouse_left_button_down(tevent_handler& event);
//! Inherited from twidget.
void mouse_left_button_up(tevent_handler& event);
//! Inherited from tcontrol.
void set_active(const bool active) { set_state(active ? ENABLED : DISABLED); };
//! Inherited from tcontrol.
bool get_active() const { return state_ != DISABLED; }
//! Inherited from tcontrol.
unsigned get_state() const { return state_; }
//! Inherited from tcontrol.
void set_size(const SDL_Rect& rect);
unsigned get_item_count() const { return item_count_; }
void set_item_count(const unsigned item_count)
{ item_count_ = item_count; recalculate(); }
unsigned get_item_position() const { return item_position_; }
//! Note the position isn't guaranteed to be the wanted position
//! the step size is honoured. The value will be rouded down
void set_item_position(const unsigned item_position);
unsigned get_visible_items() const { return visible_items_; }
void set_visible_items(const unsigned visible_items)
{ visible_items_ = visible_items; recalculate(); }
unsigned get_step_size() const { return step_size_; }
void set_step_size(const unsigned step_size)
{ step_size_ = step_size; recalculate(); }
//! Is the positioner at the beginning of the scrollbar.
bool at_begin() const { return item_position_ == 0; }
//! Is the positioner at the and of the scrollbar, note both begin and end
//! might be true at the same time.
bool at_end() const
{ return item_position_ + visible_items_ + 1 == item_count_; }
protected:
unsigned get_positioner_offset() const { return positioner_offset_; }
unsigned get_positioner_length() const { return positioner_length_; }
private:
//! Note the order of the states must be the same as defined in settings.hpp.
enum tstate { ENABLED, DISABLED, PRESSED, FOCUSSED, COUNT };
void set_state(const tstate state);
tstate state_;
//! Inherited from tcontrol.
void load_config_extra();
//! The number of items the scrollbar 'holds'.
unsigned item_count_;
//! The item the positioner is at, starts at 0.
unsigned item_position_;
//! The number of items which can be shown at the same time.
//! As long as all items are visible we don't need to scroll.
unsigned visible_items_;
//! The step size is the minimum number of items we scroll through when we
//! move. Normally this value is 1, we can move per item. But for example
//! sliders want for example to move per 5 items.
unsigned step_size_;
//! The number of pixels the positioner needs to move to go to the next step.
//! Note if there is too little space it can happen 1 pixel does more than 1
//! step.
float pixels_per_step_;
//! Get the length of the object.
virtual unsigned get_length() const = 0;
//! The minimum length of the positioner.
virtual unsigned minimum_positioner_length() const = 0;
//! The number of pixels we can't use since they're used for borders.
//! These are the pixels before the widget (left side if horizontal,
//! top side if vertical).
virtual unsigned offset_before() const = 0;
//! The number of pixels we can't use since they're used for borders.
//! These are the pixels after the widget (right side if horizontal,
//! bottom side if vertical).
virtual unsigned offset_after() const = 0;
//! Is the current location on the positioner?
virtual bool on_positioner(const tpoint& coordinate) const = 0;
//! Gets the relevent difference in between the two positions.
//!
//! This function is used to determine how much the positioner needs to be
//! moved.
virtual int get_length_difference(
const tpoint& original, const tpoint& current) const = 0;
//! The position the mouse was at the last movement. This is used during
//! dragging the positioner.
tpoint mouse_;
//! The start offset of the positioner.
//! This takes the offset before in consideration.
unsigned positioner_offset_;
//! The current length of the positioner.
unsigned positioner_length_;
//! Updates the scrollbar.
//!
//! Needs to be called when someting changes eg number of items
//! or available size. It can only be called once we have a size
//! otherwise we can't calulate a thing.
void recalculate();
//! After a recalculation the canvasses also need to be updated.
void update_canvas();
//! Moves the positioner.
//!
//! @param distance The distance moved, negative to begin,
//! positive to end.
void move_positioner(const int distance);
};
} // namespace gui2
#endif

View file

@ -179,6 +179,7 @@ const std::string& tgui_definition::read(const config& cfg)
* spacer_definition A spacer.
* text_box_definition A single line text box.
* tooltip_definition A small tooltip with help.
* vertical_scrollbar_definition A vertical scrollbar.
* window_definition A window.
* @end_table
*
@ -204,6 +205,8 @@ const std::string& tgui_definition::read(const config& cfg)
load_definitions<tspacer_definition>("spacer", cfg.get_children("spacer_definition"));
load_definitions<ttext_box_definition>("text_box", cfg.get_children("text_box_definition"));
load_definitions<ttooltip_definition>("tooltip", cfg.get_children("tooltip_definition"));
load_definitions<tvertical_scrollbar_definition>
("vertical_scrollbar", cfg.get_children("vertical_scrollbar_definition"));
load_definitions<twindow_definition>("window", cfg.get_children("window_definition"));
/***** Window types *****/
@ -633,6 +636,7 @@ ttooltip_definition::ttooltip_definition(const config& cfg) :
ttooltip_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* @page = GUIToolkitWML
@ -651,6 +655,64 @@ ttooltip_definition::tresolution::tresolution(const config& cfg) :
state.push_back(tstate_definition(cfg.child("state_enabled")));
}
tvertical_scrollbar_definition::tvertical_scrollbar_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing vertical scrollbar " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tvertical_scrollbar_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg),
minimum_positioner_length(
lexical_cast_default<unsigned>(cfg["minimum_positioner_length"])),
top_offset(lexical_cast_default<unsigned>(cfg["top_offset"])),
bottom_offset(lexical_cast_default<unsigned>(cfg["bottom_offset"]))
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget_vertical_scrollbar
*
* == Vertical scrollbar ==
*
* The definition of a vertical scrollbar. This class is most of the time not
* used directly. Instead it's used to build other items with scrollbars.
*
* The resolution for a vertical scrollbar also contains the following keys:
* @start_table = config
* minimum_positioner_length (unsigned)
* The minumum size the positioner is
* allowed to be. The engine needs to know
* this in order to calculate the best size
* for the positioner. There is no maximum
* size for the positioner it should be
* scaleable for the entire size. (Of course
* it is possible to file a FR if this is
* really wanted.)
* top_offset (unsigned = 0) The number of pixels at the top which
* can't be used by the positioner.
* bottom_offset (unsigned = 0) The number of pixels at the bottom which
* can't be used by the positioner.
* @end_table
*
* The following states exist:
* * state_enabled, the vertical scrollbar is enabled.
* * state_disabled, the vertical scrollbar is disabled.
* * state_pressed, the left mouse button is down on the positioner of the vertical scrollbar.
* * state_focussed, the mouse is over the positioner of the vertical scrollbar.
*/
VALIDATE(minimum_positioner_length,
missing_mandatory_wml_key("resolution", "minimum_positioner_length"));
// Note the order should be the same as the enum tstate is scrollbar.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
state.push_back(tstate_definition(cfg.child("state_disabled")));
state.push_back(tstate_definition(cfg.child("state_pressed")));
state.push_back(tstate_definition(cfg.child("state_focussed")));
}
twindow_definition::twindow_definition(const config& cfg) :
tpanel_definition(cfg)
{

View file

@ -176,6 +176,21 @@ struct ttooltip_definition : public tcontrol_definition
};
};
struct tvertical_scrollbar_definition : public tcontrol_definition
{
tvertical_scrollbar_definition(const config& cfg);
struct tresolution : public tresolution_definition_
{
tresolution(const config& cfg);
unsigned minimum_positioner_length;
unsigned top_offset;
unsigned bottom_offset;
};
};
struct twindow_definition : public tpanel_definition
{
twindow_definition(const config& cfg);

View file

@ -0,0 +1,84 @@
/* $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.
*/
#include "gui/widgets/vertical_scrollbar.hpp"
#include "log.hpp"
#include <cassert>
#define DBG_G LOG_STREAM_INDENT(debug, gui)
#define LOG_G LOG_STREAM_INDENT(info, gui)
#define WRN_G LOG_STREAM_INDENT(warn, gui)
#define ERR_G LOG_STREAM_INDENT(err, gui)
#define DBG_G_D LOG_STREAM_INDENT(debug, gui_draw)
#define LOG_G_D LOG_STREAM_INDENT(info, gui_draw)
#define WRN_G_D LOG_STREAM_INDENT(warn, gui_draw)
#define ERR_G_D LOG_STREAM_INDENT(err, gui_draw)
#define DBG_G_E LOG_STREAM_INDENT(debug, gui_event)
#define LOG_G_E LOG_STREAM_INDENT(info, gui_event)
#define WRN_G_E LOG_STREAM_INDENT(warn, gui_event)
#define ERR_G_E LOG_STREAM_INDENT(err, gui_event)
#define DBG_G_P LOG_STREAM_INDENT(debug, gui_parse)
#define LOG_G_P LOG_STREAM_INDENT(info, gui_parse)
#define WRN_G_P LOG_STREAM_INDENT(warn, gui_parse)
#define ERR_G_P LOG_STREAM_INDENT(err, gui_parse)
namespace gui2 {
//! Inherited from tscrollbar.
unsigned tvertical_scrollbar::minimum_positioner_length() const
{
const tvertical_scrollbar_definition::tresolution* conf =
dynamic_cast<const tvertical_scrollbar_definition::tresolution*>(config());
assert(conf);
return conf->minimum_positioner_length;
}
//! Inherited from tscrollbar.
unsigned tvertical_scrollbar::offset_before() const
{
const tvertical_scrollbar_definition::tresolution* conf =
dynamic_cast<const tvertical_scrollbar_definition::tresolution*>(config());
assert(conf);
return conf->top_offset;
}
//! Inherited from tscrollbar.
unsigned tvertical_scrollbar::offset_after() const
{
const tvertical_scrollbar_definition::tresolution* conf =
dynamic_cast<const tvertical_scrollbar_definition::tresolution*>(config());
assert(conf);
return conf->bottom_offset;
}
//! Inherited from tscrollbar.
bool tvertical_scrollbar::on_positioner(const tpoint& coordinate) const
{
// Note we assume the positioner is over the entire width of the widget.
return coordinate.y >= get_positioner_offset()
&& coordinate.y < get_positioner_offset() + get_positioner_length()
&& coordinate.x > 0
&& coordinate.x < get_width();
}
} // namespace gui2

View file

@ -0,0 +1,63 @@
/* $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_VERTICAL_SCROLLBAR_HPP_INCLUDED__
#define __GUI_WIDGETS_VERTICAL_SCROLLBAR_HPP_INCLUDED__
#include "gui/widgets/scrollbar.hpp"
namespace gui2 {
//! A vertical scrollbar.
class tvertical_scrollbar : public tscrollbar_
{
public:
tvertical_scrollbar() :
tscrollbar_()
{
load_config();
}
private:
//! Inherited from tscrollbar.
unsigned get_length() const { return get_height(); }
//! Inherited from tscrollbar.
unsigned minimum_positioner_length() const;
//! Inherited from tscrollbar.
unsigned offset_before() const;
//! Inherited from tscrollbar.
unsigned offset_after() const;
//! Inherited from tscrollbar.
bool on_positioner(const tpoint& coordinate) const;
//! Inherited from tscrollbar.
int get_length_difference(const tpoint& original, const tpoint& current) const
{ return current.y - original.y; }
//! Inherited from tcontrol.
const std::string& get_control_type() const
{ static const std::string type = "vertical_scrollbar"; return type; }
};
} // namespace gui2
#endif

View file

@ -21,6 +21,7 @@
#include "gui/widgets/settings.hpp"
#include "gui/widgets/spacer.hpp"
#include "gui/widgets/text_box.hpp"
#include "gui/widgets/vertical_scrollbar.hpp"
#include "gui/widgets/widget.hpp"
#include "gui/widgets/window.hpp"
#include "log.hpp"
@ -177,6 +178,28 @@ public:
history_(cfg["history"])
{}
twidget* build () const;
}
;
struct tbuilder_vertical_scrollbar : public tbuilder_control
{
private:
tbuilder_vertical_scrollbar();
public:
/*WIKI
* @page = GUIToolkitWML
* @order = 3_widget_vertical_scrollbar
*
* == Vertical scrollbar ==
*
* A vertical scrollbar has no special fields.
*
*/
tbuilder_vertical_scrollbar(const config& cfg) :
tbuilder_control(cfg)
{}
twidget* build () const;
};
@ -529,6 +552,7 @@ tbuilder_grid::tbuilder_grid(const config& cfg) :
* * panel a panel (a grid which can be drawn on).
* * spacer a filler item.
* * text_box a text box.
* * vertical_scrollbar a vertical scrollbar.
*
* More details about the widgets is in the next section.
*
@ -563,6 +587,9 @@ tbuilder_grid::tbuilder_grid(const config& cfg) :
widgets.push_back(new tbuilder_spacer(*((**col_itor).child("spacer"))));
} else if((**col_itor).child("text_box")) {
widgets.push_back(new tbuilder_text_box(*((**col_itor).child("text_box"))));
} else if((**col_itor).child("vertical_scrollbar")) {
widgets.push_back(
new tbuilder_vertical_scrollbar(*((**col_itor).child("vertical_scrollbar"))));
} else if((**col_itor).child("grid")) {
widgets.push_back(new tbuilder_grid(*((**col_itor).child("grid"))));
} else {
@ -802,6 +829,18 @@ twidget* tbuilder_text_box::build() const
return text_box;
}
twidget* tbuilder_vertical_scrollbar::build() const
{
tvertical_scrollbar *vertical_scrollbar = new tvertical_scrollbar();
init_control(vertical_scrollbar);
DBG_G << "Window builder: placed text box '" << id << "' with defintion '"
<< definition << "'.\n";
return vertical_scrollbar;
}
twidget* tbuilder_grid::build() const
{
tgrid *grid = new tgrid();