1 /* NetHack may be freely redistributed.  See license for details. */
2 
3 #include "vulture_win.h"
4 #include "vulture_gra.h"
5 #include "vulture_sdl.h"
6 #include "vulture_mou.h"
7 #include "vulture_txt.h"
8 #include "vulture_tile.h"
9 
10 #include "menuwin.h"
11 #include "objitemwin.h"
12 
13 
objitemwin(window * p,menuitem * mi,std::string cap,char accel,char group_accel,int glyph,bool selected,bool multiselect)14 objitemwin::objitemwin(window *p, menuitem* mi, std::string cap, char accel, char group_accel,
15                        int glyph, bool selected, bool multiselect) :
16                        optionwin(p, mi, cap, accel, group_accel, glyph, selected, multiselect)
17 {
18 	v_type = V_WINTYPE_OBJITEM;
19 	last_toggled = false;
20 	hover = false;
21 	autobg = true;
22 	w = V_LISTITEM_WIDTH;
23 	h = V_LISTITEM_HEIGHT;
24 	obj = NULL;
25 }
26 
27 
draw()28 bool objitemwin::draw()
29 {
30 	char tmpstr[32];
31 	int text_start_x, text_start_y, txt_height;
32 	int x = abs_x;
33 	int y = abs_y;
34 	int weight = 0;
35 	Uint32 textcolor;
36 
37 	vulture_set_draw_region(x, y, x + w - 1, y + h - 1);
38 
39 	/* re-set the background to prevent shadings from stacking repatedly until they become solid */
40 	if (background)
41 		vulture_put_img(x, y, background);
42 
43 
44 	/* hovering gives an item a light blue frame */
45 	if (hover)
46 		vulture_rect(x+1, y+1, x+w-2, y+h-2, CLR32_BLESS_BLUE);
47 
48 	/* otherwise, if it is selected, the item has an orange frame */
49 	else if (item->selected)
50 		vulture_rect(x+1, y+1, x+w-2, y+h-2, CLR32_ORANGE);
51 
52 	/* all other items appear etched */
53 	else
54 	{
55 		/* draw the outer edge of the frame */
56 		vulture_draw_lowered_frame(x, y, x+w-1, y+h-1);
57 		/* Inner edge */
58 		vulture_draw_raised_frame(x+1, y+1, x+w-2, y+h-2);
59 	}
60 
61 	/* the item that was toggled last has a white outer frame to indicate it's special status */
62 	if (last_toggled)
63 		vulture_rect(x, y, x+w-1, y+h-1, CLR32_WHITE);
64 
65 
66 	/* selected items also have yellow background shading */
67 	if (item->selected)
68 		vulture_fill_rect(x+h-1, y+2, x+w-3, y+h-3, CLR32_GOLD_SHADE);
69 
70 
71 	/* use a different text color for worn objects */
72 	if (obj && obj->owornmask)
73 		textcolor = CLR32_LIGHTGREEN;
74 	else
75 		textcolor = CLR32_WHITE;
76 
77 
78 	/* draw text, leaving a h by h square on the left free for the object tile */
79 	/* line 1 and if necessary line 2 contain the item description */
80 	vulture_put_text_multiline(V_FONT_MENU, caption, vulture_screen, x + h,
81 								y + 3, textcolor, CLR32_BLACK, w - h - 6);
82 
83   if ( obj ) {
84     weight = obj->owt;
85   }
86 
87 	/* weight is in line 3 */
88 	txt_height = vulture_text_height(V_FONT_MENU, caption);
89 	text_start_y = y + txt_height*2 + 4;
90 
91 	/* draw the object weight */
92 	tmpstr[0] = '\0';
93 	if (weight)
94 		snprintf(tmpstr, 32, "w: %d", weight);
95 	text_start_x = x + (w - vulture_text_length(V_FONT_MENU, tmpstr))/2;
96 	vulture_put_text_shadow(V_FONT_MENU, tmpstr, vulture_screen, text_start_x,
97 								text_start_y, textcolor, CLR32_BLACK);
98 
99 	if (item->selected) {
100 		tmpstr[0] = '\0';
101 		if (item->count <= 0 || (obj && item->count > obj->quan))
102 			snprintf(tmpstr, 32, "selected (all)");
103 		else
104 			snprintf(tmpstr, 32, "selected (%d)", item->count);
105 		text_start_x = x + w - vulture_text_length(V_FONT_MENU, tmpstr) - 6;
106 		vulture_put_text_shadow(V_FONT_MENU, tmpstr, vulture_screen, text_start_x,
107 									text_start_y, textcolor, CLR32_BLACK);
108 	}
109 
110 	/* draw the tile itself */
111 	/* constrain the drawing region to the box for the object tile, so that large
112 	* tiles don't overlap */
113 	vulture_set_draw_region(x + 2, y + 2, x + h - 3, y + h - 3);
114 
115 	/* darken the background */
116 	vulture_fill_rect(x + 2, y + 2, x + h - 3, y + h - 3, CLR32_BLACK_A30);
117 
118 	/* indicate blessed/cursed visually */
119 	if (obj && obj->bknown && obj->blessed)
120 		vulture_fill_rect(x + 2, y + 2, x + h - 3, y + h - 3, CLR32_BLESS_BLUE);
121 
122 	if (obj && obj->bknown && obj->cursed)
123 		vulture_fill_rect(x + 2, y + 2, x + h - 3, y + h - 3, CLR32_CURSE_RED);
124 
125 	/* draw the object tile */
126 	if (obj) {
127     int tile_x, tile_y;
128     int tile = 0;
129 
130 		tile = vulture_object_to_tile(obj->otyp, -1, -1, obj);
131 
132 		tile_x = x + h/2;
133 		tile_y = y + h * 3 / 4;
134 
135 		if (TILE_IS_OBJECT(tile))
136 		{
137 			tile = tile - OBJTILEOFFSET + ICOTILEOFFSET;
138 			tile_x = x + 2;
139 			tile_y = y + 2;
140 		}
141 
142     vulture_put_tile(tile_x, tile_y, tile);
143 	}
144 
145 	/* draw the item letter on the top left corner of the object tile */
146 	snprintf(tmpstr, 11, "%c", accelerator);
147 	vulture_put_text_shadow(V_FONT_MENU, tmpstr, vulture_screen, x + 2,
148 								y + 2, textcolor, CLR32_BLACK);
149 
150 	/* draw the quantity on the tile */
151 	if (obj && obj->quan > 1)
152 	{
153 		snprintf(tmpstr, 11, "%ld", obj->quan);
154 		txt_height = vulture_text_height(V_FONT_MENU, tmpstr);
155 		text_start_x = x + h - vulture_text_length(V_FONT_MENU, tmpstr) - 2;
156 		vulture_put_text_shadow(V_FONT_MENU, tmpstr, vulture_screen, text_start_x,
157 									y + h - txt_height, CLR32_WHITE, CLR32_BLACK);
158 	}
159 
160 	/* restore the drawing region */
161 	vulture_set_draw_region(0, 0, vulture_screen->w - 1, vulture_screen->h - 1);
162 
163 	vulture_invalidate_region(x, y, w, h);
164 
165 	return 0;
166 }
167 
168 
handle_mousemotion_event(window * target,void * result,int xrel,int yrel,int state)169 eventresult objitemwin::handle_mousemotion_event(window* target, void* result,
170                                                   int xrel, int yrel, int state)
171 {
172 	bool prevhover;
173 
174 	vulture_set_mcursor(V_CURSOR_NORMAL);
175 	prevhover = hover;
176 	hover = true;
177 
178 	if (hover != prevhover) {
179 		need_redraw = true;
180 		return V_EVENT_HANDLED_REDRAW;
181 	}
182 	return V_EVENT_HANDLED_NOREDRAW;
183 }
184 
185 
handle_other_event(window * target,void * result,SDL_Event * event)186 eventresult objitemwin::handle_other_event(window* target, void* result, SDL_Event *event)
187 {
188 	bool prevhover;
189 
190 	if (event->type == SDL_MOUSEMOVEOUT) {
191 		prevhover = hover;
192 		hover = false;
193 
194 		if (hover != prevhover) {
195 			need_redraw = true;
196 			return V_EVENT_HANDLED_REDRAW;
197 		}
198 		return V_EVENT_HANDLED_NOREDRAW;
199 	}
200 
201 	return V_EVENT_UNHANDLED;
202 }
203 
204 
handle_mousebuttonup_event(window * target,void * result,int mouse_x,int mouse_y,int button,int state)205 eventresult objitemwin::handle_mousebuttonup_event(window* target, void* result,
206                                 int mouse_x, int mouse_y, int button, int state)
207 {
208 	if (button == SDL_BUTTON_WHEELUP || button == SDL_BUTTON_WHEELDOWN)
209 		hover = false;
210 	return V_EVENT_UNHANDLED;
211 }
212