From 9856cc9d0a339bace9c50a722e6a2bfc37cbdd88 Mon Sep 17 00:00:00 2001 From: alberth Date: Sun, 26 Jul 2009 17:29:01 +0000 Subject: (svn r16963) -Codechange: Added NWidgetViewport widget. --- src/widget.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/widget_type.h | 20 ++++++++++++++++ src/window.cpp | 10 ++++---- src/window_gui.h | 3 ++- 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 4ece7f3a5..0f8aec3de 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -6,6 +6,8 @@ #include "company_func.h" #include "gfx_func.h" #include "window_gui.h" +#include "viewport_func.h" +#include "zoom_func.h" #include "debug.h" #include "strings_func.h" @@ -1798,6 +1800,65 @@ NWidgetBase *NWidgetBackground::GetWidgetOfType(WidgetType tp) return nwid; } +NWidgetViewport::NWidgetViewport(int index) : NWidgetCore(NWID_VIEWPORT, INVALID_COLOUR, true, true, 0x0, STR_NULL) +{ + this->SetIndex(index); +} + +void NWidgetViewport::SetupSmallestSize(Window *w, bool init_array) +{ + if (init_array && this->index >= 0) { + assert(w->nested_array_size > (uint)this->index); + w->nested_array[this->index] = this; + } + this->smallest_x = this->min_x; + this->smallest_y = this->min_y; +} + +void NWidgetViewport::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) +{ + NOT_REACHED(); +} + +void NWidgetViewport::Draw(const Window *w) +{ + w->DrawViewport(); +} + +Scrollbar *NWidgetViewport::FindScrollbar(Window *w, bool allow_next) +{ + return NULL; +} + +/** + * Initialize the viewport of the window. + * @param w Window owning the viewport. + * @param follow_flags Type of viewport, see #InitializeViewport(). + * @param zoom Zoom level. + */ +void NWidgetViewport::InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom) +{ + InitializeWindowViewport(w, this->pos_x, this->pos_y, this->current_x, this->current_y, follow_flags, zoom); +} + +/** + * Update the position and size of the viewport (after eg a resize). + * @param w Window owning the viewport. + */ +void NWidgetViewport::UpdateViewportCoordinates(Window *w) +{ + ViewPort *vp = w->viewport; + if (vp != NULL) { + vp->left = w->left + this->pos_x; + vp->top = w->top + this->pos_y; + vp->width = this->current_x; + vp->height = this->current_y; + + vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); + vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); + } +} + /** Reset the cached dimensions. */ /* static */ void NWidgetLeaf::InvalidateDimensionCache() { @@ -2401,9 +2462,15 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_ENDCONTAINER: return num_used; + case NWID_VIEWPORT: + if (*dest != NULL) return num_used; + *dest = new NWidgetViewport(parts->u.widget.index); + *biggest_index = max(*biggest_index, (int)parts->u.widget.index); + break; + default: if (*dest != NULL) return num_used; - assert((parts->type & WWT_MASK) < NWID_HORIZONTAL); + assert((parts->type & WWT_MASK) < WWT_LAST); *dest = new NWidgetLeaf(parts->type, parts->u.widget.colour, parts->u.widget.index, 0x0, STR_NULL); *biggest_index = max(*biggest_index, (int)parts->u.widget.index); break; diff --git a/src/widget_type.h b/src/widget_type.h index 58c9c580b..ae30eac0b 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -113,6 +113,7 @@ enum WidgetType { NWID_SPACER, ///< Invisible widget that takes some space. NWID_SELECTION, ///< Stacked widgets, only one visible at a time (eg in a panel with tabs). NWID_LAYERED, ///< Widgets layered on top of each other, all visible at the same time. + NWID_VIEWPORT, ///< Nested widget containing a viewport. /* Nested widget part types. */ WPT_RESIZE, ///< Widget part for specifying resizing. @@ -471,6 +472,25 @@ private: NWidgetPIPContainer *child; ///< Child widget. }; +/** + * Nested widget to display a viewport in a window. + * After initializing the nested widget tree, call #InitializeViewport(). After changing the window size, + * call #UpdateViewportCoordinates() eg from Window::OnResize(). + * @todo Class derives from #NWidgetCore, but does not use #colour, #widget_data, or #tool_tip. + * @ingroup NestedWidgets */ +class NWidgetViewport : public NWidgetCore { +public: + NWidgetViewport(int index); + + /* virtual */ void SetupSmallestSize(Window *w, bool init_array); + /* virtual */ void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl); + /* virtual */ void Draw(const Window *w); + /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true); + + void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom); + void UpdateViewportCoordinates(Window *w); +}; + /** Leaf widget. * @ingroup NestedWidgets */ class NWidgetLeaf : public NWidgetCore { diff --git a/src/window.cpp b/src/window.cpp index 2f79cdc77..4d83af2b3 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -560,9 +560,7 @@ void SetWindowDirty(const Window *w) if (w != NULL) w->SetDirty(); } -/** Re-initialize a window. - * @todo Extend the function to handle viewports. - */ +/** Re-initialize a window. */ void Window::ReInit() { if (this->nested_root == NULL) return; // Only nested widget windows can re-initialize. @@ -595,6 +593,10 @@ void Window::ReInit() if (dx == 0 && dy == 0) { // No resize needed. this->SetDirty(); + if (this->viewport != NULL) { + NWidgetViewport *nvp = (NWidgetViewport *)nested_root->GetWidgetOfType(NWID_VIEWPORT); + nvp->UpdateViewportCoordinates(this); + } return; } @@ -602,7 +604,7 @@ void Window::ReInit() Point diff; diff.x = dx; diff.y = dy; - this->OnResize(diff); + this->OnResize(diff); // Calls NWidgetViewport::UpdateViewportCoordinates() } /** Find the Window whose parent pointer points to this window diff --git a/src/window_gui.h b/src/window_gui.h index ff806d1f1..3ea0f7c2e 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -193,7 +193,7 @@ enum SortButtonState { * A viewport is either following a vehicle (its id in then in #follow_vehicle), or it aims to display a specific * location #dest_scrollpos_x, #dest_scrollpos_y (#follow_vehicle is then #INVALID_VEHICLE). * The actual location being shown is #scrollpos_x, #scrollpos_y. - * @see InitializeViewport(), UpdateViewportPosition(). + * @see InitializeViewport(), UpdateViewportPosition(), UpdateViewportCoordinates(). */ struct ViewportData : ViewPort { VehicleID follow_vehicle; ///< VehicleID to follow if following a vehicle, #INVALID_VEHICLE otherwise. @@ -644,6 +644,7 @@ public: /** * Called after the window got resized. + * For nested windows with a viewport, call NWidgetViewport::UpdateViewportCoordinates. * @param delta The amount of which the window size changed. */ virtual void OnResize(Point delta) {} -- cgit v1.2.3-70-g09d2