summaryrefslogtreecommitdiff
path: root/widget.c
diff options
context:
space:
mode:
Diffstat (limited to 'widget.c')
-rw-r--r--widget.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/widget.c b/widget.c
index 5d4ff9e4d..d56304287 100644
--- a/widget.c
+++ b/widget.c
@@ -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;
+}