mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 23:50:25 +00:00
(svn r16515) -Codechange: Added scrollbar handling for nested widgets, and finding widgets by type or position in the tree.
This commit is contained in:
parent
5c9071fcff
commit
1a4934ef07
225
src/widget.cpp
225
src/widget.cpp
@ -47,25 +47,25 @@ static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom)
|
|||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Special handling for the scrollbar widget type.
|
/**
|
||||||
* Handles the special scrolling buttons and other
|
* Compute new position of the scrollbar after a click and updates the window flags.
|
||||||
* scrolling.
|
|
||||||
* @param w Window on which a scroll was performed.
|
* @param w Window on which a scroll was performed.
|
||||||
* @param wi Pointer to the scrollbar widget.
|
* @param wtp Scrollbar widget type.
|
||||||
|
* @param mi Minimum coordinate of the scroll bar.
|
||||||
|
* @param ma Maximum coordinate of the scroll bar.
|
||||||
* @param x The X coordinate of the mouse click.
|
* @param x The X coordinate of the mouse click.
|
||||||
* @param y The Y coordinate of the mouse click. */
|
* @param y The Y coordinate of the mouse click.
|
||||||
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
*/
|
||||||
|
static void ScrollbarClickPositioning(Window *w, WidgetType wtp, int x, int y, int mi, int ma)
|
||||||
{
|
{
|
||||||
int mi, ma, pos;
|
int pos;
|
||||||
Scrollbar *sb;
|
Scrollbar *sb;
|
||||||
|
|
||||||
switch (wi->type) {
|
switch (wtp) {
|
||||||
case WWT_SCROLLBAR:
|
case WWT_SCROLLBAR:
|
||||||
/* vertical scroller */
|
/* vertical scroller */
|
||||||
w->flags4 &= ~WF_HSCROLL;
|
w->flags4 &= ~WF_HSCROLL;
|
||||||
w->flags4 &= ~WF_SCROLL2;
|
w->flags4 &= ~WF_SCROLL2;
|
||||||
mi = wi->top;
|
|
||||||
ma = wi->bottom;
|
|
||||||
pos = y;
|
pos = y;
|
||||||
sb = &w->vscroll;
|
sb = &w->vscroll;
|
||||||
break;
|
break;
|
||||||
@ -74,8 +74,6 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||||||
/* 2nd vertical scroller */
|
/* 2nd vertical scroller */
|
||||||
w->flags4 &= ~WF_HSCROLL;
|
w->flags4 &= ~WF_HSCROLL;
|
||||||
w->flags4 |= WF_SCROLL2;
|
w->flags4 |= WF_SCROLL2;
|
||||||
mi = wi->top;
|
|
||||||
ma = wi->bottom;
|
|
||||||
pos = y;
|
pos = y;
|
||||||
sb = &w->vscroll2;
|
sb = &w->vscroll2;
|
||||||
break;
|
break;
|
||||||
@ -84,8 +82,6 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||||||
/* horizontal scroller */
|
/* horizontal scroller */
|
||||||
w->flags4 &= ~WF_SCROLL2;
|
w->flags4 &= ~WF_SCROLL2;
|
||||||
w->flags4 |= WF_HSCROLL;
|
w->flags4 |= WF_HSCROLL;
|
||||||
mi = wi->left;
|
|
||||||
ma = wi->right;
|
|
||||||
pos = x;
|
pos = x;
|
||||||
sb = &w->hscroll;
|
sb = &w->hscroll;
|
||||||
break;
|
break;
|
||||||
@ -106,8 +102,7 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||||||
|
|
||||||
if (_scroller_click_timeout == 0) {
|
if (_scroller_click_timeout == 0) {
|
||||||
_scroller_click_timeout = 6;
|
_scroller_click_timeout = 6;
|
||||||
if ((byte)(sb->pos + sb->cap) < sb->count)
|
if (sb->pos + sb->cap < sb->count) sb->pos++;
|
||||||
sb->pos++;
|
|
||||||
}
|
}
|
||||||
_left_button_clicked = false;
|
_left_button_clicked = false;
|
||||||
} else {
|
} else {
|
||||||
@ -116,10 +111,7 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||||||
if (pos < pt.x) {
|
if (pos < pt.x) {
|
||||||
sb->pos = max(sb->pos - sb->cap, 0);
|
sb->pos = max(sb->pos - sb->cap, 0);
|
||||||
} else if (pos > pt.y) {
|
} else if (pos > pt.y) {
|
||||||
sb->pos = min(
|
sb->pos = min(sb->pos + sb->cap, max(sb->count - sb->cap, 0));
|
||||||
sb->pos + sb->cap,
|
|
||||||
max(sb->count - sb->cap, 0)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
_scrollbar_start_pos = pt.x - mi - 9;
|
_scrollbar_start_pos = pt.x - mi - 9;
|
||||||
_scrollbar_size = ma - mi - 23;
|
_scrollbar_size = ma - mi - 23;
|
||||||
@ -132,6 +124,76 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||||||
w->SetDirty();
|
w->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Special handling for the scrollbar widget type.
|
||||||
|
* Handles the special scrolling buttons and other scrolling.
|
||||||
|
* @param w Window on which a scroll was performed.
|
||||||
|
* @param wi Pointer to the scrollbar widget.
|
||||||
|
* @param x The X coordinate of the mouse click.
|
||||||
|
* @param y The Y coordinate of the mouse click.
|
||||||
|
*/
|
||||||
|
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
||||||
|
{
|
||||||
|
int mi, ma;
|
||||||
|
|
||||||
|
switch (wi->type) {
|
||||||
|
case WWT_SCROLLBAR:
|
||||||
|
/* vertical scroller */
|
||||||
|
mi = wi->top;
|
||||||
|
ma = wi->bottom;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WWT_SCROLL2BAR:
|
||||||
|
/* 2nd vertical scroller */
|
||||||
|
mi = wi->top;
|
||||||
|
ma = wi->bottom;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WWT_HSCROLLBAR:
|
||||||
|
/* horizontal scroller */
|
||||||
|
mi = wi->left;
|
||||||
|
ma = wi->right;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
ScrollbarClickPositioning(w, wi->type, x, y, mi, ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Special handling for the scrollbar widget type.
|
||||||
|
* Handles the special scrolling buttons and other scrolling.
|
||||||
|
* @param w Window on which a scroll was performed.
|
||||||
|
* @param nw Pointer to the scrollbar widget.
|
||||||
|
* @param x The X coordinate of the mouse click.
|
||||||
|
* @param y The Y coordinate of the mouse click.
|
||||||
|
*/
|
||||||
|
void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y)
|
||||||
|
{
|
||||||
|
int mi, ma;
|
||||||
|
|
||||||
|
switch (nw->type) {
|
||||||
|
case WWT_SCROLLBAR:
|
||||||
|
/* vertical scroller */
|
||||||
|
mi = nw->pos_y;
|
||||||
|
ma = nw->pos_y + nw->current_y;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WWT_SCROLL2BAR:
|
||||||
|
/* 2nd vertical scroller */
|
||||||
|
mi = nw->pos_y;
|
||||||
|
ma = nw->pos_y + nw->current_y;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WWT_HSCROLLBAR:
|
||||||
|
/* horizontal scroller */
|
||||||
|
mi = nw->pos_x;
|
||||||
|
ma = nw->pos_x + nw->current_x;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
ScrollbarClickPositioning(w, nw->type, x, y, mi, ma);
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the index for the widget located at the given position
|
/** Returns the index for the widget located at the given position
|
||||||
* relative to the window. It includes all widget-corner pixels as well.
|
* relative to the window. It includes all widget-corner pixels as well.
|
||||||
* @param *w Window to look inside
|
* @param *w Window to look inside
|
||||||
@ -141,8 +203,12 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||||||
*/
|
*/
|
||||||
int GetWidgetFromPos(const Window *w, int x, int y)
|
int GetWidgetFromPos(const Window *w, int x, int y)
|
||||||
{
|
{
|
||||||
int found_index = -1;
|
if (w->nested_root != NULL) {
|
||||||
|
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
|
return (nw != NULL) ? nw->index : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int found_index = -1;
|
||||||
/* Go through the widgets and check if we find the widget that the coordinate is inside. */
|
/* Go through the widgets and check if we find the widget that the coordinate is inside. */
|
||||||
for (uint index = 0; index < w->widget_count; index++) {
|
for (uint index = 0; index < w->widget_count; index++) {
|
||||||
const Widget *wi = &w->widget[index];
|
const Widget *wi = &w->widget[index];
|
||||||
@ -912,6 +978,21 @@ void NWidgetBase::Invalidate(const Window *w) const
|
|||||||
SetDirtyBlocks(abs_left, abs_top, abs_left + this->current_x, abs_top + this->current_y);
|
SetDirtyBlocks(abs_left, abs_top, abs_left + this->current_x, abs_top + this->current_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn NWidgetCore *GetWidgetFromPos(int x, int y)
|
||||||
|
* Retrieve a widget by its position.
|
||||||
|
* @param x Horizontal position relative to the left edge of the window.
|
||||||
|
* @param y Vertical position relative to the top edge of the window.
|
||||||
|
* @return Returns the deepest nested widget that covers the given position, or \c NULL if no widget can be found.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn NWidgetBase *GetWidgetOfType(WidgetType tp)
|
||||||
|
* Retrieve a widget by its type.
|
||||||
|
* @param tp Widget type to search for.
|
||||||
|
* @return Returns the first widget of the specified type, or \c NULL if no widget can be found.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for resizable nested widgets.
|
* Constructor for resizable nested widgets.
|
||||||
* @param tp Nested widget type.
|
* @param tp Nested widget type.
|
||||||
@ -1047,6 +1128,18 @@ void NWidgetCore::StoreWidgets(Widget *widgets, int length, bool left_moving, bo
|
|||||||
w->tooltips = this->tool_tip;
|
w->tooltips = this->tool_tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn Scrollbar *NWidgetCore::FindScrollbar(Window *w, bool allow_next = true)
|
||||||
|
* Find the scrollbar of the widget through the Window::nested_array.
|
||||||
|
* @param w Window containing the widgets and the scrollbar,
|
||||||
|
* @param allow_next Search may be extended to the next widget.
|
||||||
|
*
|
||||||
|
* @todo This implementation uses the constraint that a scrollbar must be the next item in the #Window::nested_array, and the scrollbar
|
||||||
|
* data is stored in the #Window structure (#Window::vscroll, #Window::vscroll2, and #Window::hscroll).
|
||||||
|
* Alternative light-weight implementations may be considered, eg by sub-classing a canvas-like widget, and/or by having
|
||||||
|
* an explicit link between the scrollbar and the widget being scrolled.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor container baseclass.
|
* Constructor container baseclass.
|
||||||
* @param tp Type of the container.
|
* @param tp Type of the container.
|
||||||
@ -1067,6 +1160,16 @@ NWidgetContainer::~NWidgetContainer()
|
|||||||
this->tail = NULL;
|
this->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NWidgetBase *NWidgetContainer::GetWidgetOfType(WidgetType tp)
|
||||||
|
{
|
||||||
|
if (this->type == tp) return this;
|
||||||
|
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
|
||||||
|
NWidgetBase *nwid = child_wid->GetWidgetOfType(tp);
|
||||||
|
if (nwid != NULL) return nwid;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append widget \a wid to container.
|
* Append widget \a wid to container.
|
||||||
* @param wid Widget to append.
|
* @param wid Widget to append.
|
||||||
@ -1190,6 +1293,16 @@ void NWidgetStacked::Draw(const Window *w)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NWidgetCore *NWidgetStacked::GetWidgetFromPos(int x, int y)
|
||||||
|
{
|
||||||
|
if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
|
||||||
|
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
|
||||||
|
NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
|
||||||
|
if (nwid != NULL) return nwid;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
NWidgetPIPContainer::NWidgetPIPContainer(WidgetType tp) : NWidgetContainer(tp)
|
NWidgetPIPContainer::NWidgetPIPContainer(WidgetType tp) : NWidgetContainer(tp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1217,6 +1330,17 @@ void NWidgetPIPContainer::Draw(const Window *w)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NWidgetCore *NWidgetPIPContainer::GetWidgetFromPos(int x, int y)
|
||||||
|
{
|
||||||
|
if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
|
||||||
|
|
||||||
|
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
|
||||||
|
NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
|
||||||
|
if (nwid != NULL) return nwid;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** Horizontal container widget. */
|
/** Horizontal container widget. */
|
||||||
NWidgetHorizontal::NWidgetHorizontal() : NWidgetPIPContainer(NWID_HORIZONTAL)
|
NWidgetHorizontal::NWidgetHorizontal() : NWidgetPIPContainer(NWID_HORIZONTAL)
|
||||||
{
|
{
|
||||||
@ -1503,6 +1627,16 @@ void NWidgetSpacer::Invalidate(const Window *w) const
|
|||||||
/* Spacer widget never need repainting. */
|
/* Spacer widget never need repainting. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NWidgetCore *NWidgetSpacer::GetWidgetFromPos(int x, int y)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NWidgetBase *NWidgetSpacer::GetWidgetOfType(WidgetType tp)
|
||||||
|
{
|
||||||
|
return (this->type == tp) ? this : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor parent nested widgets.
|
* Constructor parent nested widgets.
|
||||||
* @param tp Type of parent widget.
|
* @param tp Type of parent widget.
|
||||||
@ -1641,6 +1775,33 @@ void NWidgetBackground::Draw(const Window *w)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NWidgetCore *NWidgetBackground::GetWidgetFromPos(int x, int y)
|
||||||
|
{
|
||||||
|
NWidgetCore *nwid = NULL;
|
||||||
|
if (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) {
|
||||||
|
if (this->child != NULL) nwid = this->child->GetWidgetFromPos(x, y);
|
||||||
|
if (nwid == NULL) nwid = this;
|
||||||
|
}
|
||||||
|
return nwid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scrollbar *NWidgetBackground::FindScrollbar(Window *w, bool allow_next)
|
||||||
|
{
|
||||||
|
if (this->index > 0 && allow_next && this->child == NULL && (uint)(this->index) + 1 < w->nested_array_size) {
|
||||||
|
NWidgetCore *next_wid = w->nested_array[this->index + 1];
|
||||||
|
if (next_wid != NULL) return next_wid->FindScrollbar(w, false);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NWidgetBase *NWidgetBackground::GetWidgetOfType(WidgetType tp)
|
||||||
|
{
|
||||||
|
NWidgetBase *nwid = NULL;
|
||||||
|
if (this->child != NULL) nwid = this->child->GetWidgetOfType(tp);
|
||||||
|
if (nwid == NULL && this->type == tp) nwid = this;
|
||||||
|
return nwid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nested leaf widget.
|
* Nested leaf widget.
|
||||||
* @param tp Type of leaf widget.
|
* @param tp Type of leaf widget.
|
||||||
@ -1839,6 +2000,28 @@ void NWidgetLeaf::Invalidate(const Window *w) const
|
|||||||
NWidgetBase::Invalidate(w);
|
NWidgetBase::Invalidate(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NWidgetCore *NWidgetLeaf::GetWidgetFromPos(int x, int y)
|
||||||
|
{
|
||||||
|
return (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) ? this : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scrollbar *NWidgetLeaf::FindScrollbar(Window *w, bool allow_next)
|
||||||
|
{
|
||||||
|
if (this->type == WWT_SCROLLBAR) return &w->vscroll;
|
||||||
|
if (this->type == WWT_SCROLL2BAR) return &w->vscroll2;
|
||||||
|
|
||||||
|
if (this->index > 0 && allow_next && (uint)(this->index) + 1 < w->nested_array_size) {
|
||||||
|
NWidgetCore *next_wid = w->nested_array[this->index + 1];
|
||||||
|
if (next_wid != NULL) return next_wid->FindScrollbar(w, false);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NWidgetBase *NWidgetLeaf::GetWidgetOfType(WidgetType tp)
|
||||||
|
{
|
||||||
|
return (this->type == tp) ? this : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intialize nested widget tree and convert to widget array.
|
* Intialize nested widget tree and convert to widget array.
|
||||||
* @param nwid Nested widget tree.
|
* @param nwid Nested widget tree.
|
||||||
|
@ -153,6 +153,7 @@ enum SizingType {
|
|||||||
|
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
class NWidgetCore;
|
class NWidgetCore;
|
||||||
|
struct Scrollbar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baseclass for nested widgets.
|
* Baseclass for nested widgets.
|
||||||
@ -170,6 +171,9 @@ public:
|
|||||||
virtual void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) = 0;
|
virtual void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) = 0;
|
||||||
virtual void FillNestedArray(NWidgetCore **array, uint length) = 0;
|
virtual void FillNestedArray(NWidgetCore **array, uint length) = 0;
|
||||||
|
|
||||||
|
virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
|
||||||
|
virtual NWidgetBase *GetWidgetOfType(WidgetType tp) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set additional space (padding) around the widget.
|
* Set additional space (padding) around the widget.
|
||||||
* @param top Amount of additional space above the widget.
|
* @param top Amount of additional space above the widget.
|
||||||
@ -284,6 +288,8 @@ public:
|
|||||||
void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
|
void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
|
||||||
/* virtual */ void FillNestedArray(NWidgetCore **array, uint length);
|
/* virtual */ void FillNestedArray(NWidgetCore **array, uint length);
|
||||||
|
|
||||||
|
virtual Scrollbar *FindScrollbar(Window *w, bool allow_next = true) = 0;
|
||||||
|
|
||||||
NWidgetDisplay disp_flags; ///< Flags that affect display and interaction with the widget.
|
NWidgetDisplay disp_flags; ///< Flags that affect display and interaction with the widget.
|
||||||
Colours colour; ///< Colour of this widget.
|
Colours colour; ///< Colour of this widget.
|
||||||
int index; ///< Index of the nested widget in the widget array of the window (\c -1 means 'not used').
|
int index; ///< Index of the nested widget in the widget array of the window (\c -1 means 'not used').
|
||||||
@ -335,6 +341,8 @@ public:
|
|||||||
/** Return whether the container is empty. */
|
/** Return whether the container is empty. */
|
||||||
inline bool IsEmpty() { return head == NULL; };
|
inline bool IsEmpty() { return head == NULL; };
|
||||||
|
|
||||||
|
/* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NWidgetBase *head; ///< Pointer to first widget in container.
|
NWidgetBase *head; ///< Pointer to first widget in container.
|
||||||
NWidgetBase *tail; ///< Pointer to last widget in container.
|
NWidgetBase *tail; ///< Pointer to last widget in container.
|
||||||
@ -352,6 +360,7 @@ public:
|
|||||||
void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
|
void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
|
||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
|
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Container with pre/inter/post child space. */
|
/** Container with pre/inter/post child space. */
|
||||||
@ -362,6 +371,8 @@ public:
|
|||||||
void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
|
void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
|
||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
|
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8 pip_pre; ///< Amount of space before first widget.
|
uint8 pip_pre; ///< Amount of space before first widget.
|
||||||
uint8 pip_inter; ///< Amount of space between widgets.
|
uint8 pip_inter; ///< Amount of space between widgets.
|
||||||
@ -416,6 +427,8 @@ public:
|
|||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
/* virtual */ void Invalidate(const Window *w) const;
|
/* virtual */ void Invalidate(const Window *w) const;
|
||||||
|
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
||||||
|
/* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Nested widget with a child.
|
/** Nested widget with a child.
|
||||||
@ -435,6 +448,9 @@ public:
|
|||||||
/* virtual */ void FillNestedArray(NWidgetCore **array, uint length);
|
/* virtual */ void FillNestedArray(NWidgetCore **array, uint length);
|
||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
|
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
||||||
|
/* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
|
||||||
|
/* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NWidgetPIPContainer *child; ///< Child widget.
|
NWidgetPIPContainer *child; ///< Child widget.
|
||||||
@ -448,6 +464,9 @@ public:
|
|||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
/* virtual */ void Invalidate(const Window *w) const;
|
/* virtual */ void Invalidate(const Window *w) const;
|
||||||
|
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
||||||
|
/* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
|
||||||
|
/* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
Widget *InitializeNWidgets(NWidgetBase *nwid, bool rtl = false);
|
Widget *InitializeNWidgets(NWidgetBase *nwid, bool rtl = false);
|
||||||
|
@ -399,18 +399,20 @@ static void DispatchMouseWheelEvent(Window *w, int widget, int wheel)
|
|||||||
{
|
{
|
||||||
if (widget < 0) return;
|
if (widget < 0) return;
|
||||||
|
|
||||||
|
Scrollbar *sb = NULL;
|
||||||
|
if (w->widget != NULL) {
|
||||||
const Widget *wi1 = &w->widget[widget];
|
const Widget *wi1 = &w->widget[widget];
|
||||||
const Widget *wi2 = &w->widget[widget + 1];
|
const Widget *wi2 = &w->widget[widget + 1];
|
||||||
|
if (wi1->type == WWT_SCROLLBAR || wi2->type == WWT_SCROLLBAR) {
|
||||||
|
sb = &w->vscroll;
|
||||||
|
} else if (wi1->type == WWT_SCROLL2BAR || wi2->type == WWT_SCROLL2BAR) {
|
||||||
|
sb = &w->vscroll2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The listbox can only scroll if scrolling was done on the scrollbar itself,
|
if (w->nested_array != NULL && (uint)widget < w->nested_array_size) sb = w->nested_array[widget]->FindScrollbar(w);
|
||||||
* or on the listbox (and the next item is (must be) the scrollbar)
|
|
||||||
* XXX - should be rewritten as a widget-dependent scroller but that's
|
|
||||||
* not happening until someone rewrites the whole widget-code */
|
|
||||||
Scrollbar *sb;
|
|
||||||
if ((sb = &w->vscroll, wi1->type == WWT_SCROLLBAR) || (sb = &w->vscroll2, wi1->type == WWT_SCROLL2BAR) ||
|
|
||||||
(sb = &w->vscroll2, wi2->type == WWT_SCROLL2BAR) || (sb = &w->vscroll, wi2->type == WWT_SCROLLBAR) ) {
|
|
||||||
|
|
||||||
if (sb->count > sb->cap) {
|
if (sb != NULL && sb->count > sb->cap) {
|
||||||
int pos = Clamp(sb->pos + wheel, 0, sb->count - sb->cap);
|
int pos = Clamp(sb->pos + wheel, 0, sb->count - sb->cap);
|
||||||
if (pos != sb->pos) {
|
if (pos != sb->pos) {
|
||||||
sb->pos = pos;
|
sb->pos = pos;
|
||||||
@ -418,7 +420,6 @@ static void DispatchMouseWheelEvent(Window *w, int widget, int wheel)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate repaint events for the visible part of window w within the rectangle.
|
* Generate repaint events for the visible part of window w within the rectangle.
|
||||||
|
Loading…
Reference in New Issue
Block a user