widget.c
changeset 164 0cbdf3c9bde1
parent 0 29654efe3188
child 176 84990c4b9212
--- a/widget.c	Mon Sep 06 16:57:40 2004 +0000
+++ b/widget.c	Mon Sep 06 18:15:13 2004 +0000
@@ -373,3 +373,186 @@
 	}
 
 }
+
+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;
+}