diff options
Diffstat (limited to 'widget.c')
-rw-r--r-- | widget.c | 183 |
1 files changed, 183 insertions, 0 deletions
@@ -373,3 +373,186 @@ draw_default:; } } + +static uint _dropdown_item_count; +static uint32 _dropdown_disabled; +static const StringID *_dropdown_items; +static int _dropdown_selindex; +static byte _dropdown_button; +static WindowClass _dropdown_windowclass; +static WindowNumber _dropdown_windownum; +static byte _dropdown_var1; +static byte _dropdown_var2; + +static Widget _dropdown_menu_widgets[] = { +{ WWT_IMGBTN, 0, 0, 0, 0, 0, 0x0}, +{ WWT_LAST}, +}; + +static int GetDropdownItem(Window *w) +{ + uint item; + int y; + + if (GetWidgetFromPos(w, _cursor.pos.x - w->left, _cursor.pos.y - w->top) < 0) + return -1; + + y = _cursor.pos.y - w->top - 2; + + if (y < 0) + return - 1; + + item = y / 10; + if (item >= _dropdown_item_count || HASBIT(_dropdown_disabled,item) || _dropdown_items[item] == 0) + return - 1; + + return item; +} + +void DropdownMenuWndProc(Window *w, WindowEvent *e) +{ + int item; + + switch(e->event) { + case WE_PAINT: { + int x,y,i,sel; + uint32 dis; + + DrawWindowWidgets(w); + + x = 1; + y = 2; + sel = _dropdown_selindex; + dis = _dropdown_disabled; + + for(i=0; _dropdown_items[i] != INVALID_STRING_ID; i++) { + if (_dropdown_items[i] != 0) { + if (sel == 0) { + GfxFillRect(x+1, y, x+w->width-4, y + 9, 0); + } + DrawString(x+2, y, _dropdown_items[i], sel==0 ? 12 : 16); + + if (dis & 1) { + GfxFillRect(x, y, x+w->width-3, y + 9, 0x8000 + + _color_list[_dropdown_menu_widgets[0].color].window_color_bga); + } + } else { + int color_1 = _color_list[_dropdown_menu_widgets[0].color].window_color_1a; + int color_2 = _color_list[_dropdown_menu_widgets[0].color].window_color_2; + GfxFillRect(x+1, y+3, x+w->width-5, y+3, color_1); + GfxFillRect(x+1, y+4, x+w->width-5, y+4, color_2); + } + y += 10; + sel--; + dis>>=1; + } + } break; + + case WE_CLICK: { + item = GetDropdownItem(w); + if (item >= 0) { + _dropdown_var1 = 4; + _dropdown_selindex = item; + SetWindowDirty(w); + } + } break; + + case WE_MOUSELOOP: { + Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum); + if (w2 == NULL) { + DeleteWindow(w); + return; + } + + if (_dropdown_var1 != 0 && --_dropdown_var1 == 0) { + WindowEvent e; + e.event = WE_DROPDOWN_SELECT; + e.dropdown.button = _dropdown_button; + e.dropdown.index = _dropdown_selindex; + w2->wndproc(w2, &e); + DeleteWindow(w); + return; + } + + if (_dropdown_var2 != 0) { + item = GetDropdownItem(w); + + if (!_left_button_clicked) { + _dropdown_var2 = 0; + if (item < 0) + return; + _dropdown_var1 = 2; + } else { + if (item < 0) + return; + } + + _dropdown_selindex = item; + SetWindowDirty(w); + } + } break; + + case WE_DESTROY: { + Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum); + if (w2 != NULL) { + CLRBIT(w2->click_state, _dropdown_button); + InvalidateWidget(w2, _dropdown_button); + } + } break; + } +} + +void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask) +{ + WindowNumber num; + WindowClass cls; + int i,t1,t2; + const Widget *wi; + Window *w2; + uint32 old_click_state = w->click_state; + + _dropdown_disabled = disabled_mask; + + cls = w->window_class; + num = w->window_number; + DeleteWindowById(WC_DROPDOWN_MENU, 0); + w = FindWindowById(cls, num); + + if (HASBIT(old_click_state, button)) + return; + + SETBIT(w->click_state, button); + + InvalidateWidget(w, button); + + for(i=0;strings[i] != INVALID_STRING_ID;i++); + if (i == 0) + return; + + _dropdown_items = strings; + _dropdown_item_count = i; + _dropdown_selindex = selected; + + _dropdown_windowclass = w->window_class; + _dropdown_windownum = w->window_number; + _dropdown_button = button; + + _dropdown_var1 = 0; + _dropdown_var2 = 1; + + wi = &w->widget[button]; + + _dropdown_menu_widgets[0].color = wi->color; + + w2 = AllocateWindow( + w->left + wi[-1].left + 1, + w->top + wi->bottom + 2, + (_dropdown_menu_widgets[0].right=t1=wi->right - wi[-1].left, t1 + 1), + (_dropdown_menu_widgets[0].bottom=t2=i*10+3, t2+1), + DropdownMenuWndProc, + 0x3F, + _dropdown_menu_widgets); + + + w2->flags4 &= ~WF_WHITE_BORDER_MASK; +} |