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