truelight@0: #include "stdafx.h" truelight@0: #include "ttd.h" tron@507: #include "table/strings.h" truelight@0: #include "window.h" truelight@0: #include "gfx.h" truelight@0: #include "viewport.h" truelight@0: truelight@0: static Point HandleScrollbarHittest(Scrollbar *sb, int top, int bottom) truelight@0: { truelight@0: Point pt; truelight@0: int height, count, pos, cap; truelight@0: truelight@0: top += 10; truelight@0: bottom -= 9; truelight@193: truelight@0: height = (bottom - top); truelight@0: truelight@0: pos = sb->pos; truelight@0: count = sb->count; truelight@0: cap = sb->cap; truelight@0: truelight@0: if (count != 0) top += height * pos / count; truelight@193: truelight@0: if (cap > count) cap = count; truelight@0: if (count != 0) truelight@0: bottom -= (count - pos - cap) * height / count; truelight@0: truelight@0: pt.x = top; truelight@0: pt.y = bottom - 1; truelight@0: return pt; truelight@0: } truelight@0: truelight@0: /***************************************************** truelight@0: * Special handling for the scrollbar widget type. truelight@0: * Handles the special scrolling buttons and other truelight@0: * scrolling. truelight@0: * Parameters: truelight@0: * w - Window. truelight@0: * wi - Pointer to the scrollbar widget. truelight@0: * x - The X coordinate of the mouse click. truelight@0: * y - The Y coordinate of the mouse click. truelight@0: */ truelight@0: truelight@0: void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y) truelight@0: { truelight@0: int mi, ma, pos; truelight@0: Scrollbar *sb; truelight@0: bjarni@842: switch (wi->type) { bjarni@842: case WWT_SCROLLBAR: { bjarni@842: // vertical scroller bjarni@842: w->flags4 &= ~WF_HSCROLL; bjarni@842: w->flags4 &= ~WF_SCROLL2; bjarni@842: mi = wi->top; bjarni@842: ma = wi->bottom; bjarni@842: pos = y; bjarni@842: sb = &w->vscroll; bjarni@842: break; bjarni@842: } bjarni@842: case WWT_SCROLL2BAR: { bjarni@842: // 2nd vertical scroller bjarni@842: w->flags4 &= ~WF_HSCROLL; bjarni@842: w->flags4 |= WF_SCROLL2; bjarni@842: mi = wi->top; bjarni@842: ma = wi->bottom; bjarni@842: pos = y; bjarni@842: sb = &w->vscroll2; bjarni@842: break; bjarni@842: } bjarni@842: case WWT_HSCROLLBAR: { bjarni@842: // horizontal scroller truelight@867: w->flags4 &= ~WF_SCROLL2; bjarni@842: w->flags4 |= WF_HSCROLL; bjarni@842: mi = wi->left; bjarni@842: ma = wi->right; bjarni@842: pos = x; bjarni@842: sb = &w->hscroll; truelight@867: break; bjarni@842: } bjarni@845: default: return; //this should never happen truelight@0: } truelight@0: if (pos <= mi+9) { truelight@0: // Pressing the upper button? truelight@0: if (!_demo_mode) { truelight@0: w->flags4 |= WF_SCROLL_UP; truelight@0: if (_scroller_click_timeout == 0) { truelight@0: _scroller_click_timeout = 6; truelight@0: if (sb->pos != 0) sb->pos--; truelight@0: } truelight@0: _left_button_clicked = false; truelight@0: } truelight@0: } else if (pos >= ma-10) { truelight@0: // Pressing the lower button? truelight@0: if (!_demo_mode) { truelight@0: w->flags4 |= WF_SCROLL_DOWN; truelight@193: truelight@0: if (_scroller_click_timeout == 0) { truelight@0: _scroller_click_timeout = 6; truelight@0: if ((byte)(sb->pos + sb->cap) < sb->count) truelight@0: sb->pos++; truelight@0: } truelight@0: _left_button_clicked = false; truelight@0: } truelight@0: } else { truelight@193: // truelight@0: Point pt = HandleScrollbarHittest(sb, mi, ma); truelight@0: truelight@0: if (pos < pt.x) { truelight@0: sb->pos = max(sb->pos - sb->cap, 0); truelight@0: } else if (pos > pt.y) { truelight@0: sb->pos = min( truelight@193: sb->pos + sb->cap, truelight@0: max(sb->count - sb->cap, 0) truelight@0: ); truelight@0: } else { truelight@0: _scrollbar_start_pos = pt.x - mi - 9; truelight@0: _scrollbar_size = ma - mi - 23; truelight@0: w->flags4 |= WF_SCROLL_MIDDLE; truelight@0: _scrolling_scrollbar = true; truelight@0: _cursorpos_drag_start = _cursor.pos; truelight@0: } truelight@0: } truelight@0: truelight@0: SetWindowDirty(w); truelight@0: } truelight@0: truelight@0: /***************************************************** truelight@0: * Returns the index for the widget located at the given truelight@0: * position relative to the window. truelight@0: * Parameters: truelight@0: * w - Window truelight@0: * x/y - Window client coordinates truelight@0: * Returns: truelight@0: * A widget index, or -1 if no widget was found. truelight@0: */ truelight@0: int GetWidgetFromPos(Window *w, int x, int y) truelight@0: { truelight@0: const Widget *wi; truelight@0: int index, found_index = -1; truelight@0: truelight@0: // Go through the widgets and check if we find the widget that the coordinate is truelight@0: // inside. truelight@0: for(index=0,wi=w->widget; wi->type != WWT_LAST; index++, wi++) { truelight@0: if (wi->type == WWT_EMPTY || wi->type == WWT_FRAME) truelight@0: continue; truelight@0: truelight@0: if (x >= wi->left && truelight@0: x < wi->right && truelight@0: y >= wi->top && truelight@0: y < wi->bottom && !HASBIT(w->hidden_state,index)) { truelight@0: found_index = index; truelight@0: } truelight@0: } truelight@0: truelight@0: // Return the index truelight@0: return found_index; truelight@0: } truelight@0: truelight@0: truelight@0: void DrawWindowWidgets(Window *w) truelight@0: { truelight@0: const Widget *wi; truelight@0: DrawPixelInfo *dpi = _cur_dpi; truelight@0: Rect r; truelight@674: uint32 dparam_backup[20]; truelight@0: uint32 cur_click, cur_disabled, cur_hidden; truelight@193: truelight@0: if (w->desc_flags & WDF_RESTORE_DPARAM) COPY_OUT_DPARAM(dparam_backup, 0, lengthof(dparam_backup)); truelight@193: truelight@0: wi = w->widget; truelight@0: truelight@0: cur_click = w->click_state; truelight@0: cur_disabled = w->disabled_state; truelight@0: cur_hidden = w->hidden_state; truelight@0: truelight@0: do { truelight@0: if (dpi->left > (r.right=/*w->left + */wi->right) || truelight@0: dpi->left + dpi->width <= (r.left=wi->left/* + w->left*/) || truelight@0: dpi->top > (r.bottom=/*w->top +*/ wi->bottom) || truelight@0: dpi->top + dpi->height <= (r.top = /*w->top +*/ wi->top) || truelight@0: (cur_hidden&1)) truelight@0: continue; truelight@0: truelight@0: switch(wi->type&WWT_MASK) { truelight@0: case WWT_PANEL: truelight@0: case WWT_PANEL_2: { truelight@0: int img; truelight@0: truelight@0: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, truelight@0: (cur_click & 1) ? 0x20 : 0); truelight@0: truelight@0: if ((img=wi->unkA) != 0) { truelight@0: if ((wi->type&WWT_MASK) == WWT_PANEL_2 && (cur_click&1)) img++; truelight@0: DrawSprite(img, r.left+1, r.top+1); truelight@0: } truelight@0: goto draw_default; truelight@0: } truelight@0: truelight@0: case WWT_CLOSEBOX: truelight@0: case WWT_4: { truelight@0: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, truelight@0: (cur_click & 1) ? 0x20 : 0); truelight@0: } truelight@0: /* fall through */ truelight@0: truelight@0: case WWT_5: { truelight@0: StringID str = wi->unkA; truelight@0: truelight@0: if ((wi->type&WWT_MASK) == WWT_4 && (cur_click&1)) str++; truelight@193: truelight@0: DrawStringCentered((r.left + r.right+1)>>1, ((r.top+r.bottom + 1)>>1) - 5, str, 0); truelight@0: goto restore_dparam; truelight@0: } truelight@0: truelight@0: case WWT_6: { truelight@0: StringID str; truelight@0: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, 0x60); truelight@0: truelight@0: if ((str = wi->unkA) != 0) { truelight@0: DrawString(r.left+2, r.top+1, str, 0); truelight@0: goto restore_dparam; truelight@0: } truelight@0: goto draw_default; truelight@0: } truelight@0: truelight@0: case WWT_MATRIX: { truelight@193: int c, d, ctr; truelight@0: int x, amt1, amt2; truelight@0: int color; truelight@193: truelight@0: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, truelight@0: (cur_click & 1) ? 0x20 : 0); truelight@193: truelight@0: c = (wi->unkA&0xFF); truelight@0: amt1 = (wi->right - wi->left + 1) / c; truelight@0: truelight@0: d = (wi->unkA >> 8); truelight@0: amt2 = (wi->bottom - wi->top + 1) / d; truelight@0: truelight@0: color = _color_list[wi->color&0xF].window_color_bgb; truelight@193: truelight@0: x = r.left; truelight@0: for(ctr=c; --ctr; ) { truelight@0: x += amt1; truelight@0: GfxFillRect(x, r.top+1, x, r.bottom-1, color); truelight@0: } truelight@0: truelight@0: x = r.top; truelight@0: for(ctr=d; --ctr; ) { truelight@0: x += amt2; truelight@0: GfxFillRect(r.left+1, x, r.right-1, x, color); truelight@0: } truelight@0: truelight@0: color = _color_list[wi->color&0xF].window_color_1b; truelight@0: truelight@0: x = r.left-1; truelight@0: for(ctr=c; --ctr; ) { truelight@0: x += amt1; truelight@0: GfxFillRect(x, r.top+1, x, r.bottom-1, color); truelight@0: } truelight@0: truelight@0: x = r.top-1; truelight@0: for(ctr=d; --ctr; ) { truelight@0: x += amt2; truelight@0: GfxFillRect(r.left+1, x, r.right-1, x, color); truelight@0: } truelight@0: truelight@193: goto draw_default; truelight@0: } truelight@0: truelight@0: // vertical scrollbar truelight@0: case WWT_SCROLLBAR: { truelight@0: Point pt; truelight@0: int c1,c2; truelight@0: darkvater@893: assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere! darkvater@893: truelight@0: // draw up/down buttons bjarni@842: DrawFrameRect(r.left, r.top, r.right, r.top+9, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP ? 0x20 : 0); bjarni@842: DrawFrameRect(r.left, r.bottom-9, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN ? 0x20 : 0); truelight@0: truelight@0: // draw icons in up/down buttons truelight@0: DoDrawString("\xA0", r.left+2, r.top, 0x10); truelight@0: DoDrawString("\xAA", r.left+2, r.bottom-9, 0x10); truelight@0: truelight@0: c1 = _color_list[wi->color&0xF].window_color_1a; truelight@0: c2 = _color_list[wi->color&0xF].window_color_2; truelight@0: truelight@0: // draw "shaded" background truelight@0: GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2); truelight@0: GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | 0x8000); truelight@0: truelight@0: // draw shaded lines truelight@0: GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1); truelight@0: GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2); truelight@0: GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1); truelight@0: GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2); truelight@193: truelight@0: pt = HandleScrollbarHittest(&w->vscroll, r.top, r.bottom); bjarni@842: DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE ? 0x20 : 0); bjarni@842: break; bjarni@842: } bjarni@842: case WWT_SCROLL2BAR: { bjarni@842: Point pt; bjarni@842: int c1,c2; bjarni@842: darkvater@893: assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere! darkvater@893: bjarni@842: // draw up/down buttons bjarni@842: DrawFrameRect(r.left, r.top, r.right, r.top+9, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2) ? 0x20 : 0); bjarni@842: DrawFrameRect(r.left, r.bottom-9, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2) ? 0x20 : 0); bjarni@842: bjarni@842: // draw icons in up/down buttons bjarni@842: DoDrawString("\xA0", r.left+2, r.top, 0x10); bjarni@842: DoDrawString("\xAA", r.left+2, r.bottom-9, 0x10); bjarni@842: bjarni@842: c1 = _color_list[wi->color&0xF].window_color_1a; bjarni@842: c2 = _color_list[wi->color&0xF].window_color_2; bjarni@842: bjarni@842: // draw "shaded" background bjarni@842: GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2); bjarni@842: GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | 0x8000); bjarni@842: bjarni@842: // draw shaded lines bjarni@842: GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1); bjarni@842: GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2); bjarni@842: GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1); bjarni@842: GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2); bjarni@842: bjarni@842: pt = HandleScrollbarHittest(&w->vscroll2, r.top, r.bottom); bjarni@842: 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) ? 0x20 : 0); truelight@0: break; truelight@0: } truelight@0: truelight@0: // horizontal scrollbar truelight@0: case WWT_HSCROLLBAR: { truelight@0: Point pt; truelight@0: int c1,c2; truelight@0: darkvater@893: assert(r.bottom - r.top == 13); // XXX - to ensure the same sizes are used everywhere! darkvater@893: truelight@0: DrawFrameRect(r.left, r.top, r.left + 9, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL) ? 0x20 : 0); truelight@0: DrawFrameRect(r.right-9, r.top, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL) ? 0x20 : 0); truelight@0: truelight@0: // draw icons in up/down buttons darkvater@884: DrawSprite(SPR_ARROW_LEFT, r.left + 3, r.top + 2); darkvater@884: DrawSprite(SPR_ARROW_RIGHT, r.right - 6, r.top + 2); truelight@0: truelight@0: c1 = _color_list[wi->color&0xF].window_color_1a; truelight@0: c2 = _color_list[wi->color&0xF].window_color_2; truelight@0: truelight@0: // draw "shaded" background truelight@0: GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c2); truelight@0: GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | 0x8000); truelight@0: truelight@0: // draw shaded lines truelight@0: GfxFillRect(r.left+10, r.top+2, r.right-10, r.top+2, c1); truelight@0: GfxFillRect(r.left+10, r.top+3, r.right-10, r.top+3, c2); truelight@0: GfxFillRect(r.left+10, r.top+7, r.right-10, r.top+7, c1); truelight@0: GfxFillRect(r.left+10, r.top+8, r.right-10, r.top+8, c2); truelight@0: truelight@0: // draw actual scrollbar truelight@0: pt = HandleScrollbarHittest(&w->hscroll, r.left, r.right); truelight@0: DrawFrameRect(pt.x, r.top, pt.y, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL) ? 0x20 : 0); truelight@0: truelight@0: break; truelight@0: } truelight@0: truelight@0: case WWT_FRAME: { truelight@0: int c1,c2; darkvater@860: int x2 = r.left; // by default the left side is the left side of the widget truelight@0: truelight@0: if (wi->unkA != 0) { truelight@0: x2 = DrawString(r.left+6, r.top, wi->unkA, 0); truelight@0: } truelight@0: truelight@0: c1 = _color_list[wi->color].window_color_1a; truelight@0: c2 = _color_list[wi->color].window_color_2; truelight@0: truelight@0: //Line from upper left corner to start of text truelight@0: GfxFillRect(r.left, r.top+4, r.left+4,r.top+4, c1); truelight@0: GfxFillRect(r.left+1, r.top+5, r.left+4,r.top+5, c2); truelight@0: truelight@0: // Line from end of text to upper right corner truelight@0: GfxFillRect(x2, r.top+4, r.right-1,r.top+4,c1); truelight@0: GfxFillRect(x2, r.top+5, r.right-2,r.top+5,c2); truelight@0: truelight@0: // Line from upper left corner to bottom left corner truelight@0: GfxFillRect(r.left, r.top+5, r.left, r.bottom-1, c1); truelight@0: GfxFillRect(r.left+1, r.top+6, r.left+1, r.bottom-2, c2); truelight@0: truelight@0: //Line from upper right corner to bottom right corner truelight@0: GfxFillRect(r.right-1, r.top+5, r.right-1, r.bottom-2, c1); truelight@0: GfxFillRect(r.right, r.top+4, r.right, r.bottom-1, c2); truelight@0: truelight@0: GfxFillRect(r.left+1, r.bottom-1, r.right-1, r.bottom-1, c1); truelight@0: GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2); truelight@0: truelight@0: goto restore_dparam; truelight@0: } truelight@0: darkvater@682: case WWT_STICKYBOX: { darkvater@893: assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere! darkvater@682: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (cur_click & 1) ? 0x20 : 0); truelight@867: DrawSprite((cur_click & 1) ? SPR_PIN_UP : SPR_PIN_DOWN, r.left + 2, r.top + 3); darkvater@682: break; darkvater@682: } truelight@867: truelight@867: case WWT_RESIZEBOX: { darkvater@893: assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere! darkvater@893: truelight@867: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, 0); darkvater@893: DrawSprite(SPR_WINDOW_RESIZE, r.left + 3, r.top + 3); truelight@867: break; truelight@867: } truelight@867: truelight@0: case WWT_CAPTION: { darkvater@893: assert(r.bottom - r.top == 13); // XXX - to ensure the same sizes are used everywhere! truelight@0: DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, 0x10); truelight@0: DrawFrameRect(r.left+1, r.top+1, r.right-1, r.bottom-1, wi->color, (w->caption_color == 0xFF) ? 0x60 : 0x70); truelight@193: truelight@0: if (w->caption_color != 0xFF) { truelight@0: GfxFillRect(r.left+2, r.top+2, r.right-2, r.bottom-2, _color_list[_player_colors[w->caption_color]].window_color_1b); truelight@0: } truelight@0: truelight@0: DrawStringCentered( (r.left+r.right+1)>>1, r.top+2, wi->unkA, 0x84); truelight@0: restore_dparam:; truelight@0: if (w->desc_flags & WDF_RESTORE_DPARAM) COPY_IN_DPARAM(0, dparam_backup, lengthof(dparam_backup)); truelight@0: draw_default:; truelight@0: if (cur_disabled & 1) { truelight@0: GfxFillRect(r.left+1, r.top+1, r.right-1, r.bottom-1, _color_list[wi->color&0xF].unk2 | 0x8000); truelight@0: } truelight@0: } truelight@0: } truelight@0: } while (cur_click>>=1, cur_disabled>>=1, cur_hidden >>= 1, (++wi)->type != WWT_LAST); truelight@193: truelight@0: truelight@0: if (w->flags4 & WF_WHITE_BORDER_MASK) { truelight@0: //DrawFrameRect(w->left, w->top, w->left + w->width-1, w->top+w->height-1, 0xF, 0x10); truelight@0: DrawFrameRect(0, 0, w->width-1, w->height-1, 0xF, 0x10); truelight@0: } truelight@0: truelight@0: } darkvater@164: darkvater@164: static uint _dropdown_item_count; darkvater@164: static uint32 _dropdown_disabled; bjarni@842: static bool _dropdown_hide_disabled; darkvater@164: static const StringID *_dropdown_items; darkvater@164: static int _dropdown_selindex; darkvater@164: static byte _dropdown_button; darkvater@164: static WindowClass _dropdown_windowclass; darkvater@164: static WindowNumber _dropdown_windownum; darkvater@164: static byte _dropdown_var1; darkvater@164: static byte _dropdown_var2; darkvater@164: truelight@883: static const Widget _dropdown_menu_widgets[] = { truelight@867: { WWT_IMGBTN, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, darkvater@164: }; darkvater@164: darkvater@164: static int GetDropdownItem(Window *w) darkvater@164: { darkvater@164: uint item; darkvater@164: int y; darkvater@164: darkvater@164: if (GetWidgetFromPos(w, _cursor.pos.x - w->left, _cursor.pos.y - w->top) < 0) darkvater@164: return -1; truelight@193: darkvater@164: y = _cursor.pos.y - w->top - 2; darkvater@164: darkvater@164: if (y < 0) darkvater@164: return - 1; darkvater@164: darkvater@164: item = y / 10; darkvater@164: if (item >= _dropdown_item_count || HASBIT(_dropdown_disabled,item) || _dropdown_items[item] == 0) darkvater@164: return - 1; darkvater@164: darkvater@164: return item; darkvater@164: } darkvater@164: darkvater@164: void DropdownMenuWndProc(Window *w, WindowEvent *e) darkvater@164: { darkvater@164: int item; darkvater@164: darkvater@164: switch(e->event) { bjarni@842: case WE_PAINT: { bjarni@842: int x,y,i,sel; bjarni@842: uint32 dis; bjarni@842: bool hidden; darkvater@164: bjarni@842: DrawWindowWidgets(w); darkvater@164: bjarni@842: x = 1; bjarni@842: y = 2; bjarni@842: sel = _dropdown_selindex; bjarni@842: dis = _dropdown_disabled; bjarni@842: hidden = _dropdown_hide_disabled; truelight@867: darkvater@164: bjarni@842: for(i=0; _dropdown_items[i] != INVALID_STRING_ID; i++) { truelight@867: if (!(hidden && (dis & 1))) { bjarni@842: if (_dropdown_items[i] != 0) { bjarni@842: if (sel == 0) { bjarni@842: GfxFillRect(x+1, y, x+w->width-4, y + 9, 0); bjarni@842: } bjarni@842: DrawString(x+2, y, _dropdown_items[i], sel==0 ? 12 : 16); darkvater@164: bjarni@842: if (dis & 1) { bjarni@842: GfxFillRect(x, y, x+w->width-3, y + 9, 0x8000 + truelight@883: _color_list[w->widget[0].color].window_color_bga); bjarni@842: } bjarni@842: } else { truelight@883: int color_1 = _color_list[w->widget[0].color].window_color_1a; truelight@883: int color_2 = _color_list[w->widget[0].color].window_color_2; bjarni@842: GfxFillRect(x+1, y+3, x+w->width-5, y+3, color_1); bjarni@842: GfxFillRect(x+1, y+4, x+w->width-5, y+4, color_2); bjarni@842: } bjarni@842: y += 10; bjarni@842: sel--; bjarni@842: } bjarni@842: dis>>=1; bjarni@842: } bjarni@842: } break; bjarni@842: bjarni@842: case WE_CLICK: { bjarni@842: item = GetDropdownItem(w); bjarni@842: if (item >= 0) { bjarni@842: _dropdown_var1 = 4; bjarni@842: _dropdown_selindex = item; bjarni@842: SetWindowDirty(w); bjarni@842: } bjarni@842: } break; bjarni@842: bjarni@842: case WE_MOUSELOOP: { bjarni@842: Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum); bjarni@842: if (w2 == NULL) { bjarni@842: DeleteWindow(w); bjarni@842: return; darkvater@164: } darkvater@164: bjarni@842: if (_dropdown_var1 != 0 && --_dropdown_var1 == 0) { bjarni@842: WindowEvent e; bjarni@842: e.event = WE_DROPDOWN_SELECT; bjarni@842: e.dropdown.button = _dropdown_button; bjarni@842: e.dropdown.index = _dropdown_selindex; bjarni@842: w2->wndproc(w2, &e); bjarni@842: DeleteWindow(w); bjarni@842: return; bjarni@842: } truelight@193: bjarni@842: if (_dropdown_var2 != 0) { bjarni@842: item = GetDropdownItem(w); bjarni@842: bjarni@842: if (!_left_button_clicked) { bjarni@842: _dropdown_var2 = 0; bjarni@842: if (item < 0) bjarni@842: return; bjarni@842: _dropdown_var1 = 2; bjarni@842: } else { bjarni@842: if (item < 0) bjarni@842: return; bjarni@842: } bjarni@842: bjarni@842: _dropdown_selindex = item; bjarni@842: SetWindowDirty(w); bjarni@842: } bjarni@842: } break; bjarni@842: bjarni@842: case WE_DESTROY: { bjarni@842: Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum); bjarni@842: if (w2 != NULL) { bjarni@842: CLRBIT(w2->click_state, _dropdown_button); bjarni@842: InvalidateWidget(w2, _dropdown_button); bjarni@842: } bjarni@842: } break; darkvater@164: } darkvater@164: } darkvater@164: bjarni@842: void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, bool remove_filtered_strings) darkvater@164: { darkvater@164: WindowNumber num; darkvater@164: WindowClass cls; truelight@867: int i; darkvater@164: const Widget *wi; darkvater@164: Window *w2; darkvater@164: uint32 old_click_state = w->click_state; truelight@193: darkvater@164: _dropdown_disabled = disabled_mask; bjarni@842: _dropdown_hide_disabled = remove_filtered_strings; darkvater@164: darkvater@164: cls = w->window_class; darkvater@164: num = w->window_number; darkvater@164: DeleteWindowById(WC_DROPDOWN_MENU, 0); darkvater@164: w = FindWindowById(cls, num); darkvater@164: darkvater@164: if (HASBIT(old_click_state, button)) darkvater@164: return; darkvater@164: darkvater@164: SETBIT(w->click_state, button); darkvater@164: darkvater@164: InvalidateWidget(w, button); truelight@193: darkvater@164: for(i=0;strings[i] != INVALID_STRING_ID;i++); darkvater@164: if (i == 0) darkvater@164: return; darkvater@164: darkvater@164: _dropdown_items = strings; darkvater@164: _dropdown_item_count = i; darkvater@164: _dropdown_selindex = selected; truelight@193: darkvater@164: _dropdown_windowclass = w->window_class; darkvater@164: _dropdown_windownum = w->window_number; darkvater@164: _dropdown_button = button; truelight@193: darkvater@164: _dropdown_var1 = 0; darkvater@164: _dropdown_var2 = 1; darkvater@164: darkvater@164: wi = &w->widget[button]; darkvater@164: bjarni@842: if ( remove_filtered_strings ) { bjarni@842: int j; bjarni@842: for(j=0; _dropdown_items[j] != INVALID_STRING_ID; j++) { bjarni@842: if ( disabled_mask & ( 1 << j )) { bjarni@842: _dropdown_item_count--; bjarni@842: i--; bjarni@842: } bjarni@842: } bjarni@842: } bjarni@842: darkvater@164: w2 = AllocateWindow( darkvater@164: w->left + wi[-1].left + 1, darkvater@164: w->top + wi->bottom + 2, truelight@867: wi->right - wi[-1].left + 1, truelight@867: i * 10 + 4, darkvater@164: DropdownMenuWndProc, darkvater@164: 0x3F, darkvater@164: _dropdown_menu_widgets); darkvater@164: truelight@867: w2->widget[0].color = wi->color; truelight@867: w2->widget[0].right = wi->right - wi[-1].left; truelight@867: w2->widget[0].bottom = i * 10 + 3; darkvater@164: darkvater@164: w2->flags4 &= ~WF_WHITE_BORDER_MASK; darkvater@164: }