summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralberth <alberth@openttd.org>2009-07-26 17:29:01 +0000
committeralberth <alberth@openttd.org>2009-07-26 17:29:01 +0000
commit9856cc9d0a339bace9c50a722e6a2bfc37cbdd88 (patch)
treeabfd00cb0e2915b31761021afe69aa39f372753e
parent2dd998ab06d0f79445bf96239da9944fa30b7578 (diff)
downloadopenttd-9856cc9d0a339bace9c50a722e6a2bfc37cbdd88.tar.xz
(svn r16963) -Codechange: Added NWidgetViewport widget.
-rw-r--r--src/widget.cpp69
-rw-r--r--src/widget_type.h20
-rw-r--r--src/window.cpp10
-rw-r--r--src/window_gui.h3
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) {}