Created basic implementation of the viewport.

The class can now hold a widget and forward calls to it. The class is
not yet complete but it looks much better now.

Also allows to switch between the naked pane and the pane in a viewport
with a #if 0.

The code is used to experiment with a different approach of the
implementation of a listbox.
This commit is contained in:
Mark de Wever 2012-05-06 09:44:47 +00:00
parent 8ff6416e22
commit 0ccec6b7c5
3 changed files with 161 additions and 7 deletions

View file

@ -106,10 +106,10 @@ twidget* tbuilder_listbox::build() const
tpane *pane = new tpane(list_builder);
pane->set_id(id);
tviewport *viewport = new tviewport();
tgrid* grid = new tgrid();
grid->set_rows_cols(1, 2);
grid->set_rows_cols(1, 1);
#if 0
grid->set_child(
pane
, 0
@ -117,15 +117,16 @@ twidget* tbuilder_listbox::build() const
, tgrid::VERTICAL_GROW_SEND_TO_CLIENT
| tgrid::HORIZONTAL_GROW_SEND_TO_CLIENT
, tgrid::BORDER_ALL);
#else
tviewport *viewport = new tviewport(*pane);
grid->set_child(
viewport
, 0
, 1
, 0
, tgrid::VERTICAL_GROW_SEND_TO_CLIENT
| tgrid::HORIZONTAL_GROW_SEND_TO_CLIENT
, tgrid::BORDER_ALL);
#endif
return grid;
}

View file

@ -24,14 +24,137 @@
namespace gui2 {
tviewport::tviewport()
/**
* Helper to implement private functions without modifying the header.
*
* The class is a helper to avoid recompilation and only has static
* functions. It also facilitates to create duplicates of functions for a const
* and a non-const member function.
*/
struct tviewport_implementation
{
/**
* Implementation for the wrappers for
* [const] twidget* tpane::find_at(const tpoint&, const bool) [const].
*
* @tparam W A pointer to the pane.
*/
template<class W>
static typename tconst_clone<twidget, W>::pointer
find_at(
W viewport
, tpoint coordinate
, const bool must_be_active
)
{
/*
* First test whether the mouse is at the pane.
*/
if(viewport->twidget::find_at(coordinate, must_be_active) != viewport) {
return NULL;
}
/*
* The widgets are placed at coordinate 0,0 so adjust the offset to
* that coordinate system.
*/
coordinate.x -= viewport->get_x();
coordinate.y -= viewport->get_y();
return viewport->widget_.find_at(coordinate, must_be_active);
}
template<class W>
static typename tconst_clone<twidget, W>::pointer
find(
W viewport
, const std::string& id
, const bool must_be_active
)
{
if(viewport->twidget::find(id, must_be_active)) {
return viewport;
} else {
return viewport->widget_.find(id, must_be_active);
}
}
};
tviewport::tviewport(twidget& widget)
: widget_(widget)
{
widget_.set_parent(this);
}
void tviewport::place(const tpoint& origin, const tpoint& size)
{
twidget::place(origin, size);
widget_.place(tpoint(0, 0), widget_.get_best_size());
}
void tviewport::layout_init(const bool full_initialization)
{
twidget::layout_init(full_initialization);
if(widget_.get_visible() != twidget::INVISIBLE) {
widget_.layout_init(full_initialization);
}
}
void tviewport::impl_draw_children(
surface& frame_buffer
, int x_offset
, int y_offset)
{
x_offset += get_x();
y_offset += get_y();
if(widget_.get_visible() != twidget::INVISIBLE) {
widget_.draw_background(frame_buffer, x_offset, y_offset);
widget_.draw_children(frame_buffer, x_offset, y_offset);
widget_.draw_foreground(frame_buffer, x_offset, y_offset);
widget_.set_dirty(false);
}
}
void tviewport::child_populate_dirty_list(
twindow& caller
, const std::vector<twidget*>& call_stack)
{
std::vector<twidget*> child_call_stack = call_stack;
widget_.populate_dirty_list(caller, child_call_stack);
}
void tviewport::request_reduce_width(const unsigned /*maximum_width*/)
{
}
twidget* tviewport::find_at(const tpoint& coordinate, const bool must_be_active)
{
return tviewport_implementation::find_at(this, coordinate, must_be_active);
}
const twidget* tviewport::find_at(
const tpoint& coordinate
, const bool must_be_active) const
{
return tviewport_implementation::find_at(this, coordinate, must_be_active);
}
twidget* tviewport::find(const std::string& id, const bool must_be_active)
{
return tviewport_implementation::find(this, id, must_be_active);
}
const twidget* tviewport::find(
const std::string& id
, const bool must_be_active) const
{
return tviewport_implementation::find(this, id, must_be_active);
}
tpoint tviewport::calculate_best_size() const
{
return tpoint(500, 500);

View file

@ -25,13 +25,41 @@ class tgrid;
class tviewport
: public twidget
{
friend struct tviewport_implementation;
public:
tviewport();
explicit tviewport(twidget& widget);
/** Inherited from twidget. */
void place(const tpoint& origin, const tpoint& size);
/** Inherited from twidget. */
void layout_init(const bool full_initialization);
/** Inherited from twidget. */
void impl_draw_children(surface& frame_buffer, int x_offset, int y_offset);
/** Inherited from twidget. */
void child_populate_dirty_list(twindow& caller,
const std::vector<twidget*>& call_stack);
/** Inherited from twidget. */
void request_reduce_width(const unsigned maximum_width);
/** Inherited from twidget. */
twidget* find_at(const tpoint& coordinate, const bool must_be_active);
/** Inherited from twidget. */
const twidget* find_at(
const tpoint& coordinate
, const bool must_be_active) const;
/** Inherited from twidget. */
twidget* find(const std::string& id, const bool must_be_active);
/** Inherited from twidget. */
const twidget* find(const std::string& id, const bool must_be_active) const;
private:
/** Inherited from twidget. */
tpoint calculate_best_size() const;
@ -45,6 +73,8 @@ public:
private:
twidget& widget_;
};
} // namespace gui2