1 //------------------------------------------------------------------------
2 // Information Bar (bottom of window)
3 //------------------------------------------------------------------------
4 //
5 // Eureka DOOM Editor
6 //
7 // Copyright (C) 2007-2019 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_linedef.h"
26 #include "m_config.h"
27 #include "m_game.h"
28 #include "r_grid.h"
29 #include "r_render.h"
30
31
32 #define SNAP_COLOR (gui_scheme == 2 ? fl_rgb_color(255,96,0) : fl_rgb_color(255, 96, 0))
33 #define FREE_COLOR (gui_scheme == 2 ? fl_rgb_color(0,192,0) : fl_rgb_color(128, 255, 128))
34
35 #define RATIO_COLOR FL_YELLOW
36
37
38 const char *UI_InfoBar::scale_options_str =
39 " 6%| 12%| 25%| 33%| 50%|100%|200%|400%|800%";
40
41 const double UI_InfoBar::scale_amounts[9] =
42 {
43 0.0625, 0.125, 0.25, 0.33333, 0.5, 1.0, 2.0, 4.0, 8.0
44 };
45
46 const char *UI_InfoBar::grid_options_str =
47 "1024|512|256|192|128| 64| 32| 16| 8| 4| 2|OFF";
48
49 const int UI_InfoBar::grid_amounts[12] =
50 {
51 1024, 512, 256, 192, 128, 64, 32, 16, 8, 4, 2,
52 -1 /* OFF */
53 };
54
55
56 //
57 // UI_InfoBar Constructor
58 //
UI_InfoBar(int X,int Y,int W,int H,const char * label)59 UI_InfoBar::UI_InfoBar(int X, int Y, int W, int H, const char *label) :
60 Fl_Group(X, Y, W, H, label)
61 {
62 box(FL_FLAT_BOX);
63
64
65 // Fitts' law : keep buttons flush with bottom of window
66 Y += 4;
67 H -= 4;
68
69
70 Fl_Box *mode_lab = new Fl_Box(FL_NO_BOX, X, Y, 56, H, "Mode:");
71 mode_lab->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
72 mode_lab->labelsize(16);
73
74 mode = new Fl_Menu_Button(X+58, Y, 96, H, "Things");
75 mode->align(FL_ALIGN_INSIDE);
76 mode->add("Things|Linedefs|Sectors|Vertices");
77 mode->callback(mode_callback, this);
78 mode->labelsize(16);
79
80 X = mode->x() + mode->w() + 10;
81
82
83 Fl_Box *scale_lab = new Fl_Box(FL_NO_BOX, X, Y, 58, H, "Scale:");
84 scale_lab->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
85 scale_lab->labelsize(16);
86
87 scale = new Fl_Menu_Button(X+60+26, Y, 78, H, "100%");
88 scale->align(FL_ALIGN_INSIDE);
89 scale->add(scale_options_str);
90 scale->callback(scale_callback, this);
91 scale->labelsize(16);
92
93 Fl_Button *sc_minus, *sc_plus;
94
95 sc_minus = new Fl_Button(X+60, Y+1, 24, H-2, "-");
96 sc_minus->callback(sc_minus_callback, this);
97 sc_minus->labelfont(FL_HELVETICA_BOLD);
98 sc_minus->labelsize(16);
99
100 sc_plus = new Fl_Button(X+60+26+80, Y+1, 24, H-2, "+");
101 sc_plus->callback(sc_plus_callback, this);
102 sc_plus->labelfont(FL_HELVETICA_BOLD);
103 sc_plus->labelsize(16);
104
105 X = sc_plus->x() + sc_plus->w() + 12;
106
107
108 Fl_Box *gs_lab = new Fl_Box(FL_NO_BOX, X, Y, 42, H, "Grid:");
109 gs_lab->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
110 gs_lab->labelsize(16);
111
112 grid_size = new Fl_Menu_Button(X+44, Y, 72, H, "OFF");
113
114 grid_size->align(FL_ALIGN_INSIDE);
115 grid_size->add(grid_options_str);
116 grid_size->callback(grid_callback, this);
117 grid_size->labelsize(16);
118
119 X = grid_size->x() + grid_size->w() + 12;
120
121
122 grid_snap = new Fl_Toggle_Button(X+4, Y, 72, H);
123 grid_snap->value(grid.snap ? 1 : 0);
124 grid_snap->color(FREE_COLOR);
125 grid_snap->selection_color(SNAP_COLOR);
126 grid_snap->callback(snap_callback, this);
127 grid_snap->labelsize(16);
128
129 UpdateSnapText();
130
131 X = grid_snap->x() + grid_snap->w() + 12;
132
133
134 Fl_Box *ratio_lab = new Fl_Box(FL_NO_BOX, X, Y, 52, H, "Ratio:");
135 ratio_lab->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
136 ratio_lab->labelsize(16);
137
138 ratio_lock = new Fl_Menu_Button(X+54, Y, 106, H, "UNLOCK");
139 ratio_lock->align(FL_ALIGN_INSIDE);
140 ratio_lock->add("UNLOCK|1:1|2:1|4:1|8:1|5:4|7:4|User Value");
141 ratio_lock->callback(ratio_callback, this);
142 ratio_lock->labelsize(16);
143
144 X = ratio_lock->x() + ratio_lock->w() + 12;
145
146
147 Fl_Box *rend_lab = new Fl_Box(FL_FLAT_BOX, X, Y, 56, H, "Rend:");
148 rend_lab->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
149 rend_lab->labelsize(16);
150
151 sec_rend = new Fl_Menu_Button(X+58, Y, 96, H, "PLAIN");
152 sec_rend->align(FL_ALIGN_INSIDE);
153 sec_rend->add("PLAIN|Floor|Ceiling|Lighting|Floor Bright|Ceil Bright|Sound|3D VIEW");
154 sec_rend->callback(rend_callback, this);
155 sec_rend->labelsize(16);
156
157 X = sec_rend->x() + rend_lab->w() + 10;
158
159
160 resizable(NULL);
161
162 end();
163 }
164
165 //
166 // UI_InfoBar Destructor
167 //
~UI_InfoBar()168 UI_InfoBar::~UI_InfoBar()
169 { }
170
171
handle(int event)172 int UI_InfoBar::handle(int event)
173 {
174 return Fl_Group::handle(event);
175 }
176
177
mode_callback(Fl_Widget * w,void * data)178 void UI_InfoBar::mode_callback(Fl_Widget *w, void *data)
179 {
180 Fl_Menu_Button *mode = (Fl_Menu_Button *)w;
181
182 static const char *mode_keys = "tlsvr";
183
184 Editor_ChangeMode(mode_keys[mode->value()]);
185 }
186
187
rend_callback(Fl_Widget * w,void * data)188 void UI_InfoBar::rend_callback(Fl_Widget *w, void *data)
189 {
190 Fl_Menu_Button *sec_rend = (Fl_Menu_Button *)w;
191
192 // last option is 3D mode
193 if (sec_rend->value() > SREND_SoundProp)
194 {
195 Render3D_Enable(true);
196 return;
197 }
198
199 switch (sec_rend->value())
200 {
201 case 1: edit.sector_render_mode = SREND_Floor; break;
202 case 2: edit.sector_render_mode = SREND_Ceiling; break;
203 case 3: edit.sector_render_mode = SREND_Lighting; break;
204 case 4: edit.sector_render_mode = SREND_FloorBright; break;
205 case 5: edit.sector_render_mode = SREND_CeilBright; break;
206 case 6: edit.sector_render_mode = SREND_SoundProp; break;
207 default: edit.sector_render_mode = SREND_Nothing; break;
208 }
209
210 if (edit.render3d)
211 Render3D_Enable(false);
212
213 // need sectors mode for sound propagation display
214 if (edit.sector_render_mode == SREND_SoundProp && edit.mode != OBJ_SECTORS)
215 Editor_ChangeMode('s');
216
217 RedrawMap();
218 }
219
220
scale_callback(Fl_Widget * w,void * data)221 void UI_InfoBar::scale_callback(Fl_Widget *w, void *data)
222 {
223 Fl_Menu_Button *scale = (Fl_Menu_Button *)w;
224
225 double new_scale = scale_amounts[scale->value()];
226
227 grid.NearestScale(new_scale);
228 }
229
230
sc_minus_callback(Fl_Widget * w,void * data)231 void UI_InfoBar::sc_minus_callback(Fl_Widget *w, void *data)
232 {
233 ExecuteCommand("Zoom", "-1", "/center");
234 }
235
sc_plus_callback(Fl_Widget * w,void * data)236 void UI_InfoBar::sc_plus_callback(Fl_Widget *w, void *data)
237 {
238 ExecuteCommand("Zoom", "+1", "/center");
239 }
240
241
grid_callback(Fl_Widget * w,void * data)242 void UI_InfoBar::grid_callback(Fl_Widget *w, void *data)
243 {
244 Fl_Menu_Button *gsize = (Fl_Menu_Button *)w;
245
246 int new_step = grid_amounts[gsize->value()];
247
248 if (new_step < 0)
249 grid.SetShown(false);
250 else
251 grid.ForceStep(new_step);
252 }
253
254
snap_callback(Fl_Widget * w,void * data)255 void UI_InfoBar::snap_callback(Fl_Widget *w, void *data)
256 {
257 Fl_Toggle_Button *grid_snap = (Fl_Toggle_Button *)w;
258
259 // update editor state
260 grid.SetSnap(grid_snap->value() ? true : false);
261 }
262
263
ratio_callback(Fl_Widget * w,void * data)264 void UI_InfoBar::ratio_callback(Fl_Widget *w, void *data)
265 {
266 Fl_Menu_Button *ratio_lock = (Fl_Menu_Button *)w;
267
268 grid.ratio = ratio_lock->value();
269 main_win->info_bar->UpdateRatio();
270 }
271
272
273 //------------------------------------------------------------------------
274
NewEditMode(obj_type_e new_mode)275 void UI_InfoBar::NewEditMode(obj_type_e new_mode)
276 {
277 switch (new_mode)
278 {
279 case OBJ_THINGS: mode->value(0); break;
280 case OBJ_LINEDEFS: mode->value(1); break;
281 case OBJ_SECTORS: mode->value(2); break;
282 case OBJ_VERTICES: mode->value(3); break;
283
284 default: break;
285 }
286
287 UpdateModeColor();
288 }
289
290
SetMouse(double mx,double my)291 void UI_InfoBar::SetMouse(double mx, double my)
292 {
293 // TODO this method should go away
294
295 main_win->status_bar->redraw();
296 }
297
298
SetScale(double new_scale)299 void UI_InfoBar::SetScale(double new_scale)
300 {
301 double perc = new_scale * 100.0;
302
303 char buffer[64];
304
305 if (perc < 10.0)
306 snprintf(buffer, sizeof(buffer), "%1.1f%%", perc);
307 else
308 snprintf(buffer, sizeof(buffer), "%3d%%", (int)perc);
309
310 scale->copy_label(buffer);
311 }
312
SetGrid(int new_step)313 void UI_InfoBar::SetGrid(int new_step)
314 {
315 if (new_step < 0)
316 {
317 grid_size->label("OFF");
318 }
319 else
320 {
321 char buffer[64];
322 snprintf(buffer, sizeof(buffer), "%d", new_step);
323 grid_size->copy_label(buffer);
324 }
325 }
326
327
UpdateSnap()328 void UI_InfoBar::UpdateSnap()
329 {
330 grid_snap->value(grid.snap ? 1 : 0);
331
332 UpdateSnapText();
333 }
334
335
UpdateSecRend()336 void UI_InfoBar::UpdateSecRend()
337 {
338 if (edit.render3d)
339 {
340 sec_rend->label("3D VIEW");
341 return;
342 }
343
344 switch (edit.sector_render_mode)
345 {
346 case SREND_Floor: sec_rend->label("Floor"); break;
347 case SREND_Ceiling: sec_rend->label("Ceiling"); break;
348 case SREND_Lighting: sec_rend->label("Lighting"); break;
349 case SREND_FloorBright: sec_rend->label("Floor Brt"); break;
350 case SREND_CeilBright: sec_rend->label("Ceil Brt"); break;
351 case SREND_SoundProp: sec_rend->label("Sound"); break;
352 default: sec_rend->label("PLAIN"); break;
353 }
354 }
355
356
UpdateRatio()357 void UI_InfoBar::UpdateRatio()
358 {
359 if (grid.ratio == 0)
360 ratio_lock->color(FL_BACKGROUND_COLOR);
361 else
362 ratio_lock->color(RATIO_COLOR);
363
364 if (grid.ratio == 7)
365 {
366 char buffer[256];
367 snprintf(buffer, sizeof(buffer), "Usr %d:%d", grid_ratio_high, grid_ratio_low);
368
369 // drop the "Usr" part when overly long
370 if (strlen(buffer) > 9)
371 ratio_lock->copy_label(buffer+4);
372 else
373 ratio_lock->copy_label(buffer);
374 }
375 else
376 {
377 ratio_lock->copy_label(ratio_lock->text(grid.ratio));
378 }
379 }
380
381
UpdateModeColor()382 void UI_InfoBar::UpdateModeColor()
383 {
384 switch (mode->value())
385 {
386 case 0: mode->label("Things"); mode->color(THING_MODE_COL); break;
387 case 1: mode->label("Linedefs"); mode->color(LINE_MODE_COL); break;
388 case 2: mode->label("Sectors"); mode->color(SECTOR_MODE_COL); break;
389 case 3: mode->label("Vertices"); mode->color(VERTEX_MODE_COL); break;
390 }
391 }
392
393
UpdateSnapText()394 void UI_InfoBar::UpdateSnapText()
395 {
396 if (grid_snap->value())
397 {
398 grid_snap->label("SNAP");
399 }
400 else
401 {
402 grid_snap->label("Free");
403 }
404
405 grid_snap->redraw();
406 }
407
408
409 //------------------------------------------------------------------------
410
411
412 #define INFO_TEXT_COL fl_rgb_color(192, 192, 192)
413 #define INFO_DIM_COL fl_rgb_color(128, 128, 128)
414
415
UI_StatusBar(int X,int Y,int W,int H,const char * label)416 UI_StatusBar::UI_StatusBar(int X, int Y, int W, int H, const char *label) :
417 Fl_Widget(X, Y, W, H, label),
418 status()
419 {
420 box(FL_NO_BOX);
421 }
422
~UI_StatusBar()423 UI_StatusBar::~UI_StatusBar()
424 { }
425
426
handle(int event)427 int UI_StatusBar::handle(int event)
428 {
429 // this never handles any events
430 return 0;
431 }
432
draw()433 void UI_StatusBar::draw()
434 {
435 fl_color(fl_rgb_color(64, 64, 64));
436 fl_rectf(x(), y(), w(), h());
437
438 fl_color(fl_rgb_color(96, 96, 96));
439 fl_rectf(x(), y() + h() - 1, w(), 1);
440
441 fl_push_clip(x(), y(), w(), h());
442
443 fl_font(FL_COURIER, 16);
444
445 int cx = x() + 10;
446 int cy = y() + 20;
447
448 if (edit.render3d)
449 {
450 IB_Number(cx, cy, "x", I_ROUND(r_view.x), 5);
451 IB_Number(cx, cy, "y", I_ROUND(r_view.y), 5);
452 IB_Number(cx, cy, "z", I_ROUND(r_view.z) - Misc_info.view_height, 4);
453
454 // use less space when an action is occurring
455 if (edit.action == ACT_NOTHING)
456 {
457 int ang = I_ROUND(r_view.angle * 180 / M_PI);
458 if (ang < 0) ang += 360;
459
460 IB_Number(cx, cy, "ang", ang, 3);
461 cx += 2;
462
463 IB_Flag(cx, cy, r_view.gravity, "GRAV", "grav");
464 #if 0
465 IB_Number(cx, cy, "gamma", usegamma, 1);
466 #endif
467 }
468
469 cx += 4;
470 }
471 else // 2D view
472 {
473 float mx = grid.SnapX(edit.map_x);
474 float my = grid.SnapX(edit.map_y);
475
476 mx = CLAMP(-32767, mx, 32767);
477 my = CLAMP(-32767, my, 32767);
478
479 IB_Coord(cx, cy, "x", mx);
480 IB_Coord(cx, cy, "y", my);
481 cx += 10;
482 #if 0
483 IB_Number(cx, cy, "gamma", usegamma, 1);
484 cx += 10;
485 #endif
486 }
487
488 /* status message */
489
490 IB_Flag(cx, cy, true, "|", "|");
491
492 fl_color(INFO_TEXT_COL);
493
494 switch (edit.action)
495 {
496 case ACT_DRAG:
497 IB_ShowDrag(cx, cy);
498 break;
499
500 case ACT_TRANSFORM:
501 IB_ShowTransform(cx, cy);
502 break;
503
504 case ACT_ADJUST_OFS:
505 IB_ShowOffsets(cx, cy);
506 break;
507
508 case ACT_DRAW_LINE:
509 IB_ShowDrawLine(cx, cy);
510 break;
511
512 default:
513 fl_draw(status.c_str(), cx, cy);
514 break;
515 }
516
517 fl_pop_clip();
518 }
519
520
IB_ShowDrag(int cx,int cy)521 void UI_StatusBar::IB_ShowDrag(int cx, int cy)
522 {
523 if (edit.render3d && edit.mode == OBJ_SECTORS)
524 {
525 IB_Number(cx, cy, "raise delta", I_ROUND(edit.drag_sector_dz), 4);
526 return;
527 }
528 if (edit.render3d && edit.mode == OBJ_THINGS && edit.drag_thing_up_down)
529 {
530 double dz = edit.drag_cur_z - edit.drag_start_z;
531 IB_Number(cx, cy, "raise delta", I_ROUND(dz), 4);
532 return;
533 }
534
535 double dx, dy;
536
537 if (edit.render3d)
538 {
539 dx = edit.drag_cur_x - edit.drag_start_x;
540 dy = edit.drag_cur_y - edit.drag_start_y;
541 }
542 else
543 {
544 main_win->canvas->DragDelta(&dx, &dy);
545 }
546
547 IB_Coord(cx, cy, "dragging delta x", dx);
548 IB_Coord(cx, cy, "y", dy);
549 }
550
551
IB_ShowTransform(int cx,int cy)552 void UI_StatusBar::IB_ShowTransform(int cx, int cy)
553 {
554 int rot_degrees;
555
556 switch (edit.trans_mode)
557 {
558 case TRANS_K_Scale:
559 IB_Coord(cx, cy, "scale by", edit.trans_param.scale_x);
560 break;
561
562 case TRANS_K_Stretch:
563 IB_Coord(cx, cy, "stretch x", edit.trans_param.scale_x);
564 IB_Coord(cx, cy, "y", edit.trans_param.scale_y);
565 break;
566
567 case TRANS_K_Rotate:
568 case TRANS_K_RotScale:
569 rot_degrees = edit.trans_param.rotate * 90 / 16384;
570 IB_Number(cx, cy, "rotate by", rot_degrees, 3);
571 break;
572
573 case TRANS_K_Skew:
574 IB_Coord(cx, cy, "skew x", edit.trans_param.skew_x);
575 IB_Coord(cx, cy, "y", edit.trans_param.skew_y);
576 break;
577 }
578
579 if (edit.trans_mode == TRANS_K_RotScale)
580 IB_Coord(cx, cy, "scale", edit.trans_param.scale_x);
581 }
582
583
IB_ShowOffsets(int cx,int cy)584 void UI_StatusBar::IB_ShowOffsets(int cx, int cy)
585 {
586 int dx = I_ROUND(edit.adjust_dx);
587 int dy = I_ROUND(edit.adjust_dy);
588
589 Objid hl = edit.highlight;
590
591 if (! edit.Selected->empty())
592 {
593 if (edit.Selected->count_obj() == 1)
594 {
595 int first = edit.Selected->find_first();
596 int parts = edit.Selected->get_ext(first);
597
598 hl = Objid(edit.mode, first, parts);
599 }
600 else
601 {
602 hl.clear();
603 }
604 }
605
606 if (hl.valid() && hl.parts >= 2)
607 {
608 const LineDef *L = LineDefs[edit.highlight.num];
609
610 int x_offset = 0;
611 int y_offset = 0;
612
613 const SideDef *SD = NULL;
614
615 if (hl.parts & PART_LF_ALL)
616 SD = L->Left();
617 else
618 SD = L->Right();
619
620 if (SD != NULL)
621 {
622 x_offset = SD->x_offset;
623 y_offset = SD->y_offset;
624
625 IB_Number(cx, cy, "new ofs x", x_offset + dx, 4);
626 IB_Number(cx, cy, "y", y_offset + dy, 4);
627 }
628 }
629
630 IB_Number(cx, cy, "delta x", dx, 4);
631 IB_Number(cx, cy, "y", dy, 4);
632 }
633
634
IB_ShowDrawLine(int cx,int cy)635 void UI_StatusBar::IB_ShowDrawLine(int cx, int cy)
636 {
637 if (! edit.draw_from.valid())
638 return;
639
640 const Vertex *V = Vertices[edit.draw_from.num];
641
642 double dx = edit.draw_to_x - V->x();
643 double dy = edit.draw_to_y - V->y();
644
645 // show a ratio value
646 fixcoord_t fdx = TO_COORD(dx);
647 fixcoord_t fdy = TO_COORD(dy);
648
649 std::string ratio_name = LD_RatioName(fdx, fdy, false);
650
651 int old_cx = cx;
652 IB_String(cx, cy, ratio_name.c_str());
653
654 cx = MAX(cx+12, old_cx + 170);
655
656 IB_Coord(cx, cy, "delta x", dx);
657 IB_Coord(cx, cy, "y", dy);
658 }
659
660
IB_Number(int & cx,int & cy,const char * label,int value,int size)661 void UI_StatusBar::IB_Number(int& cx, int& cy, const char *label, int value, int size)
662 {
663 char buffer[256];
664
665 // negative size means we require a sign
666 if (size < 0)
667 snprintf(buffer, sizeof(buffer), "%s:%-+*d ", label, -size + 1, value);
668 else
669 snprintf(buffer, sizeof(buffer), "%s:%-*d ", label, size, value);
670
671 fl_color(INFO_TEXT_COL);
672 fl_draw(buffer, cx, cy);
673
674 cx = cx + fl_width(buffer);
675 }
676
677
IB_Coord(int & cx,int & cy,const char * label,float value)678 void UI_StatusBar::IB_Coord(int& cx, int& cy, const char *label, float value)
679 {
680 char buffer[256];
681 snprintf(buffer, sizeof(buffer), "%s:%-8.2f ", label, value);
682
683 fl_color(INFO_TEXT_COL);
684 fl_draw(buffer, cx, cy);
685
686 cx = cx + fl_width(buffer);
687 }
688
689
IB_String(int & cx,int & cy,const char * str)690 void UI_StatusBar::IB_String(int& cx, int& cy, const char *str)
691 {
692 fl_draw(str, cx, cy);
693
694 cx = cx + fl_width(str);
695 }
696
697
IB_Flag(int & cx,int & cy,bool value,const char * label_on,const char * label_off)698 void UI_StatusBar::IB_Flag(int& cx, int& cy, bool value, const char *label_on, const char *label_off)
699 {
700 const char *label = value ? label_on : label_off;
701
702 fl_color(value ? INFO_TEXT_COL : INFO_DIM_COL);
703
704 fl_draw(label, cx, cy);
705
706 cx = cx + fl_width(label) + 20;
707 }
708
709
SetStatus(const char * str)710 void UI_StatusBar::SetStatus(const char *str)
711 {
712 if (status == str)
713 return;
714
715 status = str;
716
717 redraw();
718 }
719
720
Status_Set(const char * fmt,...)721 void Status_Set(const char *fmt, ...)
722 {
723 if (! main_win)
724 return;
725
726 va_list arg_ptr;
727
728 static char buffer[MSG_BUF_LEN];
729
730 va_start(arg_ptr, fmt);
731 vsnprintf(buffer, MSG_BUF_LEN-1, fmt, arg_ptr);
732 va_end(arg_ptr);
733
734 buffer[MSG_BUF_LEN-1] = 0;
735
736 main_win->status_bar->SetStatus(buffer);
737 }
738
739
Status_Clear()740 void Status_Clear()
741 {
742 if (! main_win)
743 return;
744
745 main_win->status_bar->SetStatus("");
746 }
747
748 //--- editor settings ---
749 // vi:ts=4:sw=4:noexpandtab
750