src/misc_gui.cpp
branchnoai
changeset 9722 ebf0ece7d8f6
parent 9718 f82a4facea8b
child 9723 eee46cb39750
equal deleted inserted replaced
9721:9a27928bcd5e 9722:ebf0ece7d8f6
    58 static void LandInfoWndProc(Window *w, WindowEvent *e)
    58 static void LandInfoWndProc(Window *w, WindowEvent *e)
    59 {
    59 {
    60 	if (e->event == WE_PAINT) {
    60 	if (e->event == WE_PAINT) {
    61 		DrawWindowWidgets(w);
    61 		DrawWindowWidgets(w);
    62 
    62 
    63 		DoDrawStringCentered(140, 16, _landinfo_data[0], 13);
    63 		DoDrawStringCentered(140, 16, _landinfo_data[0], TC_LIGHT_BLUE);
    64 		DoDrawStringCentered(140, 27, _landinfo_data[1], 0);
    64 		DoDrawStringCentered(140, 27, _landinfo_data[1], TC_FROMSTRING);
    65 		DoDrawStringCentered(140, 38, _landinfo_data[2], 0);
    65 		DoDrawStringCentered(140, 38, _landinfo_data[2], TC_FROMSTRING);
    66 		DoDrawStringCentered(140, 49, _landinfo_data[3], 0);
    66 		DoDrawStringCentered(140, 49, _landinfo_data[3], TC_FROMSTRING);
    67 		DoDrawStringCentered(140, 60, _landinfo_data[4], 0);
    67 		DoDrawStringCentered(140, 60, _landinfo_data[4], TC_FROMSTRING);
    68 		if (_landinfo_data[5][0] != '\0') DrawStringMultiCenter(140, 76, BindCString(_landinfo_data[5]), w->width - 4);
    68 		if (_landinfo_data[5][0] != '\0') DrawStringMultiCenter(140, 76, BindCString(_landinfo_data[5]), w->width - 4);
    69 		if (_landinfo_data[6][0] != '\0') DoDrawStringCentered(140, 71, _landinfo_data[6], 0);
    69 		if (_landinfo_data[6][0] != '\0') DoDrawStringCentered(140, 71, _landinfo_data[6], TC_FROMSTRING);
    70 	}
    70 	}
    71 }
    71 }
    72 
    72 
    73 static const Widget _land_info_widgets[] = {
    73 static const Widget _land_info_widgets[] = {
    74 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},
    74 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},
   197 {
   197 {
   198 	if (_cursor.sprite == SPR_CURSOR_QUERY) {
   198 	if (_cursor.sprite == SPR_CURSOR_QUERY) {
   199 		ResetObjectToPlace();
   199 		ResetObjectToPlace();
   200 	} else {
   200 	} else {
   201 		_place_proc = Place_LandInfo;
   201 		_place_proc = Place_LandInfo;
   202 		SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, 1, WC_MAIN_TOOLBAR, 0);
   202 		SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, VHM_RECT, WC_MAIN_TOOLBAR, 0);
   203 	}
   203 	}
   204 }
   204 }
   205 
   205 
   206 static const char *credits[] = {
   206 static const char *credits[] = {
   207 	/*************************************************************************
   207 	/*************************************************************************
   221 	"  Attila Bán (MiHaMiX) - WebTranslator, Nightlies, Wiki and bugtracker host",
   221 	"  Attila Bán (MiHaMiX) - WebTranslator, Nightlies, Wiki and bugtracker host",
   222 	"  Owen Rudge (orudge) - Forum host, OS/2 port",
   222 	"  Owen Rudge (orudge) - Forum host, OS/2 port",
   223 	"  Peter Nelson (peter1138) - Spiritual descendant from newgrf gods",
   223 	"  Peter Nelson (peter1138) - Spiritual descendant from newgrf gods",
   224 	"  Remko Bijker (Rubidium) - THE desync hunter",
   224 	"  Remko Bijker (Rubidium) - THE desync hunter",
   225 	"  Christoph Mallon (Tron) - Programmer, code correctness police",
   225 	"  Christoph Mallon (Tron) - Programmer, code correctness police",
   226 	"  Patric Stout (TrueLight) - Coder, network guru, SVN-, MS- and website host",
       
   227 	"",
   226 	"",
   228 	"Retired Developers:",
   227 	"Retired Developers:",
   229 	"  Ludvig Strigeus (ludde) - OpenTTD author, main coder (0.1 - 0.3.3)",
   228 	"  Ludvig Strigeus (ludde) - OpenTTD author, main coder (0.1 - 0.3.3)",
   230 	"  Serge Paquet (vurlix) - Assistant project manager, coder (0.1 - 0.3.3)",
   229 	"  Serge Paquet (vurlix) - Assistant project manager, coder (0.1 - 0.3.3)",
   231 	"  Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3.0 - 0.3.6)",
   230 	"  Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3.0 - 0.3.6)",
       
   231 	"  Patric Stout (TrueLight) - Programmer, webhoster (0.3 - pre0.6)",
   232 	"",
   232 	"",
   233 	"Special thanks go out to:",
   233 	"Special thanks go out to:",
   234 	"  Josef Drexler - For his great work on TTDPatch",
   234 	"  Josef Drexler - For his great work on TTDPatch",
   235 	"  Marcin Grzegorczyk - For his documentation of TTD internals",
   235 	"  Marcin Grzegorczyk - For his documentation of TTD internals",
   236 	"  Petr Baudis (pasky) - Many patches, newgrf support",
   236 	"  Petr Baudis (pasky) - Many patches, newgrf support",
   263 		uint i;
   263 		uint i;
   264 		int y = WP(w, scroller_d).height;
   264 		int y = WP(w, scroller_d).height;
   265 		DrawWindowWidgets(w);
   265 		DrawWindowWidgets(w);
   266 
   266 
   267 		/* Show original copyright and revision version */
   267 		/* Show original copyright and revision version */
   268 		DrawStringCentered(210, 17, STR_00B6_ORIGINAL_COPYRIGHT, 0);
   268 		DrawStringCentered(210, 17, STR_00B6_ORIGINAL_COPYRIGHT, TC_FROMSTRING);
   269 		DrawStringCentered(210, 17 + 10, STR_00B7_VERSION, 0);
   269 		DrawStringCentered(210, 17 + 10, STR_00B7_VERSION, TC_FROMSTRING);
   270 
   270 
   271 		/* Show all scrolling credits */
   271 		/* Show all scrolling credits */
   272 		for (i = 0; i < lengthof(credits); i++) {
   272 		for (i = 0; i < lengthof(credits); i++) {
   273 			if (y >= 50 && y < (w->height - 40)) {
   273 			if (y >= 50 && y < (w->height - 40)) {
   274 				DoDrawString(credits[i], 10, y, 0x10);
   274 				DoDrawString(credits[i], 10, y, TC_BLACK);
   275 			}
   275 			}
   276 			y += 10;
   276 			y += 10;
   277 		}
   277 		}
   278 
   278 
   279 		/* If the last text has scrolled start anew from the start */
   279 		/* If the last text has scrolled start anew from the start */
   280 		if (y < 50) WP(w, scroller_d).height = w->height - 40;
   280 		if (y < 50) WP(w, scroller_d).height = w->height - 40;
   281 
   281 
   282 		DoDrawStringCentered(210, w->height - 25, "Website: http://www.openttd.org", 16);
   282 		DoDrawStringCentered(210, w->height - 25, "Website: http://www.openttd.org", TC_BLACK);
   283 		DrawStringCentered(210, w->height - 15, STR_00BA_COPYRIGHT_OPENTTD, 0);
   283 		DrawStringCentered(210, w->height - 15, STR_00BA_COPYRIGHT_OPENTTD, TC_FROMSTRING);
   284 	} break;
   284 	} break;
   285 	case WE_MOUSELOOP: // Timer to scroll the text and adjust the new top
   285 	case WE_MOUSELOOP: // Timer to scroll the text and adjust the new top
   286 		if (WP(w, scroller_d).counter++ % 3 == 0) {
   286 		if (WP(w, scroller_d).counter++ % 3 == 0) {
   287 			WP(w, scroller_d).height--;
   287 			WP(w, scroller_d).height--;
   288 			SetWindowDirty(w);
   288 			SetWindowDirty(w);
   364 		case 3: case 4: case 5: case 6:
   364 		case 3: case 4: case 5: case 6:
   365 		case 7: case 8: case 9: case 10:
   365 		case 7: case 8: case 9: case 10:
   366 		case 11:case 12: case 13: case 14:
   366 		case 11:case 12: case 13: case 14:
   367 			if (wid - 3 >= WP(w,tree_d).count) break;
   367 			if (wid - 3 >= WP(w,tree_d).count) break;
   368 
   368 
   369 			if (HandlePlacePushButton(w, wid, SPR_CURSOR_TREE, 1, NULL))
   369 			if (HandlePlacePushButton(w, wid, SPR_CURSOR_TREE, VHM_RECT, NULL))
   370 				_tree_to_plant = WP(w,tree_d).base + wid - 3;
   370 				_tree_to_plant = WP(w,tree_d).base + wid - 3;
   371 			break;
   371 			break;
   372 
   372 
   373 		case 15: // tree of random type.
   373 		case 15: // tree of random type.
   374 			if (HandlePlacePushButton(w, 15, SPR_CURSOR_TREE, 1, NULL))
   374 			if (HandlePlacePushButton(w, 15, SPR_CURSOR_TREE, VHM_RECT, NULL))
   375 				_tree_to_plant = -1;
   375 				_tree_to_plant = -1;
   376 			break;
   376 			break;
   377 
   377 
   378 		case 16: // place trees randomly over the landscape
   378 		case 16: // place trees randomly over the landscape
   379 			LowerWindowWidget(w, 16);
   379 			LowerWindowWidget(w, 16);
   607 		w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
   607 		w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
   608 	} else {
   608 	} else {
   609 		if ( (x|y) != 0) {
   609 		if ( (x|y) != 0) {
   610 			pt = RemapCoords2(x, y);
   610 			pt = RemapCoords2(x, y);
   611 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
   611 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
   612 			pt.x = clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
   612 			pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
   613 			pt.y = clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
   613 			pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
   614 		} else {
   614 		} else {
   615 			pt.x = (_screen.width - 334) >> 1;
   615 			pt.x = (_screen.width - 334) >> 1;
   616 			pt.y = (_screen.height - 137) >> 1;
   616 			pt.y = (_screen.height - 137) >> 1;
   617 		}
   617 		}
   618 		w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
   618 		w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
   744 	}
   744 	}
   745 
   745 
   746 	/* Correctly position the tooltip position, watch out for window and cursor size
   746 	/* Correctly position the tooltip position, watch out for window and cursor size
   747 	 * Clamp value to below main toolbar and above statusbar. If tooltip would
   747 	 * Clamp value to below main toolbar and above statusbar. If tooltip would
   748 	 * go below window, flip it so it is shown above the cursor */
   748 	 * go below window, flip it so it is shown above the cursor */
   749 	y = clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, 22, _screen.height - 12);
   749 	y = Clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, 22, _screen.height - 12);
   750 	if (y + br.height > _screen.height - 12) y = _cursor.pos.y + _cursor.offs.y - br.height - 5;
   750 	if (y + br.height > _screen.height - 12) y = _cursor.pos.y + _cursor.offs.y - br.height - 5;
   751 	x = clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width);
   751 	x = Clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width);
   752 
   752 
   753 	w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
   753 	w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
   754 
   754 
   755 	WP(w, tooltips_d).string_id = str;
   755 	WP(w, tooltips_d).string_id = str;
   756 	assert(sizeof(WP(w, tooltips_d).params[0]) == sizeof(params[0]));
   756 	assert(sizeof(WP(w, tooltips_d).params[0]) == sizeof(params[0]));
  1085 	delta = (wi->right - wi->left) - tb->width - 10;
  1085 	delta = (wi->right - wi->left) - tb->width - 10;
  1086 	if (delta > 0) delta = 0;
  1086 	if (delta > 0) delta = 0;
  1087 
  1087 
  1088 	if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
  1088 	if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
  1089 
  1089 
  1090 	DoDrawString(tb->buf, delta, 0, 8);
  1090 	DoDrawString(tb->buf, delta, 0, TC_YELLOW);
  1091 	if (tb->caret) DoDrawString("_", tb->caretxoffs + delta, 0, 12);
  1091 	if (tb->caret) DoDrawString("_", tb->caretxoffs + delta, 0, TC_WHITE);
  1092 
  1092 
  1093 	_cur_dpi = old_dpi;
  1093 	_cur_dpi = old_dpi;
  1094 }
  1094 }
  1095 
  1095 
  1096 enum QueryStringWidgets {
  1096 enum QueryStringWidgets {
  1104 {
  1104 {
  1105 	querystr_d *qs = &WP(w, querystr_d);
  1105 	querystr_d *qs = &WP(w, querystr_d);
  1106 
  1106 
  1107 	switch (e->event) {
  1107 	switch (e->event) {
  1108 		case WE_CREATE:
  1108 		case WE_CREATE:
  1109 			SETBIT(_no_scroll, SCROLL_EDIT);
  1109 			SetBit(_no_scroll, SCROLL_EDIT);
  1110 			break;
  1110 			break;
  1111 
  1111 
  1112 		case WE_PAINT:
  1112 		case WE_PAINT:
  1113 			SetDParam(0, qs->caption);
  1113 			SetDParam(0, qs->caption);
  1114 			DrawWindowWidgets(w);
  1114 			DrawWindowWidgets(w);
  1160 
  1160 
  1161 				qs->handled = true;
  1161 				qs->handled = true;
  1162 				e.event = WE_ON_EDIT_TEXT_CANCEL;
  1162 				e.event = WE_ON_EDIT_TEXT_CANCEL;
  1163 				parent->wndproc(parent, &e);
  1163 				parent->wndproc(parent, &e);
  1164 			}
  1164 			}
  1165 			CLRBIT(_no_scroll, SCROLL_EDIT);
  1165 			ClrBit(_no_scroll, SCROLL_EDIT);
  1166 			break;
  1166 			break;
  1167 		}
  1167 		}
  1168 }
  1168 }
  1169 
  1169 
  1170 static const Widget _query_string_widgets[] = {
  1170 static const Widget _query_string_widgets[] = {
  1368 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   245,   256,   168,   179, 0x0,              STR_RESIZE_BUTTON},
  1368 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   245,   256,   168,   179, 0x0,              STR_RESIZE_BUTTON},
  1369 {   WIDGETS_END},
  1369 {   WIDGETS_END},
  1370 };
  1370 };
  1371 
  1371 
  1372 /* Colors for fios types */
  1372 /* Colors for fios types */
  1373 const byte _fios_colors[] = {13, 9, 9, 6, 5, 6, 5, 6, 6, 8};
  1373 const TextColour _fios_colors[] = {
       
  1374 	TC_LIGHT_BLUE, TC_DARK_GREEN,  TC_DARK_GREEN, TC_ORANGE, TC_LIGHT_BROWN,
       
  1375 	TC_ORANGE,     TC_LIGHT_BROWN, TC_ORANGE,     TC_ORANGE, TC_YELLOW
       
  1376 };
  1374 
  1377 
  1375 void BuildFileList()
  1378 void BuildFileList()
  1376 {
  1379 {
  1377 	_fios_path_changed = true;
  1380 	_fios_path_changed = true;
  1378 	FiosFreeSavegameList();
  1381 	FiosFreeSavegameList();
  1399 		str = FiosGetDescText(&path, &tot);
  1402 		str = FiosGetDescText(&path, &tot);
  1400 		_fios_path_changed = false;
  1403 		_fios_path_changed = false;
  1401 	}
  1404 	}
  1402 
  1405 
  1403 	if (str != STR_4006_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
  1406 	if (str != STR_4006_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
  1404 	DrawString(2, 37, str, 0);
  1407 	DrawString(2, 37, str, TC_FROMSTRING);
  1405 	DoDrawStringTruncated(path, 2, 27, 16, maxw);
  1408 	DoDrawStringTruncated(path, 2, 27, TC_BLACK, maxw);
  1406 }
  1409 }
  1407 
  1410 
  1408 static void MakeSortedSaveGameList()
  1411 static void MakeSortedSaveGameList()
  1409 {
  1412 {
  1410 	uint sort_start = 0;
  1413 	uint sort_start = 0;
  1489 
  1492 
  1490 		GfxFillRect(w->widget[7].left + 1, w->widget[7].top + 1, w->widget[7].right, w->widget[7].bottom, 0xD7);
  1493 		GfxFillRect(w->widget[7].left + 1, w->widget[7].top + 1, w->widget[7].right, w->widget[7].bottom, 0xD7);
  1491 		DoDrawString(
  1494 		DoDrawString(
  1492 			_savegame_sort_order & SORT_DESCENDING ? DOWNARROW : UPARROW,
  1495 			_savegame_sort_order & SORT_DESCENDING ? DOWNARROW : UPARROW,
  1493 			_savegame_sort_order & SORT_BY_NAME ? w->widget[2].right - 9 : w->widget[3].right - 9,
  1496 			_savegame_sort_order & SORT_BY_NAME ? w->widget[2].right - 9 : w->widget[3].right - 9,
  1494 			15, 16
  1497 			15, TC_BLACK
  1495 		);
  1498 		);
  1496 
  1499 
  1497 		y = w->widget[7].top + 1;
  1500 		y = w->widget[7].top + 1;
  1498 		for (pos = w->vscroll.pos; pos < _fios_num; pos++) {
  1501 		for (pos = w->vscroll.pos; pos < _fios_num; pos++) {
  1499 			const FiosItem *item = _fios_list + pos;
  1502 			const FiosItem *item = _fios_list + pos;
  1619 		/* pause is only used in single-player, non-editor mode, non menu mode */
  1622 		/* pause is only used in single-player, non-editor mode, non menu mode */
  1620 		if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
  1623 		if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
  1621 			DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
  1624 			DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
  1622 		}
  1625 		}
  1623 		FiosFreeSavegameList();
  1626 		FiosFreeSavegameList();
  1624 		CLRBIT(_no_scroll, SCROLL_SAVE);
  1627 		ClrBit(_no_scroll, SCROLL_SAVE);
  1625 		break;
  1628 		break;
  1626 	case WE_RESIZE: {
  1629 	case WE_RESIZE: {
  1627 		/* Widget 2 and 3 have to go with halve speed, make it so obiwan */
  1630 		/* Widget 2 and 3 have to go with halve speed, make it so obiwan */
  1628 		uint diff = e->we.sizing.diff.x / 2;
  1631 		uint diff = e->we.sizing.diff.x / 2;
  1629 		w->widget[2].right += diff;
  1632 		w->widget[2].right += diff;
  1670 
  1673 
  1671 	Window *w;
  1674 	Window *w;
  1672 	const WindowDesc *sld = &_save_dialog_desc;
  1675 	const WindowDesc *sld = &_save_dialog_desc;
  1673 
  1676 
  1674 
  1677 
  1675 	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, 0, WC_MAIN_WINDOW, 0);
  1678 	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
  1676 	DeleteWindowById(WC_QUERY_STRING, 0);
  1679 	DeleteWindowById(WC_QUERY_STRING, 0);
  1677 	DeleteWindowById(WC_SAVELOAD, 0);
  1680 	DeleteWindowById(WC_SAVELOAD, 0);
  1678 
  1681 
  1679 	_saveload_mode = mode;
  1682 	_saveload_mode = mode;
  1680 	SETBIT(_no_scroll, SCROLL_SAVE);
  1683 	SetBit(_no_scroll, SCROLL_SAVE);
  1681 
  1684 
  1682 	switch (mode) {
  1685 	switch (mode) {
  1683 		case SLD_SAVE_GAME:     GenerateFileName(); break;
  1686 		case SLD_SAVE_GAME:     GenerateFileName(); break;
  1684 		case SLD_SAVE_SCENARIO: strcpy(_edit_str_buf, "UNNAMED"); break;
  1687 		case SLD_SAVE_SCENARIO: strcpy(_edit_str_buf, "UNNAMED"); break;
  1685 		default:                sld = &_load_dialog_desc; break;
  1688 		default:                sld = &_load_dialog_desc; break;
  1898 				default: SetDParam(0, val);
  1901 				default: SetDParam(0, val);
  1899 				}
  1902 				}
  1900 			} break;
  1903 			} break;
  1901 			}
  1904 			}
  1902 
  1905 
  1903 			DrawString(50, y + 1, ce->str, 0);
  1906 			DrawString(50, y + 1, ce->str, TC_FROMSTRING);
  1904 
  1907 
  1905 			y += 12;
  1908 			y += 12;
  1906 		}
  1909 		}
  1907 		break;
  1910 		break;
  1908 	}
  1911 	}
  1933 				uint16 step = ((ce->max - ce->min) / 20);
  1936 				uint16 step = ((ce->max - ce->min) / 20);
  1934 				if (step == 0) step = 1;
  1937 				if (step == 0) step = 1;
  1935 
  1938 
  1936 				/* Increase or decrease the value and clamp it to extremes */
  1939 				/* Increase or decrease the value and clamp it to extremes */
  1937 				value += (x >= 30) ? step : -step;
  1940 				value += (x >= 30) ? step : -step;
  1938 				value = clamp(value, ce->min, ce->max);
  1941 				value = Clamp(value, ce->min, ce->max);
  1939 
  1942 
  1940 				/* take whatever the function returns */
  1943 				/* take whatever the function returns */
  1941 				value = ce->proc(value, (x >= 30) ? 1 : -1);
  1944 				value = ce->proc(value, (x >= 30) ? 1 : -1);
  1942 
  1945 
  1943 				if (value != oldvalue) {
  1946 				if (value != oldvalue) {