mirror of https://github.com/OpenTTD/OpenTTD
(svn r18583) -Codechange: Add WWT_SHADEBOX widget and its functions (heavily based on code by erikjanp).
parent
c03aadda08
commit
ca66652005
|
@ -229,6 +229,7 @@ STR_BUTTON_RENAME :{BLACK}Rename
|
||||||
|
|
||||||
STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Close window
|
STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Close window
|
||||||
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window
|
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window
|
||||||
|
STR_TOOLTIP_SHADE :{BLACK}Shade window - Only show the titlebar
|
||||||
STR_TOOLTIP_STICKY :{BLACK}Mark this window as uncloseable by the 'Close All Windows' key
|
STR_TOOLTIP_STICKY :{BLACK}Mark this window as uncloseable by the 'Close All Windows' key
|
||||||
STR_TOOLTIP_RESIZE :{BLACK}Click and drag to resize this window
|
STR_TOOLTIP_RESIZE :{BLACK}Click and drag to resize this window
|
||||||
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size
|
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size
|
||||||
|
|
|
@ -452,6 +452,18 @@ static inline void DrawFrame(const Rect &r, Colours colour, StringID str)
|
||||||
GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
|
GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a shade box.
|
||||||
|
* @param r Rectangle of the box.
|
||||||
|
* @param colour Colour of the shade box.
|
||||||
|
* @param clicked Box is lowered.
|
||||||
|
*/
|
||||||
|
static inline void DrawShadeBox(const Rect &r, Colours colour, bool clicked)
|
||||||
|
{
|
||||||
|
DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE);
|
||||||
|
DrawSprite((clicked) ? SPR_WINDOW_SHADE : SPR_WINDOW_UNSHADE, PAL_NONE, r.left + WD_SHADEBOX_LEFT + clicked, r.top + WD_SHADEBOX_TOP + clicked);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a sticky box.
|
* Draw a sticky box.
|
||||||
* @param r Rectangle of the box.
|
* @param r Rectangle of the box.
|
||||||
|
@ -1673,11 +1685,13 @@ void NWidgetViewport::UpdateViewportCoordinates(Window *w)
|
||||||
/** Reset the cached dimensions. */
|
/** Reset the cached dimensions. */
|
||||||
/* static */ void NWidgetLeaf::InvalidateDimensionCache()
|
/* static */ void NWidgetLeaf::InvalidateDimensionCache()
|
||||||
{
|
{
|
||||||
|
shadebox_dimension.width = shadebox_dimension.height = 0;
|
||||||
stickybox_dimension.width = stickybox_dimension.height = 0;
|
stickybox_dimension.width = stickybox_dimension.height = 0;
|
||||||
resizebox_dimension.width = resizebox_dimension.height = 0;
|
resizebox_dimension.width = resizebox_dimension.height = 0;
|
||||||
closebox_dimension.width = closebox_dimension.height = 0;
|
closebox_dimension.width = closebox_dimension.height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dimension NWidgetLeaf::shadebox_dimension = {0, 0};
|
||||||
Dimension NWidgetLeaf::stickybox_dimension = {0, 0};
|
Dimension NWidgetLeaf::stickybox_dimension = {0, 0};
|
||||||
Dimension NWidgetLeaf::resizebox_dimension = {0, 0};
|
Dimension NWidgetLeaf::resizebox_dimension = {0, 0};
|
||||||
Dimension NWidgetLeaf::closebox_dimension = {0, 0};
|
Dimension NWidgetLeaf::closebox_dimension = {0, 0};
|
||||||
|
@ -1692,7 +1706,7 @@ Dimension NWidgetLeaf::closebox_dimension = {0, 0};
|
||||||
*/
|
*/
|
||||||
NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip)
|
NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip)
|
||||||
{
|
{
|
||||||
assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX);
|
assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_SHADEBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX);
|
||||||
if (index >= 0) this->SetIndex(index);
|
if (index >= 0) this->SetIndex(index);
|
||||||
this->SetMinimalSize(0, 0);
|
this->SetMinimalSize(0, 0);
|
||||||
this->SetResize(0, 0);
|
this->SetResize(0, 0);
|
||||||
|
@ -1751,6 +1765,12 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data,
|
||||||
this->SetDataTip(STR_NULL, STR_TOOLTIP_STICKY);
|
this->SetDataTip(STR_NULL, STR_TOOLTIP_STICKY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WWT_SHADEBOX:
|
||||||
|
this->SetFill(0, 0);
|
||||||
|
this->SetMinimalSize(WD_SHADEBOX_TOP, 14);
|
||||||
|
this->SetDataTip(STR_NULL, STR_TOOLTIP_SHADE);
|
||||||
|
break;
|
||||||
|
|
||||||
case WWT_RESIZEBOX:
|
case WWT_RESIZEBOX:
|
||||||
this->SetFill(0, 0);
|
this->SetFill(0, 0);
|
||||||
this->SetMinimalSize(WD_RESIZEBOX_WIDTH, 12);
|
this->SetMinimalSize(WD_RESIZEBOX_WIDTH, 12);
|
||||||
|
@ -1799,6 +1819,17 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
|
||||||
padding = &extra;
|
padding = &extra;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WWT_SHADEBOX: {
|
||||||
|
static const Dimension extra = {WD_SHADEBOX_LEFT + WD_SHADEBOX_RIGHT, WD_SHADEBOX_TOP + WD_SHADEBOX_BOTTOM};
|
||||||
|
padding = &extra;
|
||||||
|
if (NWidgetLeaf::shadebox_dimension.width == 0) {
|
||||||
|
NWidgetLeaf::shadebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_SHADE), GetSpriteSize(SPR_WINDOW_UNSHADE));
|
||||||
|
NWidgetLeaf::shadebox_dimension.width += extra.width;
|
||||||
|
NWidgetLeaf::shadebox_dimension.height += extra.height;
|
||||||
|
}
|
||||||
|
size = maxdim(size, NWidgetLeaf::shadebox_dimension);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WWT_STICKYBOX: {
|
case WWT_STICKYBOX: {
|
||||||
static const Dimension extra = {WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT, WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM};
|
static const Dimension extra = {WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT, WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM};
|
||||||
padding = &extra;
|
padding = &extra;
|
||||||
|
@ -2010,6 +2041,11 @@ void NWidgetLeaf::Draw(const Window *w)
|
||||||
(w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), &w->hscroll);
|
(w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), &w->hscroll);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WWT_SHADEBOX:
|
||||||
|
assert(this->widget_data == 0);
|
||||||
|
DrawShadeBox(r, this->colour, w->IsShaded());
|
||||||
|
break;
|
||||||
|
|
||||||
case WWT_STICKYBOX:
|
case WWT_STICKYBOX:
|
||||||
assert(this->widget_data == 0);
|
assert(this->widget_data == 0);
|
||||||
DrawStickyBox(r, this->colour, !!(w->flags4 & WF_STICKY));
|
DrawStickyBox(r, this->colour, !!(w->flags4 & WF_STICKY));
|
||||||
|
|
|
@ -61,6 +61,7 @@ enum WidgetType {
|
||||||
WWT_CAPTION, ///< Window caption (window title between closebox and stickybox)
|
WWT_CAPTION, ///< Window caption (window title between closebox and stickybox)
|
||||||
|
|
||||||
WWT_HSCROLLBAR, ///< Horizontal scrollbar
|
WWT_HSCROLLBAR, ///< Horizontal scrollbar
|
||||||
|
WWT_SHADEBOX, ///< Shade box (at top-right of a window, between caption and stickybox)
|
||||||
WWT_STICKYBOX, ///< Sticky box (normally at top-right of a window)
|
WWT_STICKYBOX, ///< Sticky box (normally at top-right of a window)
|
||||||
WWT_SCROLL2BAR, ///< 2nd vertical scrollbar
|
WWT_SCROLL2BAR, ///< 2nd vertical scrollbar
|
||||||
WWT_RESIZEBOX, ///< Resize box (normally at bottom-right of a window)
|
WWT_RESIZEBOX, ///< Resize box (normally at bottom-right of a window)
|
||||||
|
@ -468,6 +469,7 @@ public:
|
||||||
|
|
||||||
static void InvalidateDimensionCache();
|
static void InvalidateDimensionCache();
|
||||||
private:
|
private:
|
||||||
|
static Dimension shadebox_dimension; ///< Cached size of a shadebox widget.
|
||||||
static Dimension stickybox_dimension; ///< Cached size of a stickybox widget.
|
static Dimension stickybox_dimension; ///< Cached size of a stickybox widget.
|
||||||
static Dimension resizebox_dimension; ///< Cached size of a resizebox widget.
|
static Dimension resizebox_dimension; ///< Cached size of a resizebox widget.
|
||||||
static Dimension closebox_dimension; ///< Cached size of a closebox widget.
|
static Dimension closebox_dimension; ///< Cached size of a closebox widget.
|
||||||
|
|
|
@ -333,6 +333,11 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click)
|
||||||
nw->SetDirty(w);
|
nw->SetDirty(w);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case WWT_SHADEBOX:
|
||||||
|
nw->SetDirty(w);
|
||||||
|
w->SetShaded(!w->IsShaded());
|
||||||
|
return;
|
||||||
|
|
||||||
case WWT_STICKYBOX:
|
case WWT_STICKYBOX:
|
||||||
w->flags4 ^= WF_STICKY;
|
w->flags4 ^= WF_STICKY;
|
||||||
nw->SetDirty(w);
|
nw->SetDirty(w);
|
||||||
|
@ -391,6 +396,13 @@ static void DispatchMouseWheelEvent(Window *w, const NWidgetCore *nwid, int whee
|
||||||
{
|
{
|
||||||
if (nwid == NULL) return;
|
if (nwid == NULL) return;
|
||||||
|
|
||||||
|
/* Using wheel on caption/shade-box shades or unshades the window. */
|
||||||
|
if (nwid->type == WWT_CAPTION || nwid->type == WWT_SHADEBOX) {
|
||||||
|
w->SetShaded(!w->IsShaded());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scroll the widget attached to the scrollbar. */
|
||||||
Scrollbar *sb = nwid->FindScrollbar(w);
|
Scrollbar *sb = nwid->FindScrollbar(w);
|
||||||
if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
|
if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
|
||||||
sb->UpdatePosition(wheel);
|
sb->UpdatePosition(wheel);
|
||||||
|
@ -532,6 +544,30 @@ void Window::ReInit(int rx, int ry)
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set the shaded state of the window to \a make_shaded.
|
||||||
|
* @param make_shaded If \c true, shade the window (roll up until just the title bar is visible), else unshade/unroll the window to its original size.
|
||||||
|
* @note The method uses #Window::ReInit(), thus after the call, the whole window should be considered changed.
|
||||||
|
*/
|
||||||
|
void Window::SetShaded(bool make_shaded)
|
||||||
|
{
|
||||||
|
if (this->shade_select == NULL) return;
|
||||||
|
|
||||||
|
int desired = make_shaded ? STACKED_SELECTION_ZERO_SIZE : 0;
|
||||||
|
if (this->shade_select->shown_plane != desired) {
|
||||||
|
if (make_shaded) {
|
||||||
|
this->unshaded_size.width = this->width;
|
||||||
|
this->unshaded_size.height = this->height;
|
||||||
|
this->shade_select->SetDisplayedPlane(desired);
|
||||||
|
this->ReInit();
|
||||||
|
} else {
|
||||||
|
this->shade_select->SetDisplayedPlane(desired);
|
||||||
|
int dx = ((int)this->unshaded_size.width > this->width) ? (int)this->unshaded_size.width - this->width : 0;
|
||||||
|
int dy = ((int)this->unshaded_size.height > this->height) ? (int)this->unshaded_size.height - this->height : 0;
|
||||||
|
this->ReInit(dx, dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Find the Window whose parent pointer points to this window
|
/** Find the Window whose parent pointer points to this window
|
||||||
* @param w parent Window to find child of
|
* @param w parent Window to find child of
|
||||||
* @param wc Window class of the window to remove; WC_INVALID if class does not matter
|
* @param wc Window class of the window to remove; WC_INVALID if class does not matter
|
||||||
|
@ -711,8 +747,8 @@ void ChangeWindowOwner(Owner old_owner, Owner new_owner)
|
||||||
|
|
||||||
static void BringWindowToFront(Window *w);
|
static void BringWindowToFront(Window *w);
|
||||||
|
|
||||||
/** Find a window and make it the top-window on the screen. The window
|
/** Find a window and make it the top-window on the screen.
|
||||||
* gets a white border for a brief period of time to visualize its "activation"
|
* The window gets unshaded if it was shaded, and a white border is drawn at its edges for a brief period of time to visualize its "activation".
|
||||||
* @param cls WindowClass of the window to activate
|
* @param cls WindowClass of the window to activate
|
||||||
* @param number WindowNumber of the window to activate
|
* @param number WindowNumber of the window to activate
|
||||||
* @return a pointer to the window thus activated */
|
* @return a pointer to the window thus activated */
|
||||||
|
@ -721,6 +757,8 @@ Window *BringWindowToFrontById(WindowClass cls, WindowNumber number)
|
||||||
Window *w = FindWindowById(cls, number);
|
Window *w = FindWindowById(cls, number);
|
||||||
|
|
||||||
if (w != NULL) {
|
if (w != NULL) {
|
||||||
|
if (w->IsShaded()) w->SetShaded(false); // Restore original window size if it was shaded.
|
||||||
|
|
||||||
w->flags4 |= WF_WHITE_BORDER_MASK;
|
w->flags4 |= WF_WHITE_BORDER_MASK;
|
||||||
BringWindowToFront(w);
|
BringWindowToFront(w);
|
||||||
w->SetDirty();
|
w->SetDirty();
|
||||||
|
@ -1787,6 +1825,14 @@ static bool MaybeBringWindowToFront(Window *w)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use unshaded window size rather than current size for shaded windows. */
|
||||||
|
int w_width = w->width;
|
||||||
|
int w_height = w->height;
|
||||||
|
if (w->IsShaded()) {
|
||||||
|
w_width = w->unshaded_size.width;
|
||||||
|
w_height = w->unshaded_size.height;
|
||||||
|
}
|
||||||
|
|
||||||
Window *u;
|
Window *u;
|
||||||
FOR_ALL_WINDOWS_FROM_BACK_FROM(u, w->z_front) {
|
FOR_ALL_WINDOWS_FROM_BACK_FROM(u, w->z_front) {
|
||||||
/* A modal child will prevent the activation of the parent window */
|
/* A modal child will prevent the activation of the parent window */
|
||||||
|
@ -1804,9 +1850,9 @@ static bool MaybeBringWindowToFront(Window *w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Window sizes don't interfere, leave z-order alone */
|
/* Window sizes don't interfere, leave z-order alone */
|
||||||
if (w->left + w->width <= u->left ||
|
if (w->left + w_width <= u->left ||
|
||||||
u->left + u->width <= w->left ||
|
u->left + u->width <= w->left ||
|
||||||
w->top + w->height <= u->top ||
|
w->top + w_height <= u->top ||
|
||||||
u->top + u->height <= w->top) {
|
u->top + u->height <= w->top) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2233,7 +2279,8 @@ void UpdateWindows()
|
||||||
DrawDirtyBlocks();
|
DrawDirtyBlocks();
|
||||||
|
|
||||||
FOR_ALL_WINDOWS_FROM_BACK(w) {
|
FOR_ALL_WINDOWS_FROM_BACK(w) {
|
||||||
if (w->viewport != NULL) UpdateViewportPosition(w);
|
/* Update viewport only if window is not shaded. */
|
||||||
|
if (w->viewport != NULL && !w->IsShaded()) UpdateViewportPosition(w);
|
||||||
}
|
}
|
||||||
NetworkDrawChatMessage();
|
NetworkDrawChatMessage();
|
||||||
/* Redraw mouse cursor in case it was hidden */
|
/* Redraw mouse cursor in case it was hidden */
|
||||||
|
|
|
@ -74,6 +74,13 @@ enum WidgetDrawDistances {
|
||||||
WD_MATRIX_TOP = 3, ///< Offset at top of a matrix cell.
|
WD_MATRIX_TOP = 3, ///< Offset at top of a matrix cell.
|
||||||
WD_MATRIX_BOTTOM = 1, ///< Offset at bottom of a matrix cell.
|
WD_MATRIX_BOTTOM = 1, ///< Offset at bottom of a matrix cell.
|
||||||
|
|
||||||
|
/* WWT_SHADEBOX */
|
||||||
|
WD_SHADEBOX_WIDTH = 12, ///< Width of a standard shade box widget.
|
||||||
|
WD_SHADEBOX_LEFT = 2, ///< Left offset of shade sprite.
|
||||||
|
WD_SHADEBOX_RIGHT = 2, ///< Right offset of shade sprite.
|
||||||
|
WD_SHADEBOX_TOP = 3, ///< Top offset of shade sprite.
|
||||||
|
WD_SHADEBOX_BOTTOM = 3, ///< Bottom offset of shade sprite.
|
||||||
|
|
||||||
/* WWT_STICKYBOX */
|
/* WWT_STICKYBOX */
|
||||||
WD_STICKYBOX_WIDTH = 12, ///< Width of a standard sticky box widget.
|
WD_STICKYBOX_WIDTH = 12, ///< Width of a standard sticky box widget.
|
||||||
WD_STICKYBOX_LEFT = 2, ///< Left offset of sticky sprite.
|
WD_STICKYBOX_LEFT = 2, ///< Left offset of sticky sprite.
|
||||||
|
@ -381,6 +388,8 @@ public:
|
||||||
NWidgetBase *nested_root; ///< Root of the nested tree.
|
NWidgetBase *nested_root; ///< Root of the nested tree.
|
||||||
NWidgetBase **nested_array; ///< Array of pointers into the tree. Do not access directly, use #Window::GetWidget() instead.
|
NWidgetBase **nested_array; ///< Array of pointers into the tree. Do not access directly, use #Window::GetWidget() instead.
|
||||||
uint nested_array_size; ///< Size of the nested array.
|
uint nested_array_size; ///< Size of the nested array.
|
||||||
|
NWidgetStacked *shade_select; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c NULL, window cannot shade.
|
||||||
|
Dimension unshaded_size; ///< Last known unshaded size (only valid while shaded).
|
||||||
|
|
||||||
Window *parent; ///< Parent window.
|
Window *parent; ///< Parent window.
|
||||||
Window *z_front; ///< The window in front of us in z-order.
|
Window *z_front; ///< The window in front of us in z-order.
|
||||||
|
@ -528,6 +537,14 @@ public:
|
||||||
void SetDirty() const;
|
void SetDirty() const;
|
||||||
void ReInit(int rx = 0, int ry = 0);
|
void ReInit(int rx = 0, int ry = 0);
|
||||||
|
|
||||||
|
/** Is window shaded currently? */
|
||||||
|
inline bool IsShaded() const
|
||||||
|
{
|
||||||
|
return this->shade_select != NULL && this->shade_select->shown_plane == STACKED_SELECTION_ZERO_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetShaded(bool make_shaded);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark this window's data as invalid (in need of re-computing)
|
* Mark this window's data as invalid (in need of re-computing)
|
||||||
* @param data The data to invalidate with
|
* @param data The data to invalidate with
|
||||||
|
|
Loading…
Reference in New Issue