1
0
Fork 0

(svn r13055) -Codechange: make a class of SmallMapWindow.

release/0.7
glx 2008-05-11 19:47:10 +00:00
parent 526d5de867
commit ad19bf105a
2 changed files with 481 additions and 498 deletions

View File

@ -32,13 +32,6 @@
#include "table/strings.h"
#include "table/sprites.h"
struct smallmap_d {
int32 scroll_x;
int32 scroll_y;
int32 subscroll;
};
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d));
static const Widget _smallmap_widgets[] = {
{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
{ WWT_CAPTION, RESIZE_RIGHT, 13, 11, 337, 0, 13, STR_00B0_MAP, STR_018C_WINDOW_TITLE_DRAG_THIS},
@ -561,6 +554,8 @@ enum SmallMapWindowWidgets {
SM_WIDGET_RESIZEBOX,
};
class SmallMapWindow : public Window
{
enum SmallMapType {
SMT_CONTOUR,
SMT_VEHICLES,
@ -568,6 +563,15 @@ enum SmallMapType {
SMT_OWNER = 5,
};
enum {
BASE_NB_PER_COLUMN = 6,
};
int32 scroll_x;
int32 scroll_y;
int32 subscroll;
public:
/**
* Draws the small map.
*
@ -582,7 +586,7 @@ enum SmallMapType {
* @param type type of map requested (vegetation, owners, routes, etc)
* @param show_towns true if the town names should be displayed, false if not.
*/
static void DrawSmallMap(DrawPixelInfo *dpi, Window *w, int type, bool show_towns)
void DrawSmallMap(DrawPixelInfo *dpi, int type, bool show_towns)
{
Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
DrawPixelInfo *old_dpi;
@ -617,10 +621,10 @@ static void DrawSmallMap(DrawPixelInfo *dpi, Window *w, int type, bool show_town
}
}
tile_x = WP(w, smallmap_d).scroll_x / TILE_SIZE;
tile_y = WP(w, smallmap_d).scroll_y / TILE_SIZE;
tile_x = this->scroll_x / TILE_SIZE;
tile_y = this->scroll_y / TILE_SIZE;
dx = dpi->left + WP(w, smallmap_d).subscroll;
dx = dpi->left + this->subscroll;
tile_x -= dx / 4;
tile_y += dx / 4;
dx &= 3;
@ -694,8 +698,8 @@ skip_column:
(v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0) {
/* Remap into flat coordinates. */
Point pt = RemapCoords(
v->x_pos / TILE_SIZE - WP(w, smallmap_d).scroll_x / TILE_SIZE, // divide each one separately because (a-b)/c != a/c-b/c in integer world
v->y_pos / TILE_SIZE - WP(w, smallmap_d).scroll_y / TILE_SIZE, // dtto
v->x_pos / TILE_SIZE - this->scroll_x / TILE_SIZE, // divide each one separately because (a-b)/c != a/c-b/c in integer world
v->y_pos / TILE_SIZE - this->scroll_y / TILE_SIZE, // dtto
0);
x = pt.x;
y = pt.y;
@ -708,7 +712,7 @@ skip_column:
skip = false;
/* Offset X coordinate */
x -= WP(w, smallmap_d).subscroll + 3 + dpi->left;
x -= this->subscroll + 3 + dpi->left;
if (x < 0) {
/* if x+1 is 0, that means we're on the very left edge,
@ -737,10 +741,10 @@ skip_column:
FOR_ALL_TOWNS(t) {
/* Remap the town coordinate */
Point pt = RemapCoords(
(int)(TileX(t->xy) * TILE_SIZE - WP(w, smallmap_d).scroll_x) / TILE_SIZE,
(int)(TileY(t->xy) * TILE_SIZE - WP(w, smallmap_d).scroll_y) / TILE_SIZE,
(int)(TileX(t->xy) * TILE_SIZE - this->scroll_x) / TILE_SIZE,
(int)(TileY(t->xy) * TILE_SIZE - this->scroll_y) / TILE_SIZE,
0);
x = pt.x - WP(w, smallmap_d).subscroll + 3 - (t->sign.width_2 >> 1);
x = pt.x - this->subscroll + 3 - (t->sign.width_2 >> 1);
y = pt.y;
/* Check if the town sign is within bounds */
@ -762,7 +766,7 @@ skip_column:
/* Find main viewport. */
vp = FindWindowById(WC_MAIN_WINDOW,0)->viewport;
pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w, smallmap_d).scroll_y, 0);
pt = RemapCoords(this->scroll_x, this->scroll_y, 0);
x = vp->virtual_left - pt.x;
y = vp->virtual_top - pt.y;
@ -771,8 +775,8 @@ skip_column:
x /= TILE_SIZE;
y /= TILE_SIZE;
x -= WP(w, smallmap_d).subscroll;
x2 -= WP(w, smallmap_d).subscroll;
x -= this->subscroll;
x2 -= this->subscroll;
DrawVertMapIndicator(x, y, x, y2);
DrawVertMapIndicator(x2, y, x2, y2);
@ -783,39 +787,67 @@ skip_column:
_cur_dpi = old_dpi;
}
void SmallMapCenterOnCurrentPos(Window *w)
void SmallMapCenterOnCurrentPos()
{
int x, y;
ViewPort *vp;
vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
x = ((vp->virtual_width - (w->widget[SM_WIDGET_MAP].right - w->widget[SM_WIDGET_MAP].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4;
y = ((vp->virtual_height - (w->widget[SM_WIDGET_MAP].bottom - w->widget[SM_WIDGET_MAP].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2;
WP(w, smallmap_d).scroll_x = (y - x) & ~0xF;
WP(w, smallmap_d).scroll_y = (x + y) & ~0xF;
w->SetDirty();
x = ((vp->virtual_width - (this->widget[SM_WIDGET_MAP].right - this->widget[SM_WIDGET_MAP].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4;
y = ((vp->virtual_height - (this->widget[SM_WIDGET_MAP].bottom - this->widget[SM_WIDGET_MAP].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2;
this->scroll_x = (y - x) & ~0xF;
this->scroll_y = (x + y) & ~0xF;
this->SetDirty();
}
enum {
BASE_NB_PER_COLUMN = 6,
};
static void SmallMapWindowProc(Window *w, WindowEvent *e)
SmallMapWindow(const WindowDesc *desc, void *data, int window_number) : Window(desc, data, window_number)
{
/* Resize the window to fit industries list */
if (_industries_per_column > BASE_NB_PER_COLUMN) {
uint diff = ((_industries_per_column - BASE_NB_PER_COLUMN) * BASE_NB_PER_COLUMN) + 1;
this->height = this->height + diff;
Widget *wi = &this->widget[SM_WIDGET_LEGEND]; // label panel
wi->bottom = wi->bottom + diff;
wi = &this->widget[SM_WIDGET_BUTTONSPANEL]; // filler panel under smallmap buttons
wi->bottom = wi->bottom + diff - 1;
/* Change widget position
* - footer panel
* - enable all industry
* - disable all industry
* - resize window button
*/
for (uint i = SM_WIDGET_BOTTOMPANEL; i <= SM_WIDGET_RESIZEBOX; i++) {
wi = &this->widget[i];
wi->top = wi->top + diff;
wi->bottom = wi->bottom + diff;
}
}
this->LowerWidget(_smallmap_type + SMT_OWNER);
this->SetWidgetLoweredState(SM_WIDGET_TOGGLETOWNNAME, _smallmap_show_towns);
this->SmallMapCenterOnCurrentPos();
this->FindWindowPlacementAndResize(desc);
}
virtual void OnPaint()
{
switch (e->event) {
case WE_PAINT: {
const LegendAndColour *tbl;
int x, y, y_org;
uint diff;
DrawPixelInfo new_dpi;
/* Hide Enable all/Disable all buttons if is not industry type small map*/
w->SetWidgetHiddenState(SM_WIDGET_ENABLEINDUSTRIES, _smallmap_type != SMT_INDUSTRY);
w->SetWidgetHiddenState(SM_WIDGET_DISABLEINDUSTRIES, _smallmap_type != SMT_INDUSTRY);
this->SetWidgetHiddenState(SM_WIDGET_ENABLEINDUSTRIES, _smallmap_type != SMT_INDUSTRY);
this->SetWidgetHiddenState(SM_WIDGET_DISABLEINDUSTRIES, _smallmap_type != SMT_INDUSTRY);
/* draw the window */
SetDParam(0, STR_00E5_CONTOURS + _smallmap_type);
DrawWindowWidgets(w);
DrawWindowWidgets(this);
tbl = _legend_table[_smallmap_type];
@ -823,11 +855,10 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
diff = (_industries_per_column > BASE_NB_PER_COLUMN) ? ((_industries_per_column - BASE_NB_PER_COLUMN) * BASE_NB_PER_COLUMN) + 1 : 0;
x = 4;
y_org = w->height - 44 - 11 - diff;
y_org = this->height - 44 - 11 - diff;
y = y_org;
for (;;) {
if (_smallmap_type == SMT_INDUSTRY) {
/* Industry name must be formated, since it's not in tiny font in the specs.
* So, draw with a parameter and use the STR_SMALLMAP_INDUSTRY string, which is tiny font.*/
@ -861,18 +892,15 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
}
}
if (!FillDrawPixelInfo(&new_dpi, 3, 17, w->width - 28 + 22, w->height - 64 - 11 - diff))
return;
if (!FillDrawPixelInfo(&new_dpi, 3, 17, this->width - 28 + 22, this->height - 64 - 11 - diff)) return;
DrawSmallMap(&new_dpi, w, _smallmap_type, _smallmap_show_towns);
} break;
this->DrawSmallMap(&new_dpi, _smallmap_type, _smallmap_show_towns);
}
case WE_CLICK:
switch (e->we.click.widget) {
virtual void OnClick(Point pt, int widget)
{
switch (widget) {
case SM_WIDGET_MAP: { // Map window
Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
Point pt;
/*
* XXX: scrolling with the left mouse button is done by subsequently
* clicking with the left mouse button; clicking once centers the
@ -883,11 +911,12 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
*/
_left_button_clicked = false;
pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w,smallmap_d).scroll_y, 0);
w2->viewport->dest_scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1);
w2->viewport->dest_scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1);
Point pt = RemapCoords(this->scroll_x, this->scroll_y, 0);
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
w->viewport->dest_scrollpos_x = pt.x + ((_cursor.pos.x - this->left + 2) << 4) - (w->viewport->virtual_width >> 1);
w->viewport->dest_scrollpos_y = pt.y + ((_cursor.pos.y - this->top - 16) << 4) - (w->viewport->virtual_height >> 1);
w->SetDirty();
this->SetDirty();
} break;
case SM_WIDGET_CONTOUR: // Show land contours
@ -896,26 +925,26 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
case SM_WIDGET_ROUTES: // Show transport routes
case SM_WIDGET_VEGETATION: // Show vegetation
case SM_WIDGET_OWNERS: // Show land owners
w->RaiseWidget(_smallmap_type + SM_WIDGET_CONTOUR);
_smallmap_type = e->we.click.widget - SM_WIDGET_CONTOUR;
w->LowerWidget(_smallmap_type + SM_WIDGET_CONTOUR);
this->RaiseWidget(_smallmap_type + SM_WIDGET_CONTOUR);
_smallmap_type = widget - SM_WIDGET_CONTOUR;
this->LowerWidget(_smallmap_type + SM_WIDGET_CONTOUR);
w->SetDirty();
this->SetDirty();
SndPlayFx(SND_15_BEEP);
break;
case SM_WIDGET_CENTERMAP: // Center the smallmap again
SmallMapCenterOnCurrentPos(w);
this->SmallMapCenterOnCurrentPos();
w->SetDirty();
this->SetDirty();
SndPlayFx(SND_15_BEEP);
break;
case SM_WIDGET_TOGGLETOWNNAME: // Toggle town names
w->ToggleWidgetLoweredState(SM_WIDGET_TOGGLETOWNNAME);
_smallmap_show_towns = w->IsWidgetLowered(SM_WIDGET_TOGGLETOWNNAME);
this->ToggleWidgetLoweredState(SM_WIDGET_TOGGLETOWNNAME);
_smallmap_show_towns = this->IsWidgetLowered(SM_WIDGET_TOGGLETOWNNAME);
w->SetDirty();
this->SetDirty();
SndPlayFx(SND_15_BEEP);
break;
@ -923,9 +952,9 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
/* if industry type small map*/
if (_smallmap_type == SMT_INDUSTRY) {
/* if click on industries label, find right industry type and enable/disable it */
Widget *wi = &w->widget[SM_WIDGET_LEGEND]; // label panel
uint column = (e->we.click.pt.x - 4) / 123;
uint line = (e->we.click.pt.y - wi->top - 2) / 6;
Widget *wi = &this->widget[SM_WIDGET_LEGEND]; // label panel
uint column = (pt.x - 4) / 123;
uint line = (pt.y - wi->top - 2) / 6;
uint free = _smallmap_industry_count % 3;
if (column <= 3) {
@ -945,9 +974,9 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
}
}
/* Raise the two buttons "all", as we have done a specific choice */
w->RaiseWidget(SM_WIDGET_ENABLEINDUSTRIES);
w->RaiseWidget(SM_WIDGET_DISABLEINDUSTRIES);
w->SetDirty();
this->RaiseWidget(SM_WIDGET_ENABLEINDUSTRIES);
this->RaiseWidget(SM_WIDGET_DISABLEINDUSTRIES);
this->SetDirty();
}
break;
@ -956,9 +985,9 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
_legend_from_industries[i].show_on_map = true;
}
/* toggle appeareance indicating the choice */
w->LowerWidget(SM_WIDGET_ENABLEINDUSTRIES);
w->RaiseWidget(SM_WIDGET_DISABLEINDUSTRIES);
w->SetDirty();
this->LowerWidget(SM_WIDGET_ENABLEINDUSTRIES);
this->RaiseWidget(SM_WIDGET_DISABLEINDUSTRIES);
this->SetDirty();
break;
case SM_WIDGET_DISABLEINDUSTRIES: // disable all industries
@ -966,51 +995,46 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
_legend_from_industries[i].show_on_map = false;
}
/* toggle appeareance indicating the choice */
w->RaiseWidget(SM_WIDGET_ENABLEINDUSTRIES);
w->LowerWidget(SM_WIDGET_DISABLEINDUSTRIES);
w->SetDirty();
this->RaiseWidget(SM_WIDGET_ENABLEINDUSTRIES);
this->LowerWidget(SM_WIDGET_DISABLEINDUSTRIES);
this->SetDirty();
break;
}
break;
}
case WE_RCLICK:
if (e->we.click.widget == SM_WIDGET_MAP) {
virtual void OnRightClick(Point pt, int widget)
{
if (widget == SM_WIDGET_MAP) {
if (_scrolling_viewport) return;
_scrolling_viewport = true;
_cursor.delta.x = 0;
_cursor.delta.y = 0;
}
break;
}
case WE_TICK:
virtual void OnTick()
{
/* update the window every now and then */
if ((++w->vscroll.pos & 0x1F) == 0) w->SetDirty();
break;
case WE_SCROLL: {
int x;
int y;
int sub;
int hx;
int hy;
int hvx;
int hvy;
if ((++this->vscroll.pos & 0x1F) == 0) this->SetDirty();
}
virtual void OnScroll(Point delta)
{
_cursor.fix_at = true;
x = WP(w, smallmap_d).scroll_x;
y = WP(w, smallmap_d).scroll_y;
int x = this->scroll_x;
int y = this->scroll_y;
sub = WP(w, smallmap_d).subscroll + e->we.scroll.delta.x;
int sub = this->subscroll + delta.x;
x -= (sub >> 2) << 4;
y += (sub >> 2) << 4;
sub &= 3;
x += (e->we.scroll.delta.y >> 1) << 4;
y += (e->we.scroll.delta.y >> 1) << 4;
x += (delta.y >> 1) << 4;
y += (delta.y >> 1) << 4;
if (e->we.scroll.delta.y & 1) {
if (delta.y & 1) {
x += TILE_SIZE;
sub += 2;
if (sub > 3) {
@ -1020,10 +1044,10 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
}
}
hx = (w->widget[SM_WIDGET_MAP].right - w->widget[SM_WIDGET_MAP].left) / 2;
hy = (w->widget[SM_WIDGET_MAP].bottom - w->widget[SM_WIDGET_MAP].top ) / 2;
hvx = hx * -4 + hy * 8;
hvy = hx * 4 + hy * 8;
int hx = (this->widget[SM_WIDGET_MAP].right - this->widget[SM_WIDGET_MAP].left) / 2;
int hy = (this->widget[SM_WIDGET_MAP].bottom - this->widget[SM_WIDGET_MAP].top ) / 2;
int hvx = hx * -4 + hy * 8;
int hvy = hx * 4 + hy * 8;
if (x < -hvx) {
x = -hvx;
sub = 0;
@ -1041,59 +1065,25 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e)
sub = 0;
}
WP(w, smallmap_d).scroll_x = x;
WP(w, smallmap_d).scroll_y = y;
WP(w, smallmap_d).subscroll = sub;
this->scroll_x = x;
this->scroll_y = y;
this->subscroll = sub;
w->SetDirty();
} break;
}
this->SetDirty();
}
};
static const WindowDesc _smallmap_desc = {
WDP_AUTO, WDP_AUTO, 350, 214, 446, 314,
WC_SMALLMAP, WC_NONE,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
_smallmap_widgets,
SmallMapWindowProc
NULL
};
void ShowSmallMap()
{
Window *w;
w = AllocateWindowDescFront<Window>(&_smallmap_desc, 0);
if (w == NULL) return;
/* Resize the window to fit industries list */
if (_industries_per_column > BASE_NB_PER_COLUMN) {
uint diff = ((_industries_per_column - BASE_NB_PER_COLUMN) * BASE_NB_PER_COLUMN) + 1;
w->height = w->height + diff;
Widget *wi = &w->widget[SM_WIDGET_LEGEND]; // label panel
wi->bottom = wi->bottom + diff;
wi = &w->widget[SM_WIDGET_BUTTONSPANEL]; // filler panel under smallmap buttons
wi->bottom = wi->bottom + diff - 1;
/* Change widget position
* - footer panel
* - enable all industry
* - disable all industry
* - resize window button
*/
for (uint i = SM_WIDGET_BOTTOMPANEL; i <= SM_WIDGET_RESIZEBOX; i++) {
wi = &w->widget[i];
wi->top = wi->top + diff;
wi->bottom = wi->bottom + diff;
}
}
w->LowerWidget(_smallmap_type + SMT_OWNER);
w->SetWidgetLoweredState(SM_WIDGET_TOGGLETOWNNAME, _smallmap_show_towns);
SmallMapCenterOnCurrentPos(w);
AllocateWindowDescFront<SmallMapWindow>(&_smallmap_desc, 0);
}
/* Extra ViewPort Window Stuff */
@ -1225,3 +1215,19 @@ void ShowExtraViewPortWindow(TileIndex tile)
w->viewport->dest_scrollpos_y = w->viewport->scrollpos_y;
}
}
bool ScrollMainWindowTo(int x, int y, bool instant)
{
bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0), instant);
/* If a user scrolls to a tile (via what way what so ever) and already is on
* that tile (e.g.: pressed twice), move the smallmap to that location,
* so you directly see where you are on the smallmap. */
if (res) return res;
SmallMapWindow *w = dynamic_cast<SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
if (w != NULL) w->SmallMapCenterOnCurrentPos();
return res;
}

View File

@ -144,8 +144,6 @@ TileHighlightData _thd;
static TileInfo *_cur_ti;
bool _draw_bounding_boxes = false;
extern void SmallMapCenterOnCurrentPos(Window *w);
static Point MapXYZToViewport(const ViewPort *vp, uint x, uint y, uint z)
{
Point p = RemapCoords(x, y, z);
@ -2079,27 +2077,6 @@ bool ScrollWindowTo(int x , int y, Window *w, bool instant)
return true;
}
bool ScrollMainWindowTo(int x, int y, bool instant)
{
Window *w;
bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0), instant);
/* If a user scrolls to a tile (via what way what so ever) and already is on
* that tile (e.g.: pressed twice), move the smallmap to that location,
* so you directly see where you are on the smallmap. */
if (res) return res;
w = FindWindowById(WC_SMALLMAP, 0);
if (w == NULL) return res;
SmallMapCenterOnCurrentPos(w);
return res;
}
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
{
return ScrollMainWindowTo(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2, instant);