Merge remote-tracking branch 'origin/master' into HEAD
This commit is contained in:
395
src/widget.cpp
395
src/widget.cpp
@@ -18,7 +18,10 @@
|
||||
#include "transparency.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "settings_type.h"
|
||||
#include "settings_gui.h"
|
||||
#include "querystring_gui.h"
|
||||
#include "blitter/factory.hpp"
|
||||
|
||||
|
||||
#include "table/sprites.h"
|
||||
#include "table/strings.h"
|
||||
@@ -47,6 +50,11 @@ static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom, bo
|
||||
}
|
||||
top += button_size; // top points to just below the up-button
|
||||
bottom -= button_size; // bottom points to top of the down-button
|
||||
bool wide_enough = false;
|
||||
if (bottom > top + button_size * 2) {
|
||||
bottom -= button_size; // Slider should be no smaller than a regular button, reserve some size from bottom
|
||||
wide_enough = true;
|
||||
}
|
||||
|
||||
int height = (bottom - top);
|
||||
int pos = sb->GetPosition();
|
||||
@@ -57,10 +65,11 @@ static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom, bo
|
||||
|
||||
if (cap > count) cap = count;
|
||||
if (count != 0) bottom -= (count - pos - cap) * height / count;
|
||||
if (wide_enough) bottom += button_size;
|
||||
|
||||
Point pt;
|
||||
if (horizontal && _current_text_dir == TD_RTL) {
|
||||
pt.x = rev_base - bottom;
|
||||
pt.x = rev_base - bottom - button_size;
|
||||
pt.y = rev_base - top;
|
||||
} else {
|
||||
pt.x = top;
|
||||
@@ -96,7 +105,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
|
||||
/* Pressing the upper button? */
|
||||
SetBit(sb->disp_flags, NDB_SCROLLBAR_UP);
|
||||
if (_scroller_click_timeout <= 1) {
|
||||
_scroller_click_timeout = 3;
|
||||
_scroller_click_timeout = SCROLLER_CLICK_DELAY;
|
||||
sb->UpdatePosition(rtl ? 1 : -1);
|
||||
}
|
||||
w->mouse_capture_widget = sb->index;
|
||||
@@ -105,7 +114,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
|
||||
SetBit(sb->disp_flags, NDB_SCROLLBAR_DOWN);
|
||||
|
||||
if (_scroller_click_timeout <= 1) {
|
||||
_scroller_click_timeout = 3;
|
||||
_scroller_click_timeout = SCROLLER_CLICK_DELAY;
|
||||
sb->UpdatePosition(rtl ? -1 : 1);
|
||||
}
|
||||
w->mouse_capture_widget = sb->index;
|
||||
@@ -119,7 +128,10 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
|
||||
} else {
|
||||
_scrollbar_start_pos = pt.x - mi - button_size;
|
||||
_scrollbar_size = ma - mi - button_size * 2;
|
||||
if (_scrollbar_size > button_size * 2)
|
||||
_scrollbar_size -= button_size;
|
||||
w->mouse_capture_widget = sb->index;
|
||||
w->scrolling_scrollbar = sb->index;
|
||||
_cursorpos_drag_start = _cursor.pos;
|
||||
}
|
||||
}
|
||||
@@ -342,10 +354,10 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_
|
||||
|
||||
/* draw up/down buttons */
|
||||
DrawFrameRect(r.left, r.top, r.right, r.top + height - 1, colour, (up_clicked) ? FR_LOWERED : FR_NONE);
|
||||
DrawSprite(SPR_ARROW_UP, PAL_NONE, r.left + 1 + up_clicked, r.top + 1 + up_clicked);
|
||||
DrawSpriteCenteredRect(SPR_ARROW_UP, PAL_NONE, r.left + 2 + up_clicked * 2, r.top + 2 + up_clicked * 2, r.right, r.top + height);
|
||||
|
||||
DrawFrameRect(r.left, r.bottom - (height - 1), r.right, r.bottom, colour, (down_clicked) ? FR_LOWERED : FR_NONE);
|
||||
DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + down_clicked, r.bottom - (height - 2) + down_clicked);
|
||||
DrawSpriteCenteredRect(SPR_ARROW_DOWN, PAL_NONE, r.left + 2 + down_clicked * 2, r.bottom - height + 2 + down_clicked, r.right, r.bottom);
|
||||
|
||||
int c1 = _colour_gradient[colour & 0xF][3];
|
||||
int c2 = _colour_gradient[colour & 0xF][7];
|
||||
@@ -377,12 +389,13 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l
|
||||
{
|
||||
int centre = (r.bottom - r.top) / 2;
|
||||
int width = NWidgetScrollbar::GetHorizontalDimension().width;
|
||||
int height = NWidgetScrollbar::GetVerticalDimension().height;
|
||||
|
||||
DrawFrameRect(r.left, r.top, r.left + width - 1, r.bottom, colour, left_clicked ? FR_LOWERED : FR_NONE);
|
||||
DrawSprite(SPR_ARROW_LEFT, PAL_NONE, r.left + 1 + left_clicked, r.top + 1 + left_clicked);
|
||||
DrawSpriteCenteredRect(SPR_ARROW_LEFT, PAL_NONE, r.left + left_clicked * 2, r.top + 2 + left_clicked * 2, r.left + height, r.bottom);
|
||||
|
||||
DrawFrameRect(r.right - (width - 1), r.top, r.right, r.bottom, colour, right_clicked ? FR_LOWERED : FR_NONE);
|
||||
DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - (width - 2) + right_clicked, r.top + 1 + right_clicked);
|
||||
DrawSpriteCenteredRect(SPR_ARROW_RIGHT, PAL_NONE, r.right - width + right_clicked * 2, r.top + 2 + right_clicked * 2, r.right, r.bottom);
|
||||
|
||||
int c1 = _colour_gradient[colour & 0xF][3];
|
||||
int c2 = _colour_gradient[colour & 0xF][7];
|
||||
@@ -537,16 +550,14 @@ static inline void DrawCloseBox(const Rect &r, Colours colour)
|
||||
* @param owner 'Owner' of the window.
|
||||
* @param str Text to draw in the bar.
|
||||
*/
|
||||
void DrawCaption(const Rect &r, Colours colour, Owner owner, StringID str)
|
||||
void DrawCaption(const Rect &r, Colours colour, Owner owner, StringID str, const NWidgetCore *widget, const Window *window)
|
||||
{
|
||||
bool company_owned = owner < MAX_COMPANIES;
|
||||
|
||||
GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, company_owned ? _colour_gradient[_company_colours[owner]][4] : _colour_gradient[colour][5]);
|
||||
if (widget != NULL && window != NULL) widget->DrawEdgeOrnament(window);
|
||||
DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_BORDERONLY);
|
||||
DrawFrameRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour, company_owned ? FR_LOWERED | FR_DARKENED | FR_BORDERONLY : FR_LOWERED | FR_DARKENED);
|
||||
|
||||
if (company_owned) {
|
||||
GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, _colour_gradient[_company_colours[owner]][4]);
|
||||
}
|
||||
DrawFrameRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour, FR_LOWERED | FR_DARKENED | FR_BORDERONLY);
|
||||
|
||||
if (str != STR_NULL) {
|
||||
Dimension d = GetStringBoundingBox(str);
|
||||
@@ -569,19 +580,19 @@ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicke
|
||||
{
|
||||
int text_offset = max(0, ((int)(r.bottom - r.top + 1) - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered
|
||||
|
||||
int dd_width = NWidgetLeaf::dropdown_dimension.width;
|
||||
int dd_height = NWidgetLeaf::dropdown_dimension.height;
|
||||
int dd_width = GetMinSizing(NWST_STEP, NWidgetLeaf::dropdown_dimension.width);
|
||||
int dd_height = GetMinSizing(NWST_STEP, NWidgetLeaf::dropdown_dimension.height);
|
||||
int image_offset = max(0, ((int)(r.bottom - r.top + 1) - dd_height) / 2);
|
||||
|
||||
if (_current_text_dir == TD_LTR) {
|
||||
DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE);
|
||||
DrawFrameRect(r.right + 1 - dd_width, r.top, r.right, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE);
|
||||
DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown, r.top + image_offset + clicked_dropdown);
|
||||
DrawSpriteCenteredRect(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown * 2, r.top + image_offset + clicked_dropdown * 2, r.right, r.bottom);
|
||||
if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - dd_width - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK);
|
||||
} else {
|
||||
DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE);
|
||||
DrawFrameRect(r.left, r.top, r.left + dd_width - 1, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE);
|
||||
DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown, r.top + image_offset + clicked_dropdown);
|
||||
DrawSpriteCenteredRect(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown * 2, r.top + image_offset + clicked_dropdown * 2, r.left + dd_width, r.bottom);
|
||||
if (str != STR_NULL) DrawString(r.left + dd_width + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK);
|
||||
}
|
||||
}
|
||||
@@ -628,6 +639,11 @@ void Window::DrawWidgets() const
|
||||
GfxFillRect(left, bottom, right, bottom, colour);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dim the window if it's about to close */
|
||||
if ((this->flags & WF_DRAGGING) && !_settings_client.gui.windows_titlebars && GetWindowDraggedOffScreen(this)) {
|
||||
GfxFillRect(2, 2, this->width - 3, this->height - 3, PALETTE_TO_TRANSPARENT, FILLRECT_RECOLOUR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -643,12 +659,11 @@ void Window::DrawSortButtonState(int widget, SortButtonState state) const
|
||||
const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
|
||||
|
||||
/* Sort button uses the same sprites as vertical scrollbar */
|
||||
Dimension dim = NWidgetScrollbar::GetVerticalDimension();
|
||||
int offset = this->IsWidgetLowered(widget) ? 1 : 0;
|
||||
int x = offset + nwid->pos_x + (_current_text_dir == TD_LTR ? nwid->current_x - dim.width : 0);
|
||||
int y = offset + nwid->pos_y + (nwid->current_y - dim.height) / 2;
|
||||
int x = offset + nwid->pos_x + (_current_text_dir == TD_LTR ? nwid->current_x - SETTING_BUTTON_HEIGHT / 2 : SETTING_BUTTON_HEIGHT / 2);
|
||||
int y = offset + Center(nwid->pos_y, nwid->current_y, FONT_HEIGHT_NORMAL / 4);
|
||||
|
||||
DrawSprite(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, x, y);
|
||||
DrawSpriteCentered(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -805,6 +820,7 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp)
|
||||
*/
|
||||
NWidgetResizeBase::NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y) : NWidgetBase(tp)
|
||||
{
|
||||
this->sizing_type = NWST_NONE;
|
||||
this->fill_x = fill_x;
|
||||
this->fill_y = fill_y;
|
||||
}
|
||||
@@ -818,6 +834,27 @@ void NWidgetResizeBase::SetMinimalSize(uint min_x, uint min_y)
|
||||
{
|
||||
this->min_x = max(this->min_x, min_x);
|
||||
this->min_y = max(this->min_y, min_y);
|
||||
uint min_size = 0;
|
||||
switch (this->sizing_type) {
|
||||
case NWST_NONE:
|
||||
case NWST_OVERRIDE:
|
||||
min_size = 0;
|
||||
break;
|
||||
case NWST_BUTTON:
|
||||
min_size = _settings_client.gui.min_button;
|
||||
break;
|
||||
case NWST_STEP:
|
||||
min_size = _settings_client.gui.min_step;
|
||||
break;
|
||||
case NWST_VIEWPORT:
|
||||
min_size = 3 * _settings_client.gui.min_button;
|
||||
break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
min_size = RescaleFrom854x480(min_size);
|
||||
|
||||
this->min_x = max(min_x, min_size);
|
||||
this->min_y = max(min_y, min_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -869,6 +906,7 @@ void NWidgetResizeBase::AssignSizePosition(SizingType sizing, uint x, uint y, ui
|
||||
*/
|
||||
NWidgetCore::NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint32 widget_data, StringID tool_tip) : NWidgetResizeBase(tp, fill_x, fill_y)
|
||||
{
|
||||
this->sizing_type = NWST_NONE;
|
||||
this->colour = colour;
|
||||
this->index = -1;
|
||||
this->widget_data = widget_data;
|
||||
@@ -907,6 +945,192 @@ NWidgetCore *NWidgetCore::GetWidgetFromPos(int x, int y)
|
||||
return (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) ? this : NULL;
|
||||
}
|
||||
|
||||
void NWidgetCore::DrawEdgeOrnament(const Window *w) const
|
||||
{
|
||||
if (!_settings_client.gui.windows_decorations) return;
|
||||
if (w->window_class == WC_MAIN_TOOLBAR ||
|
||||
w->window_class == WC_MAIN_TOOLBAR_RIGHT ||
|
||||
w->window_class == WC_BUILD_CONFIRMATION ||
|
||||
w->window_class == WC_STATUS_BAR ||
|
||||
w->window_class == WC_TOOLTIPS ||
|
||||
w->window_class == WC_DROPDOWN_MENU) {
|
||||
return;
|
||||
}
|
||||
if (this->pos_x == 0) {
|
||||
DrawEdgeOrnamentL();
|
||||
}
|
||||
if (int(this->pos_x + this->current_x) == w->width) {
|
||||
DrawEdgeOrnamentR();
|
||||
}
|
||||
if (this->pos_y == 0) {
|
||||
DrawEdgeOrnamentT();
|
||||
}
|
||||
if (int(this->pos_y + this->current_y) == w->height) {
|
||||
DrawEdgeOrnamentB();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ornament image
|
||||
|
||||
- - - - - - - - - - - - - - - - 0
|
||||
- - - - - - - + + + - - - + + + 1
|
||||
+ - - - - - + - - - + - + - - - 2
|
||||
- + - - - + - - - - - + - - - - 3
|
||||
- - + - + - - - - - - + - - - - 4
|
||||
- - - + - - - + - - + - + - - + 5
|
||||
- - - - - - - - + + - - - + + - 6
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
*/
|
||||
|
||||
static const unsigned char ornamentImg[][2] = {
|
||||
{ 0, 2, },
|
||||
{ 1, 3, },
|
||||
{ 2, 4, },
|
||||
{ 3, 5, },
|
||||
{ 4, 4, },
|
||||
{ 5, 3, },
|
||||
{ 6, 2, },
|
||||
{ 7, 1, },
|
||||
{ 7, 5, },
|
||||
{ 8, 1, },
|
||||
{ 8, 6, },
|
||||
{ 9, 1, },
|
||||
{ 9, 6, },
|
||||
{ 10, 2, },
|
||||
{ 10, 5, },
|
||||
{ 11, 3, },
|
||||
{ 11, 4, },
|
||||
{ 12, 2, },
|
||||
{ 12, 5, },
|
||||
{ 13, 1, },
|
||||
{ 13, 6, },
|
||||
{ 14, 1, },
|
||||
{ 14, 6, },
|
||||
{ 15, 1, },
|
||||
{ 15, 5, },
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
ORNAMENT_STEP = 16,
|
||||
ORNAMENT_HEIGHT = 4,
|
||||
ORNAMENT_IMG_LEN = sizeof(ornamentImg) / sizeof(ornamentImg[0])
|
||||
};
|
||||
|
||||
|
||||
void NWidgetCore::DrawEdgeOrnamentL() const
|
||||
{
|
||||
if (_cur_dpi == NULL || _cur_dpi->zoom != ZOOM_LVL_NORMAL) return;
|
||||
|
||||
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
|
||||
|
||||
void *dst = _cur_dpi->dst_ptr;
|
||||
int left = _cur_dpi->left;
|
||||
int width = _cur_dpi->width;
|
||||
int top = _cur_dpi->top;
|
||||
int height = _cur_dpi->height;
|
||||
|
||||
int edge = this->pos_y + this->current_y - top - 1 - ORNAMENT_HEIGHT;
|
||||
|
||||
int x = this->pos_x - left;
|
||||
|
||||
for (int y = this->pos_y - top + 1 + ORNAMENT_HEIGHT; y < edge + ORNAMENT_STEP; y += ORNAMENT_STEP) {
|
||||
for (int i = 0; i < ORNAMENT_IMG_LEN; i++) {
|
||||
int xx = x + ornamentImg[i][1];
|
||||
int yy = y + ornamentImg[i][0];
|
||||
if (yy >= height || yy >= edge) break;
|
||||
if (xx >= 0 && xx < width && yy >= 0) {
|
||||
blitter->SetPixel(dst, xx, yy, PC_DARK_GREY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NWidgetCore::DrawEdgeOrnamentR() const
|
||||
{
|
||||
if (_cur_dpi == NULL || _cur_dpi->zoom != ZOOM_LVL_NORMAL) return;
|
||||
|
||||
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
|
||||
|
||||
void *dst = _cur_dpi->dst_ptr;
|
||||
int left = _cur_dpi->left;
|
||||
int width = _cur_dpi->width;
|
||||
int top = _cur_dpi->top;
|
||||
int height = _cur_dpi->height;
|
||||
|
||||
int edge = this->pos_y + this->current_y - top - 1 - ORNAMENT_HEIGHT;
|
||||
|
||||
int x = this->pos_x + this->current_x - left - 1;
|
||||
|
||||
for (int y = this->pos_y - top + 1 + ORNAMENT_HEIGHT; y < edge + ORNAMENT_STEP; y += ORNAMENT_STEP) {
|
||||
for (int i = 0; i < ORNAMENT_IMG_LEN; i++) {
|
||||
int xx = x - ornamentImg[i][1];
|
||||
int yy = y + ornamentImg[i][0];
|
||||
if (yy >= height || yy >= edge) break;
|
||||
if (xx >= 0 && xx < width && yy >= 0) {
|
||||
blitter->SetPixel(dst, xx, yy, PC_DARK_GREY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NWidgetCore::DrawEdgeOrnamentT() const
|
||||
{
|
||||
if (_cur_dpi == NULL || _cur_dpi->zoom != ZOOM_LVL_NORMAL) return;
|
||||
|
||||
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
|
||||
|
||||
void *dst = _cur_dpi->dst_ptr;
|
||||
int left = _cur_dpi->left;
|
||||
int width = _cur_dpi->width;
|
||||
int top = _cur_dpi->top;
|
||||
int height = _cur_dpi->height;
|
||||
|
||||
int edge = this->pos_x + this->current_x - left - 1 - ORNAMENT_HEIGHT;
|
||||
|
||||
int y = this->pos_y - top;
|
||||
|
||||
for (int x = this->pos_x - left + 1 + ORNAMENT_HEIGHT; x < edge + ORNAMENT_STEP; x += ORNAMENT_STEP) {
|
||||
for (int i = 0; i < ORNAMENT_IMG_LEN; i++) {
|
||||
int xx = x + ornamentImg[i][0];
|
||||
int yy = y + ornamentImg[i][1];
|
||||
if (xx >= width || xx >= edge) break;
|
||||
if (yy >= 0 && yy < height && xx >= 0) {
|
||||
blitter->SetPixel(dst, xx, yy, PC_DARK_GREY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NWidgetCore::DrawEdgeOrnamentB() const
|
||||
{
|
||||
if (_cur_dpi == NULL || _cur_dpi->zoom != ZOOM_LVL_NORMAL) return;
|
||||
|
||||
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
|
||||
|
||||
void *dst = _cur_dpi->dst_ptr;
|
||||
int left = _cur_dpi->left;
|
||||
int width = _cur_dpi->width;
|
||||
int top = _cur_dpi->top;
|
||||
int height = _cur_dpi->height;
|
||||
|
||||
int edge = this->pos_x + this->current_x - left - 1 - ORNAMENT_HEIGHT;
|
||||
|
||||
int y = this->pos_y + this->current_y - top - 1;
|
||||
|
||||
for (int x = this->pos_x - left + 1 + ORNAMENT_HEIGHT; x < edge + ORNAMENT_STEP; x += ORNAMENT_STEP) {
|
||||
for (int i = 0; i < ORNAMENT_IMG_LEN; i++) {
|
||||
int xx = x + ornamentImg[i][0];
|
||||
int yy = y - ornamentImg[i][1];
|
||||
if (xx >= width || xx >= edge) break;
|
||||
if (yy >= 0 && yy < height && xx >= 0) {
|
||||
blitter->SetPixel(dst, xx, yy, PC_DARK_GREY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor container baseclass.
|
||||
* @param tp Type of the container.
|
||||
@@ -1859,6 +2083,8 @@ void NWidgetBackground::Draw(const Window *w)
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
DrawEdgeOrnament(w);
|
||||
|
||||
if (this->index >= 0) w->DrawWidget(r, this->index);
|
||||
if (this->child != NULL) this->child->Draw(w);
|
||||
|
||||
@@ -1867,6 +2093,7 @@ void NWidgetBackground::Draw(const Window *w)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NWidgetCore *NWidgetBackground::GetWidgetFromPos(int x, int y)
|
||||
{
|
||||
NWidgetCore *nwid = NULL;
|
||||
@@ -1989,6 +2216,7 @@ void Scrollbar::SetCapacityFromWidget(Window *w, int widget, int padding)
|
||||
NWidgetScrollbar::NWidgetScrollbar(WidgetType tp, Colours colour, int index) : NWidgetCore(tp, colour, 1, 1, 0x0, STR_NULL), Scrollbar(tp != NWID_HSCROLLBAR)
|
||||
{
|
||||
assert(tp == NWID_HSCROLLBAR || tp == NWID_VSCROLLBAR);
|
||||
this->sizing_type = NWST_STEP;
|
||||
this->SetIndex(index);
|
||||
}
|
||||
|
||||
@@ -2063,7 +2291,9 @@ void NWidgetScrollbar::Draw(const Window *w)
|
||||
if (vertical_dimension.width == 0) {
|
||||
vertical_dimension = maxdim(GetSpriteSize(SPR_ARROW_UP), GetSpriteSize(SPR_ARROW_DOWN));
|
||||
vertical_dimension.width += extra.width;
|
||||
vertical_dimension.width = GetMinSizing(NWST_STEP, vertical_dimension.width);
|
||||
vertical_dimension.height += extra.height;
|
||||
vertical_dimension.height = GetMinSizing(NWST_STEP, vertical_dimension.height);
|
||||
}
|
||||
return vertical_dimension;
|
||||
}
|
||||
@@ -2074,7 +2304,9 @@ void NWidgetScrollbar::Draw(const Window *w)
|
||||
if (horizontal_dimension.width == 0) {
|
||||
horizontal_dimension = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT));
|
||||
horizontal_dimension.width += extra.width;
|
||||
horizontal_dimension.width = GetMinSizing(NWST_STEP, horizontal_dimension.width);
|
||||
horizontal_dimension.height += extra.height;
|
||||
horizontal_dimension.height = GetMinSizing(NWST_STEP, horizontal_dimension.height);
|
||||
}
|
||||
return horizontal_dimension;
|
||||
}
|
||||
@@ -2112,12 +2344,46 @@ Dimension NWidgetLeaf::dropdown_dimension = {0, 0};
|
||||
*/
|
||||
NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip)
|
||||
{
|
||||
assert(this->sizing_type < NWST_END);
|
||||
assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_SHADEBOX || tp == WWT_DEFSIZEBOX || tp == WWT_DEBUGBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX);
|
||||
if (index >= 0) this->SetIndex(index);
|
||||
this->min_x = 0;
|
||||
this->min_y = 0;
|
||||
this->SetResize(0, 0);
|
||||
|
||||
if (this->sizing_type == NWST_NONE) {
|
||||
switch (tp) {
|
||||
case WWT_PUSHBTN:
|
||||
case WWT_IMGBTN:
|
||||
case WWT_PUSHIMGBTN:
|
||||
case WWT_IMGBTN_2:
|
||||
case WWT_TEXTBTN:
|
||||
case WWT_PUSHTXTBTN:
|
||||
case WWT_TEXTBTN_2:
|
||||
case WWT_PUSHARROWBTN:
|
||||
case WWT_EDITBOX:
|
||||
case WWT_CAPTION:
|
||||
case WWT_STICKYBOX:
|
||||
case WWT_SHADEBOX:
|
||||
case WWT_DEBUGBOX:
|
||||
case WWT_DEFSIZEBOX:
|
||||
case WWT_RESIZEBOX:
|
||||
case WWT_CLOSEBOX:
|
||||
this->sizing_type = NWST_BUTTON;
|
||||
this->SetMinimalSize(8, 8);
|
||||
break;
|
||||
case NWID_PUSHBUTTON_DROPDOWN:
|
||||
case NWID_BUTTON_DROPDOWN:
|
||||
case WWT_DROPDOWN:
|
||||
case WWT_ARROWBTN:
|
||||
this->sizing_type = NWST_STEP;
|
||||
this->SetMinimalSize(8, 8);
|
||||
break;
|
||||
default:
|
||||
this->sizing_type = NWST_OVERRIDE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tp) {
|
||||
case WWT_EMPTY:
|
||||
break;
|
||||
@@ -2146,7 +2412,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data,
|
||||
case WWT_CAPTION:
|
||||
this->SetFill(1, 0);
|
||||
this->SetResize(1, 0);
|
||||
this->min_y = WD_CAPTION_HEIGHT;
|
||||
//this->min_y = WD_CAPTION_HEIGHT;
|
||||
this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
|
||||
break;
|
||||
|
||||
@@ -2188,7 +2454,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data,
|
||||
|
||||
case WWT_DROPDOWN:
|
||||
this->SetFill(0, 0);
|
||||
this->min_y = WD_DROPDOWN_HEIGHT;
|
||||
//this->min_y = WD_DROPDOWN_HEIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2208,7 +2474,20 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
|
||||
Dimension resize = {this->resize_x, this->resize_y};
|
||||
/* Get padding, and update size with the real content size if appropriate. */
|
||||
const Dimension *padding = NULL;
|
||||
switch (this->type) {
|
||||
if (!_settings_client.gui.windows_titlebars && w->window_class != WC_NEWS_WINDOW &&
|
||||
(this->type == WWT_CAPTION || this->type == WWT_STICKYBOX || this->type == WWT_SHADEBOX ||
|
||||
this->type == WWT_DEFSIZEBOX || this->type == WWT_CLOSEBOX || this->type == WWT_DEBUGBOX)) {
|
||||
static const Dimension extra = {0, 0};
|
||||
padding = &extra;
|
||||
this->sizing_type = NWST_OVERRIDE;
|
||||
size = extra;
|
||||
fill = extra;
|
||||
resize = extra;
|
||||
if (this->type == WWT_CAPTION) {
|
||||
fill.width = 1;
|
||||
resize.width = 1;
|
||||
}
|
||||
} else switch (this->type) {
|
||||
case WWT_EMPTY: {
|
||||
static const Dimension extra = {0, 0};
|
||||
padding = &extra;
|
||||
@@ -2287,6 +2566,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
|
||||
Dimension sprite_size = GetSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
|
||||
size.width = max(size.width, 30 + sprite_size.width);
|
||||
size.height = max(sprite_size.height, GetStringBoundingBox("_").height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM);
|
||||
size.height = GetMinSizing(NWST_BUTTON, size.height);
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case WWT_PUSHBTN: {
|
||||
@@ -2353,7 +2633,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
|
||||
padding = &extra;
|
||||
if (this->index >= 0) w->SetStringParameters(this->index);
|
||||
Dimension d2 = GetStringBoundingBox(this->widget_data);
|
||||
d2.width += extra.width;
|
||||
d2.width += extra.width + GetMinSizing(NWST_STEP, 11U);
|
||||
d2.height += extra.height;
|
||||
size = maxdim(size, d2);
|
||||
break;
|
||||
@@ -2365,7 +2645,8 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
|
||||
padding = &extra;
|
||||
if (NWidgetLeaf::dropdown_dimension.width == 0) {
|
||||
NWidgetLeaf::dropdown_dimension = GetSpriteSize(SPR_ARROW_DOWN);
|
||||
NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT;
|
||||
NWidgetLeaf::dropdown_dimension.width = SETTING_BUTTON_HEIGHT;
|
||||
//NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT;
|
||||
NWidgetLeaf::dropdown_dimension.height += WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM;
|
||||
extra.width = WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT + NWidgetLeaf::dropdown_dimension.width;
|
||||
}
|
||||
@@ -2470,26 +2751,28 @@ void NWidgetLeaf::Draw(const Window *w)
|
||||
|
||||
case WWT_CAPTION:
|
||||
if (this->index >= 0) w->SetStringParameters(this->index);
|
||||
DrawCaption(r, this->colour, w->owner, this->widget_data);
|
||||
DrawCaption(r, this->colour, w->owner, this->widget_data, this, w);
|
||||
break;
|
||||
|
||||
case WWT_SHADEBOX:
|
||||
assert(this->widget_data == 0);
|
||||
DrawShadeBox(r, this->colour, w->IsShaded());
|
||||
DrawImageButtons(r, WWT_SHADEBOX, this->colour, w->IsShaded(), w->IsShaded() ? SPR_WINDOW_SHADE : SPR_WINDOW_UNSHADE);
|
||||
break;
|
||||
|
||||
case WWT_DEBUGBOX:
|
||||
DrawDebugBox(r, this->colour, clicked);
|
||||
DrawImageButtons(r, WWT_DEBUGBOX, this->colour, clicked, SPR_WINDOW_DEBUG);
|
||||
break;
|
||||
|
||||
case WWT_STICKYBOX:
|
||||
case WWT_STICKYBOX: {
|
||||
assert(this->widget_data == 0);
|
||||
DrawStickyBox(r, this->colour, !!(w->flags & WF_STICKY));
|
||||
bool clicked = !!(w->flags & WF_STICKY);
|
||||
DrawImageButtons(r, WWT_STICKYBOX, this->colour, clicked, clicked ? SPR_PIN_DOWN : SPR_PIN_UP);
|
||||
break;
|
||||
}
|
||||
|
||||
case WWT_DEFSIZEBOX:
|
||||
assert(this->widget_data == 0);
|
||||
DrawDefSizeBox(r, this->colour, clicked);
|
||||
DrawImageButtons(r, WWT_DEFSIZEBOX, this->colour, clicked, SPR_WINDOW_DEFSIZE);
|
||||
break;
|
||||
|
||||
case WWT_RESIZEBOX:
|
||||
@@ -2533,11 +2816,12 @@ void NWidgetLeaf::Draw(const Window *w)
|
||||
*/
|
||||
bool NWidgetLeaf::ButtonHit(const Point &pt)
|
||||
{
|
||||
uint button_size = GetMinSizing(NWST_STEP, 12);
|
||||
if (_current_text_dir == TD_LTR) {
|
||||
int button_width = this->pos_x + this->current_x - NWidgetLeaf::dropdown_dimension.width;
|
||||
int button_width = this->pos_x + this->current_x - button_size;
|
||||
return pt.x < button_width;
|
||||
} else {
|
||||
int button_left = this->pos_x + NWidgetLeaf::dropdown_dimension.width;
|
||||
int button_left = this->pos_x + button_size;
|
||||
return pt.x >= button_left;
|
||||
}
|
||||
}
|
||||
@@ -2630,6 +2914,16 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest,
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_SIZINGTYPE: {
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
|
||||
if (nwrb != NULL) {
|
||||
assert(parts->u.sizing_type < NWST_END);
|
||||
nwrb->sizing_type = parts->u.sizing_type;
|
||||
nwrb->SetMinimalSize(0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_MINSIZE: {
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
|
||||
if (nwrb != NULL) {
|
||||
@@ -2886,6 +3180,7 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid
|
||||
}
|
||||
|
||||
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, widnum);
|
||||
panel->sizing_type = NWST_STEP;
|
||||
panel->SetMinimalSize(sprite_size.width, sprite_size.height);
|
||||
panel->SetFill(1, 1);
|
||||
panel->SetResize(1, 0);
|
||||
@@ -2906,3 +3201,35 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid
|
||||
if (hor != NULL) vert->Add(hor);
|
||||
return vert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimal automatic size for a widget.
|
||||
* @param type The automatic sizing type to use.
|
||||
* @param min_1 Minimal passed value.
|
||||
* @return At least the passed value, or the minimal size for the associated sizing type.
|
||||
*/
|
||||
uint GetMinSizing(NWidSizingType type, uint min_1)
|
||||
{
|
||||
uint min_sizing;
|
||||
switch (type) {
|
||||
case NWST_NONE:
|
||||
case NWST_OVERRIDE:
|
||||
return min_1;
|
||||
case NWST_BUTTON:
|
||||
min_sizing = _settings_client.gui.min_button;
|
||||
break;
|
||||
case NWST_STEP:
|
||||
min_sizing = _settings_client.gui.min_step;
|
||||
break;
|
||||
case NWST_KEYBOARD:
|
||||
min_sizing = 2 * _settings_client.gui.min_button;
|
||||
break;
|
||||
case NWST_WINDOW_LENGTH:
|
||||
min_sizing = 8 * _settings_client.gui.min_button;
|
||||
break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
min_sizing = RescaleFrom854x480(min_sizing);
|
||||
|
||||
return max(min_sizing, min_1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user