1 //------------------------------------------------------------------------
2 //  DEFAULT PROPERTIES
3 //------------------------------------------------------------------------
4 //
5 //  Eureka DOOM Editor
6 //
7 //  Copyright (C) 2007-2016 Andrew Apted
8 //
9 //  This program is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU General Public License
11 //  as published by the Free Software Foundation; either version 2
12 //  of the License, or (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU General Public License for more details.
18 //
19 //------------------------------------------------------------------------
20 
21 #include "main.h"
22 #include "ui_window.h"
23 
24 #include "e_main.h"
25 #include "e_cutpaste.h"
26 #include "m_config.h"	// gui_scheme
27 #include "m_game.h"
28 #include "r_render.h"
29 #include "w_rawdef.h"
30 #include "w_texture.h"
31 
32 
33 #define HIDE_BG  (gui_scheme == 2 ? FL_DARK3 : FL_DARK1)
34 
35 
UI_DefaultProps(int X,int Y,int W,int H)36 UI_DefaultProps::UI_DefaultProps(int X, int Y, int W, int H) :
37 	Fl_Group(X, Y, W, H, NULL)
38 {
39 	box(FL_FLAT_BOX);
40 
41 
42 	Fl_Button *hide_button = new Fl_Button(X + 14, Y + 14, 22, 22, "X");
43 	hide_button->color(HIDE_BG, HIDE_BG);
44 	hide_button->labelsize(14);
45 	hide_button->callback(hide_callback, this);
46 
47 
48 	Fl_Box *title = new Fl_Box(X + 60, Y + 10, W - 70, 30, "Default Properties");
49 	title->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
50 	title->labelsize(22);
51 
52 	Y += 35; H -= 35;
53 	X += 6;  W -= 12;
54 
55 
56 	// ---- LINEDEF TEXTURES ------------
57 
58 	Y += 32;
59 
60 	w_pic = new UI_Pic(X+W-76,   Y, 64, 64);
61 	w_pic->callback(tex_callback, this);
62 	w_pic->AllowHighlight(true);
63 
64 	Y += 20;
65 
66 	w_tex = new UI_DynInput(X+68,   Y, 108, 24, "Wall: ");
67 	w_tex->callback(tex_callback, this);
68 	w_tex->callback2(dyntex_callback, this);
69 	w_tex->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
70 
71 	Y += w_tex->h() + 50;
72 
73 
74 	// ---- SECTOR PROPS --------------
75 
76 	c_pic = new UI_Pic(X+W-76, Y+2,  64, 64);
77 	f_pic = new UI_Pic(X+W-76, Y+78, 64, 64);
78 
79 	c_pic->callback(flat_callback, this);
80 	f_pic->callback(flat_callback, this);
81 
82 	f_pic->AllowHighlight(true);
83 	c_pic->AllowHighlight(true);
84 
85 
86 	c_tex = new UI_DynInput(X+68, Y, 108, 24, "Ceiling: ");
87 	c_tex->align(FL_ALIGN_LEFT);
88 	c_tex->callback(flat_callback, this);
89 	c_tex->callback2(dyntex_callback, this);
90 	c_tex->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
91 
92 	Y += c_tex->h() + 3;
93 
94 
95 	ceil_h = new Fl_Int_Input(X+68, Y, 64, 24, "");
96 	ceil_h->align(FL_ALIGN_LEFT);
97 	ceil_h->callback(height_callback, this);
98 	ceil_h->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
99 
100 
101 
102 	ce_down = new Fl_Button(X+24,    Y+1, 30, 22, "-");
103 	ce_up   = new Fl_Button(X+68+68, Y+1, 30, 22, "+");
104 
105 	ce_down->labelfont(FL_HELVETICA_BOLD);
106 	ce_up  ->labelfont(FL_HELVETICA_BOLD);
107 	ce_down->labelsize(16);
108 	ce_up  ->labelsize(16);
109 
110 	ce_down->callback(button_callback, this);
111 	ce_up  ->callback(button_callback, this);
112 
113 
114 	Y += ceil_h->h() + 8;
115 
116 	floor_h = new Fl_Int_Input(X+68, Y, 64, 24, "");
117 	floor_h->align(FL_ALIGN_LEFT);
118 	floor_h->callback(height_callback, this);
119 	floor_h->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
120 
121 
122 	fl_down = new Fl_Button(X+24,    Y+1, 30, 22, "-");
123 	fl_up   = new Fl_Button(X+68+68, Y+1, 30, 22, "+");
124 
125 	fl_down->labelfont(FL_HELVETICA_BOLD);
126 	fl_up  ->labelfont(FL_HELVETICA_BOLD);
127 	fl_down->labelsize(16);
128 	fl_up  ->labelsize(16);
129 
130 	fl_down->callback(button_callback, this);
131 	fl_up  ->callback(button_callback, this);
132 
133 	Y += floor_h->h() + 3;
134 
135 
136 	f_tex = new UI_DynInput(X+68, Y, 108, 24, "Floor:   ");
137 	f_tex->align(FL_ALIGN_LEFT);
138 	f_tex->callback(flat_callback, this);
139 	f_tex->callback2(dyntex_callback, this);
140 	f_tex->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
141 
142 	Y += f_tex->h() + 8;
143 
144 
145 	light = new Fl_Int_Input(X+68, Y, 64, 24, "Light:   ");
146 	light->align(FL_ALIGN_LEFT);
147 	light->callback(height_callback, this);
148 	light->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
149 
150 	Y += light->h() + 40;
151 
152 
153 	// ---- THING PROPS --------------
154 
155 	thing = new UI_DynInput(X+60, Y+20, 64, 24, "Thing: ");
156 	thing->align(FL_ALIGN_LEFT);
157 	thing->callback(thing_callback, this);
158 	thing->callback2(dynthing_callback, this);
159 	thing->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
160 	thing->type(FL_INT_INPUT);
161 
162 	th_desc = new Fl_Output(X+60, Y+80-26, 122, 24);
163 
164 	th_sprite = new UI_Pic(X+W-90, Y, 80,80, "Sprite");
165 	th_sprite->callback(thing_callback, this);
166 
167 
168 	resizable(NULL);
169 
170 	end();
171 }
172 
173 
~UI_DefaultProps()174 UI_DefaultProps::~UI_DefaultProps()
175 { }
176 
177 
hide_callback(Fl_Widget * w,void * data)178 void UI_DefaultProps::hide_callback(Fl_Widget *w, void *data)
179 {
180 	main_win->HideSpecialPanel();
181 }
182 
183 
SetIntVal(Fl_Int_Input * w,int value)184 void UI_DefaultProps::SetIntVal(Fl_Int_Input *w, int value)
185 {
186 	char buffer[64];
187 	snprintf(buffer, sizeof(buffer), "%d", value);
188 	w->value(buffer);
189 }
190 
191 
UpdateThingDesc()192 void UI_DefaultProps::UpdateThingDesc()
193 {
194 	const thingtype_t *info = M_GetThingType(default_thing);
195 
196 	th_desc->value(info->desc);
197 	th_sprite->GetSprite(default_thing, FL_DARK2);
198 }
199 
200 
SetThing(int number)201 void UI_DefaultProps::SetThing(int number)
202 {
203 	default_thing = number;
204 
205 	thing->value(Int_TmpStr(default_thing));
206 
207 	UpdateThingDesc();
208 }
209 
210 
Normalize_and_Dup(UI_DynInput * w)211 const char * UI_DefaultProps::Normalize_and_Dup(UI_DynInput *w)
212 {
213 	const char *normalized = StringDup(NormalizeTex(w->value()));
214 
215 	w->value(normalized);
216 
217 	return normalized;
218 }
219 
220 
tex_callback(Fl_Widget * w,void * data)221 void UI_DefaultProps::tex_callback(Fl_Widget *w, void *data)
222 {
223 	UI_DefaultProps *box = (UI_DefaultProps *)data;
224 
225 	if (w == box->w_pic)
226 	{
227 		UI_Pic * pic = (UI_Pic *) w;
228 
229 		pic->Selected(! pic->Selected());
230 
231 		if (pic->Selected())
232 			main_win->BrowserMode('T');
233 
234 		return;
235 	}
236 
237 	if (w == box->w_tex)
238 	{
239 		default_wall_tex = Normalize_and_Dup(box->w_tex);
240 	}
241 
242 	box->w_pic->GetTex(box->w_tex->value());
243 }
244 
245 
flat_callback(Fl_Widget * w,void * data)246 void UI_DefaultProps::flat_callback(Fl_Widget *w, void *data)
247 {
248 	UI_DefaultProps *box = (UI_DefaultProps *)data;
249 
250 	if (w == box->f_pic ||
251 		w == box->c_pic)
252 	{
253 		UI_Pic * pic = (UI_Pic *) w;
254 
255 		pic->Selected(! pic->Selected());
256 
257 		if (pic->Selected())
258 			main_win->BrowserMode('F');
259 
260 		return;
261 	}
262 
263 	if (w == box->f_tex)
264 		default_floor_tex = Normalize_and_Dup(box->f_tex);
265 
266 	if (w == box->c_tex)
267 		default_ceil_tex = Normalize_and_Dup(box->c_tex);
268 
269 	box->f_pic->GetFlat(box->f_tex->value());
270 	box->c_pic->GetFlat(box->c_tex->value());
271 }
272 
273 
dyntex_callback(Fl_Widget * w,void * data)274 void UI_DefaultProps::dyntex_callback(Fl_Widget *w, void *data)
275 {
276 	UI_DefaultProps *box = (UI_DefaultProps *)data;
277 
278 	if (w == box->w_tex)
279 	{
280 		box->w_pic->GetTex(box->w_tex->value());
281 	}
282 	else if (w == box->f_tex)
283 	{
284 		box->f_pic->GetFlat(box->f_tex->value());
285 	}
286 	else if (w == box->c_tex)
287 	{
288 		box->c_pic->GetFlat(box->c_tex->value());
289 	}
290 }
291 
292 
button_callback(Fl_Widget * w,void * data)293 void UI_DefaultProps::button_callback(Fl_Widget *w, void *data)
294 {
295 	UI_DefaultProps *box = (UI_DefaultProps *)data;
296 
297 	keycode_t mod = Fl::event_state() & MOD_ALL_MASK;
298 
299 	int diff = 8;
300 
301 	if (mod & MOD_SHIFT)
302 		diff = 1;
303 	else if (mod & MOD_COMMAND)
304 		diff = 64;
305 
306 	if (w == box->fl_up)
307 		default_floor_h += diff;
308 
309 	if (w == box->fl_down)
310 		default_floor_h -= diff;
311 
312 	if (w == box->ce_up)
313 		default_ceil_h += diff;
314 
315 	if (w == box->ce_down)
316 		default_ceil_h -= diff;
317 
318 	box->SetIntVal(box->floor_h, default_floor_h);
319 	box->SetIntVal(box-> ceil_h, default_ceil_h);
320 }
321 
322 
height_callback(Fl_Widget * w,void * data)323 void UI_DefaultProps::height_callback(Fl_Widget *w, void *data)
324 {
325 	UI_DefaultProps *box = (UI_DefaultProps *)data;
326 
327 	default_floor_h = atoi(box->floor_h->value());
328 	default_ceil_h  = atoi(box-> ceil_h->value());
329 	default_light_level = atoi(box->light->value());
330 }
331 
332 
thing_callback(Fl_Widget * w,void * data)333 void UI_DefaultProps::thing_callback(Fl_Widget *w, void *data)
334 {
335 	UI_DefaultProps *box = (UI_DefaultProps *)data;
336 
337 	if (w == box->th_sprite)
338 	{
339 		main_win->BrowserMode('O');
340 		return;
341 	}
342 
343 	default_thing = atoi(box->thing->value());
344 
345 	box->UpdateThingDesc();
346 }
347 
348 
dynthing_callback(Fl_Widget * w,void * data)349 void UI_DefaultProps::dynthing_callback(Fl_Widget *w, void *data)
350 {
351 	UI_DefaultProps *box = (UI_DefaultProps *)data;
352 
353 	int value = atoi(box->thing->value());
354 
355 	const thingtype_t *info = M_GetThingType(value);
356 
357 	box->th_desc->value(info->desc);
358 	box->th_sprite->GetSprite(value, FL_DARK2);
359 }
360 
361 
LoadValues()362 void UI_DefaultProps::LoadValues()
363 {
364 	w_tex->value(default_wall_tex);
365 	f_tex->value(default_floor_tex);
366 	c_tex->value(default_ceil_tex);
367 
368 	w_pic->GetTex (w_tex->value());
369 	f_pic->GetFlat(f_tex->value());
370 	c_pic->GetFlat(c_tex->value());
371 
372 	SetIntVal(floor_h, default_floor_h);
373 	SetIntVal( ceil_h, default_ceil_h);
374 	SetIntVal(  light, default_light_level);
375 
376 	thing->value(Int_TmpStr(default_thing));
377 
378 	UpdateThingDesc();
379 }
380 
381 
CB_Copy(int sel_pics)382 void UI_DefaultProps::CB_Copy(int sel_pics)
383 {
384 	const char *name = NULL;
385 
386 	switch (sel_pics)
387 	{
388 		case 1: name = f_tex->value(); break;
389 		case 2: name = c_tex->value(); break;
390 		case 4: name = w_tex->value(); break;
391 
392 		default:
393 			Beep("multiple textures");
394 			return;
395 	}
396 
397 	if (sel_pics & 4)
398 		Texboard_SetTex(name);
399 	else
400 		Texboard_SetFlat(name);
401 }
402 
403 
CB_Paste(int sel_pics)404 void UI_DefaultProps::CB_Paste(int sel_pics)
405 {
406 	if (sel_pics & 1)
407 	{
408 		f_tex->value(BA_GetString(Texboard_GetFlatNum()));
409 		f_tex->do_callback();
410 	}
411 
412 	if (sel_pics & 2)
413 	{
414 		c_tex->value(BA_GetString(Texboard_GetFlatNum()));
415 		c_tex->do_callback();
416 	}
417 
418 	if (sel_pics & 4)
419 	{
420 		w_tex->value(BA_GetString(Texboard_GetTexNum()));
421 		w_tex->do_callback();
422 	}
423 }
424 
425 
CB_Delete(int sel_pics)426 void UI_DefaultProps::CB_Delete(int sel_pics)
427 {
428 	// we abuse the delete function to turn sector ceilings into sky
429 
430 	if (sel_pics & 1)
431 	{
432 		f_tex->value(Misc_info.sky_flat);
433 		f_tex->do_callback();
434 	}
435 
436 	if (sel_pics & 2)
437 	{
438 		c_tex->value(Misc_info.sky_flat);
439 		c_tex->do_callback();
440 	}
441 }
442 
443 
ClipboardOp(char op)444 bool UI_DefaultProps::ClipboardOp(char op)
445 {
446 	int sel_pics =	(f_pic->Selected() ? 1 : 0) |
447 					(c_pic->Selected() ? 2 : 0) |
448 					(w_pic->Selected() ? 4 : 0);
449 
450 	if (sel_pics == 0)
451 	{
452 		sel_pics =	(f_pic->Highlighted() ? 1 : 0) |
453 					(c_pic->Highlighted() ? 2 : 0) |
454 					(w_pic->Highlighted() ? 4 : 0);
455 	}
456 
457 	if (sel_pics == 0)
458 		return false;
459 
460 	switch (op)
461 	{
462 		case 'c':
463 			CB_Copy(sel_pics);
464 			break;
465 
466 		case 'v':
467 			CB_Paste(sel_pics);
468 			break;
469 
470 		case 'x':
471 			Beep("cannot cut that");
472 			break;
473 
474 		case 'd':
475 			CB_Delete(sel_pics);
476 			break;
477 	}
478 
479 	return true;
480 }
481 
482 
BrowsedItem(char kind,int number,const char * name,int e_state)483 void UI_DefaultProps::BrowsedItem(char kind, int number, const char *name, int e_state)
484 {
485 	if (kind == 'O')
486 	{
487 		SetThing(number);
488 		return;
489 	}
490 
491 	if (! (kind == 'T' || kind == 'F'))
492 		return;
493 
494 	int sel_pics =	(f_pic->Selected() ? 1 : 0) |
495 					(c_pic->Selected() ? 2 : 0) |
496 					(w_pic->Selected() ? 4 : 0);
497 
498 	if (sel_pics == 0)
499 	{
500 		if (kind == 'T')
501 			sel_pics = 4;
502 		else
503 			sel_pics = (e_state & FL_BUTTON3) ? 2 : 1;
504 	}
505 
506 
507 	if (sel_pics & 1)
508 	{
509 		f_tex->value(name);
510 		f_tex->do_callback();
511 	}
512 	if (sel_pics & 2)
513 	{
514 		c_tex->value(name);
515 		c_tex->do_callback();
516 	}
517 	if (sel_pics & 4)
518 	{
519 		w_tex->value(name);
520 		w_tex->do_callback();
521 	}
522 }
523 
524 
UnselectPics()525 void UI_DefaultProps::UnselectPics()
526 {
527 	w_pic->Unhighlight();
528 	f_pic->Unhighlight();
529 	c_pic->Unhighlight();
530 
531 	w_pic->Selected(false);
532 	f_pic->Selected(false);
533 	c_pic->Selected(false);
534 }
535 
536 
537 //------------------------------------------------------------------------
538 
539 
Props_ParseUser(const char ** tokens,int num_tok)540 bool Props_ParseUser(const char ** tokens, int num_tok)
541 {
542 	// syntax is:  default  <prop>  <value>
543 	if (num_tok < 3)
544 		return false;
545 
546 	if (strcmp(tokens[0], "default") != 0)
547 		return false;
548 
549 	if (strcmp(tokens[1], "floor_h") == 0)
550 		default_floor_h = atoi(tokens[2]);
551 
552 	if (strcmp(tokens[1], "ceil_h") == 0)
553 		default_ceil_h = atoi(tokens[2]);
554 
555 	if (strcmp(tokens[1], "light_level") == 0)
556 		default_light_level = atoi(tokens[2]);
557 
558 	if (strcmp(tokens[1], "thing") == 0)
559 		default_thing = atoi(tokens[2]);
560 
561 	if (strcmp(tokens[1], "floor_tex") == 0)
562 		default_floor_tex = StringDup(tokens[2]);
563 
564 	if (strcmp(tokens[1], "ceil_tex") == 0)
565 		default_ceil_tex = StringDup(tokens[2]);
566 
567 	if (strcmp(tokens[1], "mid_tex") == 0)
568 		default_wall_tex = StringDup(tokens[2]);
569 
570 	return true;
571 }
572 
573 
Props_WriteUser(FILE * fp)574 void Props_WriteUser(FILE *fp)
575 {
576 	fprintf(fp, "\n");
577 
578 	fprintf(fp, "default floor_h %d\n", default_floor_h);
579 	fprintf(fp, "default ceil_h %d\n",  default_ceil_h);
580 	fprintf(fp, "default light_level %d\n",  default_light_level);
581 	fprintf(fp, "default thing %d\n",  default_thing);
582 
583 	fprintf(fp, "default mid_tex \"%s\"\n",   StringTidy(default_wall_tex,  "\""));
584 	fprintf(fp, "default floor_tex \"%s\"\n", StringTidy(default_floor_tex, "\""));
585 	fprintf(fp, "default ceil_tex \"%s\"\n",  StringTidy(default_ceil_tex,  "\""));
586 }
587 
588 
Props_LoadValues()589 void Props_LoadValues()
590 {
591 	if (main_win)
592 		main_win->props_box->LoadValues();
593 }
594 
595 
596 //--- editor settings ---
597 // vi:ts=4:sw=4:noexpandtab
598