src/widget.cpp
changeset 6928 44797333bcbf
parent 6604 ad6057954de6
child 6977 67b989528f3d
equal deleted inserted replaced
6927:0ed416264b17 6928:44797333bcbf
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file widget.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "functions.h"
     7 #include "functions.h"
     6 #include "player.h"
     8 #include "player.h"
    50 	int mi, ma, pos;
    52 	int mi, ma, pos;
    51 	Scrollbar *sb;
    53 	Scrollbar *sb;
    52 
    54 
    53 	switch (wi->type) {
    55 	switch (wi->type) {
    54 		case WWT_SCROLLBAR: {
    56 		case WWT_SCROLLBAR: {
    55 			// vertical scroller
    57 			/* vertical scroller */
    56 			w->flags4 &= ~WF_HSCROLL;
    58 			w->flags4 &= ~WF_HSCROLL;
    57 			w->flags4 &= ~WF_SCROLL2;
    59 			w->flags4 &= ~WF_SCROLL2;
    58 			mi = wi->top;
    60 			mi = wi->top;
    59 			ma = wi->bottom;
    61 			ma = wi->bottom;
    60 			pos = y;
    62 			pos = y;
    61 			sb = &w->vscroll;
    63 			sb = &w->vscroll;
    62 			break;
    64 			break;
    63 		}
    65 		}
    64 		case WWT_SCROLL2BAR: {
    66 		case WWT_SCROLL2BAR: {
    65 			// 2nd vertical scroller
    67 			/* 2nd vertical scroller */
    66 			w->flags4 &= ~WF_HSCROLL;
    68 			w->flags4 &= ~WF_HSCROLL;
    67 			w->flags4 |= WF_SCROLL2;
    69 			w->flags4 |= WF_SCROLL2;
    68 			mi = wi->top;
    70 			mi = wi->top;
    69 			ma = wi->bottom;
    71 			ma = wi->bottom;
    70 			pos = y;
    72 			pos = y;
    71 			sb = &w->vscroll2;
    73 			sb = &w->vscroll2;
    72 			break;
    74 			break;
    73 		}
    75 		}
    74 		case  WWT_HSCROLLBAR: {
    76 		case  WWT_HSCROLLBAR: {
    75 			// horizontal scroller
    77 			/* horizontal scroller */
    76 			w->flags4 &= ~WF_SCROLL2;
    78 			w->flags4 &= ~WF_SCROLL2;
    77 			w->flags4 |= WF_HSCROLL;
    79 			w->flags4 |= WF_HSCROLL;
    78 			mi = wi->left;
    80 			mi = wi->left;
    79 			ma = wi->right;
    81 			ma = wi->right;
    80 			pos = x;
    82 			pos = x;
    82 			break;
    84 			break;
    83 		}
    85 		}
    84 		default: return; //this should never happen
    86 		default: return; //this should never happen
    85 	}
    87 	}
    86 	if (pos <= mi+9) {
    88 	if (pos <= mi+9) {
    87 		// Pressing the upper button?
    89 		/* Pressing the upper button? */
    88 		w->flags4 |= WF_SCROLL_UP;
    90 		w->flags4 |= WF_SCROLL_UP;
    89 		if (_scroller_click_timeout == 0) {
    91 		if (_scroller_click_timeout == 0) {
    90 			_scroller_click_timeout = 6;
    92 			_scroller_click_timeout = 6;
    91 			if (sb->pos != 0) sb->pos--;
    93 			if (sb->pos != 0) sb->pos--;
    92 		}
    94 		}
    93 		_left_button_clicked = false;
    95 		_left_button_clicked = false;
    94 	} else if (pos >= ma-10) {
    96 	} else if (pos >= ma-10) {
    95 		// Pressing the lower button?
    97 		/* Pressing the lower button? */
    96 		w->flags4 |= WF_SCROLL_DOWN;
    98 		w->flags4 |= WF_SCROLL_DOWN;
    97 
    99 
    98 		if (_scroller_click_timeout == 0) {
   100 		if (_scroller_click_timeout == 0) {
    99 			_scroller_click_timeout = 6;
   101 			_scroller_click_timeout = 6;
   100 			if ((byte)(sb->pos + sb->cap) < sb->count)
   102 			if ((byte)(sb->pos + sb->cap) < sb->count)
   101 				sb->pos++;
   103 				sb->pos++;
   102 		}
   104 		}
   103 		_left_button_clicked = false;
   105 		_left_button_clicked = false;
   104 	} else {
   106 	} else {
   105 		//
       
   106 		Point pt = HandleScrollbarHittest(sb, mi, ma);
   107 		Point pt = HandleScrollbarHittest(sb, mi, ma);
   107 
   108 
   108 		if (pos < pt.x) {
   109 		if (pos < pt.x) {
   109 			sb->pos = max(sb->pos - sb->cap, 0);
   110 			sb->pos = max(sb->pos - sb->cap, 0);
   110 		} else if (pos > pt.y) {
   111 		} else if (pos > pt.y) {
   125 }
   126 }
   126 
   127 
   127 /** Returns the index for the widget located at the given position
   128 /** Returns the index for the widget located at the given position
   128  * relative to the window. It includes all widget-corner pixels as well.
   129  * relative to the window. It includes all widget-corner pixels as well.
   129  * @param *w Window to look inside
   130  * @param *w Window to look inside
   130  * @param  x,y Window client coordinates
   131  * @param  x
       
   132  * @param  y Window client coordinates
   131  * @return A widget index, or -1 if no widget was found.
   133  * @return A widget index, or -1 if no widget was found.
   132  */
   134  */
   133 int GetWidgetFromPos(const Window *w, int x, int y)
   135 int GetWidgetFromPos(const Window *w, int x, int y)
   134 {
   136 {
   135 	uint index;
   137 	uint index;
   136 	int found_index = -1;
   138 	int found_index = -1;
   137 
   139 
   138 	// Go through the widgets and check if we find the widget that the coordinate is
   140 	/* Go through the widgets and check if we find the widget that the coordinate is
   139 	// inside.
   141 	 * inside. */
   140 	for (index = 0; index < w->widget_count; index++) {
   142 	for (index = 0; index < w->widget_count; index++) {
   141 		const Widget *wi = &w->widget[index];
   143 		const Widget *wi = &w->widget[index];
   142 		if (wi->type == WWT_EMPTY || wi->type == WWT_FRAME) continue;
   144 		if (wi->type == WWT_EMPTY || wi->type == WWT_FRAME) continue;
   143 
   145 
   144 		if (x >= wi->left && x <= wi->right && y >= wi->top &&  y <= wi->bottom &&
   146 		if (x >= wi->left && x <= wi->right && y >= wi->top &&  y <= wi->bottom &&
   292 			}
   294 			}
   293 
   295 
   294 			goto draw_default;
   296 			goto draw_default;
   295 		}
   297 		}
   296 
   298 
   297 		// vertical scrollbar
   299 		/* vertical scrollbar */
   298 		case WWT_SCROLLBAR: {
   300 		case WWT_SCROLLBAR: {
   299 			Point pt;
   301 			Point pt;
   300 			int c1,c2;
   302 			int c1,c2;
   301 
   303 
   302 			assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
   304 			assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
   303 
   305 
   304 			// draw up/down buttons
   306 			/* draw up/down buttons */
   305 			clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP);
   307 			clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP);
   306 			DrawFrameRect(r.left, r.top, r.right, r.top + 9, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
   308 			DrawFrameRect(r.left, r.top, r.right, r.top + 9, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
   307 			DoDrawString(UPARROW, r.left + 2 + clicked, r.top + clicked, 0x10);
   309 			DoDrawString(UPARROW, r.left + 2 + clicked, r.top + clicked, 0x10);
   308 
   310 
   309 			clicked = (((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN));
   311 			clicked = (((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN));
   311 			DoDrawString(DOWNARROW, r.left + 2 + clicked, r.bottom - 9 + clicked, 0x10);
   313 			DoDrawString(DOWNARROW, r.left + 2 + clicked, r.bottom - 9 + clicked, 0x10);
   312 
   314 
   313 			c1 = _colour_gradient[wi->color&0xF][3];
   315 			c1 = _colour_gradient[wi->color&0xF][3];
   314 			c2 = _colour_gradient[wi->color&0xF][7];
   316 			c2 = _colour_gradient[wi->color&0xF][7];
   315 
   317 
   316 			// draw "shaded" background
   318 			/* draw "shaded" background */
   317 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
   319 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
   318 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
   320 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
   319 
   321 
   320 			// draw shaded lines
   322 			/* draw shaded lines */
   321 			GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
   323 			GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
   322 			GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
   324 			GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
   323 			GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
   325 			GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
   324 			GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
   326 			GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
   325 
   327 
   331 			Point pt;
   333 			Point pt;
   332 			int c1,c2;
   334 			int c1,c2;
   333 
   335 
   334 			assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
   336 			assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
   335 
   337 
   336 			// draw up/down buttons
   338 			/* draw up/down buttons */
   337 			clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2));
   339 			clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2));
   338 			DrawFrameRect(r.left, r.top, r.right, r.top + 9, wi->color,  (clicked) ? FR_LOWERED : FR_NONE);
   340 			DrawFrameRect(r.left, r.top, r.right, r.top + 9, wi->color,  (clicked) ? FR_LOWERED : FR_NONE);
   339 			DoDrawString(UPARROW, r.left + 2 + clicked, r.top + clicked, 0x10);
   341 			DoDrawString(UPARROW, r.left + 2 + clicked, r.top + clicked, 0x10);
   340 
   342 
   341 			clicked = ((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2));
   343 			clicked = ((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2));
   343 			DoDrawString(DOWNARROW, r.left + 2 + clicked, r.bottom - 9 + clicked, 0x10);
   345 			DoDrawString(DOWNARROW, r.left + 2 + clicked, r.bottom - 9 + clicked, 0x10);
   344 
   346 
   345 			c1 = _colour_gradient[wi->color&0xF][3];
   347 			c1 = _colour_gradient[wi->color&0xF][3];
   346 			c2 = _colour_gradient[wi->color&0xF][7];
   348 			c2 = _colour_gradient[wi->color&0xF][7];
   347 
   349 
   348 			// draw "shaded" background
   350 			/* draw "shaded" background */
   349 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
   351 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
   350 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
   352 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
   351 
   353 
   352 			// draw shaded lines
   354 			/* draw shaded lines */
   353 			GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
   355 			GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
   354 			GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
   356 			GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
   355 			GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
   357 			GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
   356 			GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
   358 			GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
   357 
   359 
   358 			pt = HandleScrollbarHittest(&w->vscroll2, r.top, r.bottom);
   360 			pt = HandleScrollbarHittest(&w->vscroll2, r.top, r.bottom);
   359 			DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2) ? FR_LOWERED : FR_NONE);
   361 			DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2) ? FR_LOWERED : FR_NONE);
   360 			break;
   362 			break;
   361 		}
   363 		}
   362 
   364 
   363 		// horizontal scrollbar
   365 		/* horizontal scrollbar */
   364 		case WWT_HSCROLLBAR: {
   366 		case WWT_HSCROLLBAR: {
   365 			Point pt;
   367 			Point pt;
   366 			int c1,c2;
   368 			int c1,c2;
   367 
   369 
   368 			assert(r.bottom - r.top == 11); // XXX - to ensure the same sizes are used everywhere!
   370 			assert(r.bottom - r.top == 11); // XXX - to ensure the same sizes are used everywhere!
   376 			DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - 8 + clicked, r.top + 1 + clicked);
   378 			DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - 8 + clicked, r.top + 1 + clicked);
   377 
   379 
   378 			c1 = _colour_gradient[wi->color&0xF][3];
   380 			c1 = _colour_gradient[wi->color&0xF][3];
   379 			c2 = _colour_gradient[wi->color&0xF][7];
   381 			c2 = _colour_gradient[wi->color&0xF][7];
   380 
   382 
   381 			// draw "shaded" background
   383 			/* draw "shaded" background */
   382 			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c2);
   384 			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c2);
   383 			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
   385 			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
   384 
   386 
   385 			// draw shaded lines
   387 			/* draw shaded lines */
   386 			GfxFillRect(r.left+10, r.top+2, r.right-10, r.top+2, c1);
   388 			GfxFillRect(r.left+10, r.top+2, r.right-10, r.top+2, c1);
   387 			GfxFillRect(r.left+10, r.top+3, r.right-10, r.top+3, c2);
   389 			GfxFillRect(r.left+10, r.top+3, r.right-10, r.top+3, c2);
   388 			GfxFillRect(r.left+10, r.top+7, r.right-10, r.top+7, c1);
   390 			GfxFillRect(r.left+10, r.top+7, r.right-10, r.top+7, c1);
   389 			GfxFillRect(r.left+10, r.top+8, r.right-10, r.top+8, c2);
   391 			GfxFillRect(r.left+10, r.top+8, r.right-10, r.top+8, c2);
   390 
   392 
   391 			// draw actual scrollbar
   393 			/* draw actual scrollbar */
   392 			pt = HandleScrollbarHittest(&w->hscroll, r.left, r.right);
   394 			pt = HandleScrollbarHittest(&w->hscroll, r.left, r.right);
   393 			DrawFrameRect(pt.x, r.top, pt.y, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL) ? FR_LOWERED : FR_NONE);
   395 			DrawFrameRect(pt.x, r.top, pt.y, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL) ? FR_LOWERED : FR_NONE);
   394 
   396 
   395 			break;
   397 			break;
   396 		}
   398 		}
   402 			if (wi->data != 0) x2 = DrawString(r.left + 6, r.top, wi->data, 0);
   404 			if (wi->data != 0) x2 = DrawString(r.left + 6, r.top, wi->data, 0);
   403 
   405 
   404 			c1 = _colour_gradient[wi->color][3];
   406 			c1 = _colour_gradient[wi->color][3];
   405 			c2 = _colour_gradient[wi->color][7];
   407 			c2 = _colour_gradient[wi->color][7];
   406 
   408 
   407 			//Line from upper left corner to start of text
   409 			/*Line from upper left corner to start of text */
   408 			GfxFillRect(r.left, r.top+4, r.left+4,r.top+4, c1);
   410 			GfxFillRect(r.left, r.top+4, r.left+4,r.top+4, c1);
   409 			GfxFillRect(r.left+1, r.top+5, r.left+4,r.top+5, c2);
   411 			GfxFillRect(r.left+1, r.top+5, r.left+4,r.top+5, c2);
   410 
   412 
   411 			// Line from end of text to upper right corner
   413 			/* Line from end of text to upper right corner */
   412 			GfxFillRect(x2, r.top+4, r.right-1,r.top+4,c1);
   414 			GfxFillRect(x2, r.top+4, r.right-1,r.top+4,c1);
   413 			GfxFillRect(x2, r.top+5, r.right-2,r.top+5,c2);
   415 			GfxFillRect(x2, r.top+5, r.right-2,r.top+5,c2);
   414 
   416 
   415 			// Line from upper left corner to bottom left corner
   417 			/* Line from upper left corner to bottom left corner */
   416 			GfxFillRect(r.left, r.top+5, r.left, r.bottom-1, c1);
   418 			GfxFillRect(r.left, r.top+5, r.left, r.bottom-1, c1);
   417 			GfxFillRect(r.left+1, r.top+6, r.left+1, r.bottom-2, c2);
   419 			GfxFillRect(r.left+1, r.top+6, r.left+1, r.bottom-2, c2);
   418 
   420 
   419 			//Line from upper right corner to bottom right corner
   421 			/*Line from upper right corner to bottom right corner */
   420 			GfxFillRect(r.right-1, r.top+5, r.right-1, r.bottom-2, c1);
   422 			GfxFillRect(r.right-1, r.top+5, r.right-1, r.bottom-2, c1);
   421 			GfxFillRect(r.right, r.top+4, r.right, r.bottom-1, c2);
   423 			GfxFillRect(r.right, r.top+4, r.right, r.bottom-1, c2);
   422 
   424 
   423 			GfxFillRect(r.left+1, r.bottom-1, r.right-1, r.bottom-1, c1);
   425 			GfxFillRect(r.left+1, r.bottom-1, r.right-1, r.bottom-1, c1);
   424 			GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
   426 			GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
   499 
   501 
   500 	item = y / 10;
   502 	item = y / 10;
   501 	if (item >= WP(w,dropdown_d).num_items || (HASBIT(WP(w,dropdown_d).disabled_state, item) && !HASBIT(WP(w,dropdown_d).hidden_state, item)) || WP(w,dropdown_d).items[item] == 0)
   503 	if (item >= WP(w,dropdown_d).num_items || (HASBIT(WP(w,dropdown_d).disabled_state, item) && !HASBIT(WP(w,dropdown_d).hidden_state, item)) || WP(w,dropdown_d).items[item] == 0)
   502 		return - 1;
   504 		return - 1;
   503 
   505 
   504 	// Skip hidden items -- +1 for each hidden item before the clicked item.
   506 	/* Skip hidden items -- +1 for each hidden item before the clicked item. */
   505 	for (counter = 0; item >= counter; ++counter)
   507 	for (counter = 0; item >= counter; ++counter)
   506 		if (HASBIT(WP(w,dropdown_d).hidden_state, counter)) item++;
   508 		if (HASBIT(WP(w,dropdown_d).hidden_state, counter)) item++;
   507 
   509 
   508 	return item;
   510 	return item;
   509 }
   511 }