Initial commit
[forms.git] / src / F_Window.C
blob97b1724a01ad1c8ed1c336ec683e28520786cd9e
2 #include <F_Text_Display.H>
3 #include <F_Window.H>
5 using namespace F;
7 void F_Window::draw_border(F_Border_t brd)
9  if (brd == F_NO_BORDER)
10    brd = border_;
11  F_Text_Symbol lu('x', fg(), bg());
12  F_Text_Symbol ru('x', fg(), bg());
13  F_Text_Symbol ll('x', fg(), bg());
14  F_Text_Symbol rl('x', fg(), bg());
15  F_Text_Symbol hs('x', fg(), bg());
16  F_Text_Symbol vs('x', fg(), bg());
17  if (brd == F_DOUBLE_BORDER) {
18    // TODO: replace by recode()
19    lu.ch_ = 'É';
20    ru.ch_ = '»';
21    ll.ch_ = 'È';
22    rl.ch_ = '¼';
23    hs.ch_ = 'Í';
24    vs.ch_ = 'º';
25  } else if ((brd == F_SINGLE_BORDER) || (brd == F_MOVING_BORDER)) {
26    lu.ch_ = 'Ú';
27    ru.ch_ = '¿';
28    ll.ch_ = 'À';
29    rl.ch_ = 'Ù';
30    hs.ch_ = 'Ä';
31    vs.ch_ = '³';
32  } /* else if (brd == F_MOVING_BORDER) {
33    lu.ch = '.';
34    ru.ch = '.';
35    ll.ch = '.';
36    rl.ch = '.';
37    hs.ch = '.';
38    vs.ch = '.';
39  } */
40  F_Point p(0, 0);
41  draw_buf.set(p, lu);
42  p.move(w() - 1, 0);
43  draw_buf.set(p, ru);
44  p.move(0, h() - 1);
45  draw_buf.set(p, ll);
46  p.move(w() - 1, h() - 1);
47  draw_buf.set(p, rl);
48  F_Region r(1, 0, w() - 2, 1);
49  draw_buf.fill(r, hs);
50  r.move(1, h() - 1);
51  draw_buf.fill(r, hs);
52  r.w(1);
53  r.h(h() - 2);
54  r.move(0, 1);
55  draw_buf.fill(r, vs);
56  r.move(w() - 1, 1);
57  draw_buf.fill(r, vs);
60 void F_Window::draw_label()
62  if (!label_.size() || (label_type_ == F_NO_ALIGN))
63    return;
64  coord_t x = 0, y = 0;
65  if (label_type_ & F_ALIGN_LEFT)
66    x = (border_ == F_NO_BORDER) ? 0 : 1;
67  else if (label_type_ & F_ALIGN_RIGHT)
68    unimplemented("F_ALIGN_RIGHT");
69  if (label_type_ & F_ALIGN_TOP)
70    y = 0;
71  else if (label_type_ & F_ALIGN_BOTTOM)
72    y = h() - 1;
73  F_Point p(x, y);
74  std::string s(" " + label_ + " ");
75  put_string(p, s); //, label_type_);
78 void F_Window::draw()
80  F_Widget::draw();
81  draw_border();
82  draw_label();
83  for (unsigned int i = 0; i < widgets.size(); i++) {
84   if (widgets[i]->visible())
85     widgets[i]->draw();
86  }
87   F_Widget::damage(F_DAMAGE_FLUSH);
90 bool F_Window::handle(F_Event_t &ev)
92  F_Event_Type_t t = ev.type;
93  switch(ev.type) {
94    case F_KEY_PRESS:
95      if (ev.kbd.key == F_Tab) { // send FOCUS to next widget
96        if (ev.kbd.modifiers & F_SHIFT)
97          take_focus(focus_prev());
98        else
99          take_focus(focus_next());
100        ev.type = F_FOCUS;
101     }
102    case F_KEY_RELEASE:
103      if (focus() && focus()->handle(ev))
104        return true;
105      break;
106    case F_FOCUS:
107      debug("F_FOCUS: wid - %d, depth - %d", id(), depth());
108      break;
109    case F_UNFOCUS:
110      debug("F_UNFOCUS: wid - %d, depth - %d", id(), depth());
111      break;
112    case F_ENTER:
113      debug("F_ENTER: wid - %d, depth - %d", id(), depth());
114      break;
115    case F_LEAVE:
116      debug("F_LEAVE: wid - %d, depth - %d", id(), depth());
117      break;
118    case F_POINTER_PRESS:
119 //     debug("F_POINTER_PRESS: wid - %d", id());
120      // check for window moving
121      if (!(ev.mouse.y - y()) && (ev.mouse.x - x()) &&
122          ((ev.mouse.x - x()) < (w() - 1))) {
123 //       F_Widget::draw();
124 //       draw_border();
125        last_mx = ev.mouse.x;
126        last_my = ev.mouse.y;
127        f_text_display->cursor(0);
128        moving(1);
129        return true;
130     }
131      break;
132    case F_POINTER_RELEASE:
133      debug("F_POINTER_RELEASE: wid - %d", id());
134      if (moving()) {
135        draw();
136        moving(0);
137        return true;
138     }
139      break;
140    case F_POINTER_MOVE:
141      debug("F_POINTER_MOVE: wid - %d", id());
142      // ÐÒÏ×ÅÒÑÅÍ widget'Ù É ÐÏÓÙÌÁÅÍ ÉÍ F_ENTER/F_LEAVE
143      for (unsigned int i = 0; i < widgets.size(); i++) {
144        if (widgets[i]->visible()) {
145          if ((widget_belowmouse() == widgets[i]) &&
146              !widgets[i]->inside(F_Point(ev.mouse.x - x(), ev.mouse.y - y()))) {
147                ev.type = F_LEAVE;
148                widget_belowmouse()->handle(ev);
149                ev.type = t;
150                widget_belowmouse(0);
151                continue;
152           }
153            if (widgets[i]->inside(F_Point(ev.mouse.x - x(), ev.mouse.y - y())) &&
154            (widget_belowmouse() != widgets[i])) {
155              if (widget_belowmouse()) {
156                ev.type = F_LEAVE;
157                widget_belowmouse()->handle(ev);
158                ev.type = t;
159             }
160              widget_belowmouse(widgets[i]);
161              ev.type = F_ENTER;
162              return widget_belowmouse()->handle(ev);
163           }
164            // propagate F_POINTER_MOVE event
165            if (widget_belowmouse() == widgets[i])
166              if (widget_belowmouse()->handle(ev))
167                return true;
168       } // if (visible())
169     } // for()
170      goto out;
171    case F_POINTER_DRAG:
172 //     debug("F_POINTER_DRAG: wid - %d", id());
173      if (moving()) {
174        hide();
175        move(x() + (ev.mouse.x - last_mx), y() + (ev.mouse.y - last_my));
176        last_mx = ev.mouse.x;
177        last_my = ev.mouse.y;
178        show();
179        return true;
180     }
181      break;
182    case F_POINTER_DROP:
183      debug("F_POINTER_DROP: wid - %d", id());
184      if (moving()) {
185        draw();
186        moving(0);
187        return true;
188     }
189      break;
190    default:
191      break;
193    for (unsigned int i = 0; i < widgets.size(); i++) {
194      if (widgets[i]->visible()) {
195        if (widget_belowmouse() == widgets[i]) {
196          if (widget_belowmouse()->handle(ev))
197            return true;
198       } else if ((ev.type == F_KEY_PRESS) || (ev.type == F_KEY_RELEASE)) {
199           if (widgets[i]->handle(ev))
200             return true;
201       }
202    } // visible
203  } // for
204 out:
205   return F_Widget::handle(ev);
208 void F_Window::add(F_Widget *w)
210  w->parent(this);
211  w->id(++wid_);
212  widgets.push_back(w, wid_);
213  // add children
214  for (unsigned int i = 0; i < w->children.size(); i++) {
215    w->children[i]->parent(this);
216    w->children[i]->id(++wid_);
217    widgets.push_back(w->children[i], wid_);