src/signs_gui.cpp
changeset 10499 9c2d9bdea61a
parent 10462 416b62f5ee6f
child 10595 7957c71b0dfe
equal deleted inserted replaced
10498:f198d0a1aab7 10499:9c2d9bdea61a
    17 #include "core/alloc_func.hpp"
    17 #include "core/alloc_func.hpp"
    18 #include "window_func.h"
    18 #include "window_func.h"
    19 #include "map_func.h"
    19 #include "map_func.h"
    20 #include "gfx_func.h"
    20 #include "gfx_func.h"
    21 #include "viewport_func.h"
    21 #include "viewport_func.h"
       
    22 #include "querystring_gui.h"
    22 
    23 
    23 #include "table/strings.h"
    24 #include "table/strings.h"
    24 #include "table/sprites.h"
    25 #include "table/sprites.h"
    25 
    26 
    26 static const Sign **_sign_sort;
    27 static const Sign **_sign_sort;
   141 		w->resize.step_height = 10;
   142 		w->resize.step_height = 10;
   142 		w->resize.height = w->height - 10 * 7; // minimum if 5 in the list
   143 		w->resize.height = w->height - 10 * 7; // minimum if 5 in the list
   143 	}
   144 	}
   144 }
   145 }
   145 
   146 
   146 /** Edit sign window stuff */
   147 static void RenameSign(SignID index, const char *text)
   147 struct editsign_d : querystr_d {
   148 {
   148 	SignID cur_sign;
   149 	_cmd_text = text;
   149 };
   150 	DoCommandP(0, index, 0, NULL, CMD_RENAME_SIGN | CMD_MSG(STR_280C_CAN_T_CHANGE_SIGN_NAME));
   150 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(editsign_d));
   151 }
   151 
   152 
   152 enum QueryEditSignWidgets {
   153 enum QueryEditSignWidgets {
   153 	QUERY_EDIT_SIGN_WIDGET_TEXT = 3,
   154 	QUERY_EDIT_SIGN_WIDGET_TEXT = 3,
   154 	QUERY_EDIT_SIGN_WIDGET_OK,
   155 	QUERY_EDIT_SIGN_WIDGET_OK,
   155 	QUERY_EDIT_SIGN_WIDGET_CANCEL,
   156 	QUERY_EDIT_SIGN_WIDGET_CANCEL,
   156 	QUERY_EDIT_SIGN_WIDGET_DELETE,
   157 	QUERY_EDIT_SIGN_WIDGET_DELETE,
   157 	QUERY_EDIT_SIGN_WIDGET_PREVIOUS = QUERY_EDIT_SIGN_WIDGET_DELETE + 2,
   158 	QUERY_EDIT_SIGN_WIDGET_PREVIOUS = QUERY_EDIT_SIGN_WIDGET_DELETE + 2,
   158 	QUERY_EDIT_SIGN_WIDGET_NEXT,
   159 	QUERY_EDIT_SIGN_WIDGET_NEXT,
   159 };
   160 };
   160 
   161 
   161 static void UpdateSignEditWindow(Window *w, const Sign *si)
   162 struct SignWindow : QueryStringBaseWindow {
   162 {
   163 	SignID cur_sign;
   163 	/* Display an empty string when the sign hasnt been edited yet */
   164 
   164 	if (si->name != NULL) {
   165 	SignWindow(const WindowDesc *desc, const Sign *si) : QueryStringBaseWindow(desc)
   165 		SetDParam(0, si->index);
   166 	{
   166 		GetString(_edit_str_buf, STR_SIGN_NAME, lastof(_edit_str_buf));
   167 		SetBit(_no_scroll, SCROLL_EDIT);
   167 	} else {
   168 		this->caption = STR_280B_EDIT_SIGN_TEXT;
   168 		GetString(_edit_str_buf, STR_EMPTY, lastof(_edit_str_buf));
   169 		this->afilter = CS_ALPHANUMERAL;
   169 	}
   170 		this->LowerWidget(QUERY_EDIT_SIGN_WIDGET_TEXT);
   170 	_edit_str_buf[lengthof(_edit_str_buf) - 1] = '\0';
   171 
   171 
   172 		UpdateSignEditWindow(si);
   172 	WP(w, editsign_d).cur_sign = si->index;
   173 	}
   173 	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, 31, 255); // Allow 31 characters (including \0)
   174 
   174 
   175 	~SignWindow()
   175 	w->InvalidateWidget(QUERY_EDIT_SIGN_WIDGET_TEXT);
   176 	{
   176 }
   177 		ClrBit(_no_scroll, SCROLL_EDIT);
   177 
   178 	}
   178 static void RenameSign(SignID index, const char *text)
   179 
   179 {
   180 	void UpdateSignEditWindow(const Sign *si)
   180 	_cmd_text = text;
   181 	{
   181 	DoCommandP(0, index, 0, NULL, CMD_RENAME_SIGN | CMD_MSG(STR_280C_CAN_T_CHANGE_SIGN_NAME));
   182 		/* Display an empty string when the sign hasnt been edited yet */
   182 }
   183 		if (si->name != NULL) {
   183 
   184 			SetDParam(0, si->index);
   184 static void QuerySignEditWndProc(Window *w, WindowEvent *e)
   185 			GetString(this->edit_str_buf, STR_SIGN_NAME, lastof(this->edit_str_buf));
   185 {
   186 		} else {
   186 	editsign_d *qs = &WP(w, editsign_d);
   187 			GetString(this->edit_str_buf, STR_EMPTY, lastof(this->edit_str_buf));
   187 	Sign       *si;
   188 		}
   188 	uint       sign_index = 0;
   189 		this->edit_str_buf[lengthof(this->edit_str_buf) - 1] = '\0';
   189 
   190 
   190 	switch (e->event) {
   191 		this->cur_sign = si->index;
   191 		case WE_CREATE:
   192 		InitializeTextBuffer(&this->text, this->edit_str_buf, 31, 255); // Allow 31 characters (including \0)
   192 			SetBit(_no_scroll, SCROLL_EDIT);
   193 
   193 			break;
   194 		this->InvalidateWidget(QUERY_EDIT_SIGN_WIDGET_TEXT);
   194 
   195 	}
   195 		case WE_PAINT:
   196 
   196 			SetDParam(0, qs->caption);
   197 	virtual void OnPaint()
   197 			DrawWindowWidgets(w);
   198 	{
   198 			DrawEditBox(w, qs, QUERY_EDIT_SIGN_WIDGET_TEXT);
   199 		SetDParam(0, this->caption);
   199 			break;
   200 		DrawWindowWidgets(this);
   200 
   201 		this->DrawEditBox(QUERY_EDIT_SIGN_WIDGET_TEXT);
   201 		case WE_CLICK:
   202 	}
   202 			switch (e->we.click.widget) {
   203 
   203 				case QUERY_EDIT_SIGN_WIDGET_PREVIOUS:
   204 	virtual void OnClick(Point pt, int widget)
   204 					if (_sign_sort_dirty) GlobalSortSignList();
   205 	{
   205 					sign_index = _sign_sort[_num_sign_sort - 1]->index;
   206 		switch (widget) {
   206 					for (uint i = 1; i < _num_sign_sort; i++) {
   207 			case QUERY_EDIT_SIGN_WIDGET_PREVIOUS: {
   207 						if (qs->cur_sign == _sign_sort[i]->index) {
   208 				if (_sign_sort_dirty) GlobalSortSignList();
   208 							sign_index = _sign_sort[i - 1]->index;
   209 				SignID sign_index = _sign_sort[_num_sign_sort - 1]->index;
   209 							break;
   210 				for (uint i = 1; i < _num_sign_sort; i++) {
   210 						}
   211 					if (this->cur_sign == _sign_sort[i]->index) {
       
   212 						sign_index = _sign_sort[i - 1]->index;
       
   213 						break;
   211 					}
   214 					}
   212 					si = GetSign(sign_index);
   215 				}
   213 
   216 				const Sign *si = GetSign(sign_index);
   214 					/* Scroll to sign and reopen window */
   217 
   215 					ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
   218 				/* Scroll to sign and reopen window */
   216 					UpdateSignEditWindow(w, si);
   219 				ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
   217 					break;
   220 				UpdateSignEditWindow(si);
   218 
   221 			} break;
   219 				case QUERY_EDIT_SIGN_WIDGET_NEXT:
   222 
   220 					if (_sign_sort_dirty) GlobalSortSignList();
   223 			case QUERY_EDIT_SIGN_WIDGET_NEXT: {
   221 					sign_index = _sign_sort[0]->index;
   224 				if (_sign_sort_dirty) GlobalSortSignList();
   222 					for (uint i = 0; i < _num_sign_sort - 1; i++) {
   225 				SignID sign_index = _sign_sort[0]->index;
   223 						if (qs->cur_sign == _sign_sort[i]->index) {
   226 				for (uint i = 0; i < _num_sign_sort - 1; i++) {
   224 							sign_index = _sign_sort[i + 1]->index;
   227 					if (this->cur_sign == _sign_sort[i]->index) {
   225 							break;
   228 						sign_index = _sign_sort[i + 1]->index;
   226 						}
   229 						break;
   227 					}
   230 					}
   228 					si = GetSign(sign_index);
   231 				}
   229 
   232 				const Sign *si = GetSign(sign_index);
   230 					/* Scroll to sign and reopen window */
   233 
   231 					ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
   234 				/* Scroll to sign and reopen window */
   232 					UpdateSignEditWindow(w, si);
   235 				ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
   233 					break;
   236 				UpdateSignEditWindow(si);
   234 
   237 			} break;
   235 				case QUERY_EDIT_SIGN_WIDGET_TEXT:
   238 
   236 					ShowOnScreenKeyboard(w, qs, e->we.click.widget, QUERY_EDIT_SIGN_WIDGET_CANCEL, QUERY_EDIT_SIGN_WIDGET_OK);
   239 			case QUERY_EDIT_SIGN_WIDGET_TEXT:
   237 					break;
   240 				ShowOnScreenKeyboard(this, widget, QUERY_EDIT_SIGN_WIDGET_CANCEL, QUERY_EDIT_SIGN_WIDGET_OK);
   238 
   241 				break;
   239 				case QUERY_EDIT_SIGN_WIDGET_DELETE:
   242 
   240 					/* Only need to set the buffer to null, the rest is handled as the OK button */
   243 			case QUERY_EDIT_SIGN_WIDGET_DELETE:
   241 					DeleteTextBufferAll(&qs->text);
   244 				/* Only need to set the buffer to null, the rest is handled as the OK button */
   242 					/* FALL THROUGH */
   245 				DeleteTextBufferAll(&this->text);
   243 
   246 				/* FALL THROUGH */
   244 				case QUERY_EDIT_SIGN_WIDGET_OK:
   247 
   245 					RenameSign(qs->cur_sign, qs->text.buf);
   248 			case QUERY_EDIT_SIGN_WIDGET_OK:
   246 					/* FALL THROUGH */
   249 				RenameSign(this->cur_sign, this->text.buf);
   247 
   250 				/* FALL THROUGH */
   248 				case QUERY_EDIT_SIGN_WIDGET_CANCEL:
   251 
   249 					delete w;
   252 			case QUERY_EDIT_SIGN_WIDGET_CANCEL:
   250 					break;
   253 				delete this;
   251 			}
   254 				break;
   252 			break;
   255 		}
   253 
   256 	}
   254 		case WE_KEYPRESS:
   257 
   255 			switch (HandleEditBoxKey(w, qs, QUERY_EDIT_SIGN_WIDGET_TEXT, e)) {
   258 	virtual bool OnKeyPress(uint16 key, uint16 keycode)
   256 				case 1: // Enter pressed, confirms change
   259 	{
   257 					RenameSign(qs->cur_sign, qs->text.buf);
   260 		bool cont = true;
   258 					/* FALL THROUGH */
   261 		switch (this->HandleEditBoxKey(QUERY_EDIT_SIGN_WIDGET_TEXT, key, keycode, cont)) {
   259 
   262 			case 1: // Enter pressed, confirms change
   260 				case 2: // ESC pressed, closes window, abandons changes
   263 				RenameSign(this->cur_sign, this->text.buf);
   261 					delete w;
   264 				/* FALL THROUGH */
   262 					break;
   265 
   263 			}
   266 			case 2: // ESC pressed, closes window, abandons changes
   264 			break;
   267 				delete this;
   265 
   268 				break;
   266 		case WE_MOUSELOOP:
   269 		}
   267 			HandleEditBox(w, qs, QUERY_EDIT_SIGN_WIDGET_TEXT);
   270 		return cont;
   268 			break;
   271 	}
   269 
   272 
   270 		case WE_DESTROY:
   273 	virtual void OnMouseLoop()
   271 			ClrBit(_no_scroll, SCROLL_EDIT);
   274 	{
   272 			break;
   275 		this->HandleEditBox(QUERY_EDIT_SIGN_WIDGET_TEXT);
   273 	}
   276 	}
   274 }
   277 };
   275 
   278 
   276 static const Widget _query_sign_edit_widgets[] = {
   279 static const Widget _query_sign_edit_widgets[] = {
   277 { WWT_CLOSEBOX, RESIZE_NONE,  14,   0,  10,   0,  13, STR_00C5,          STR_018B_CLOSE_WINDOW},
   280 { WWT_CLOSEBOX, RESIZE_NONE,  14,   0,  10,   0,  13, STR_00C5,          STR_018B_CLOSE_WINDOW},
   278 {  WWT_CAPTION, RESIZE_NONE,  14,  11, 259,   0,  13, STR_012D,          STR_NULL },
   281 {  WWT_CAPTION, RESIZE_NONE,  14,  11, 259,   0,  13, STR_012D,          STR_NULL },
   279 {    WWT_PANEL, RESIZE_NONE,  14,   0, 259,  14,  29, STR_NULL,          STR_NULL },
   282 {    WWT_PANEL, RESIZE_NONE,  14,   0, 259,  14,  29, STR_NULL,          STR_NULL },
   290 static const WindowDesc _query_sign_edit_desc = {
   293 static const WindowDesc _query_sign_edit_desc = {
   291 	190, 170, 260, 42, 260, 42,
   294 	190, 170, 260, 42, 260, 42,
   292 	WC_QUERY_STRING, WC_NONE,
   295 	WC_QUERY_STRING, WC_NONE,
   293 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
   296 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
   294 	_query_sign_edit_widgets,
   297 	_query_sign_edit_widgets,
   295 	QuerySignEditWndProc
   298 	NULL
   296 };
   299 };
   297 
   300 
   298 void ShowRenameSignWindow(const Sign *si)
   301 void ShowRenameSignWindow(const Sign *si)
   299 {
   302 {
   300 	/* Delete all other edit windows and the save window */
   303 	/* Delete all other edit windows and the save window */
   301 	DeleteWindowById(WC_QUERY_STRING, 0);
   304 	DeleteWindowById(WC_QUERY_STRING, 0);
   302 	DeleteWindowById(WC_SAVELOAD, 0);
   305 	DeleteWindowById(WC_SAVELOAD, 0);
   303 
   306 
   304 	Window *w = new Window(&_query_sign_edit_desc);
   307 	new SignWindow(&_query_sign_edit_desc, si);
   305 
   308 }
   306 	WP(w, editsign_d).caption = STR_280B_EDIT_SIGN_TEXT;
       
   307 	WP(w, editsign_d).afilter = CS_ALPHANUMERAL;
       
   308 	w->LowerWidget(QUERY_EDIT_SIGN_WIDGET_TEXT);
       
   309 
       
   310 	UpdateSignEditWindow(w, si);
       
   311 }