1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * ====================================================== */
15 #pragma implementation
22 #include "support/lstrings.h"
23 #include "BufferView.h"
26 FL_OBJECT * figinset_canvas;
32 XSync(fl_get_display(), 0);
36 // Just a bunch of C wrappers around static members of WorkArea
37 void C_WorkArea_up_cb(FL_OBJECT * ob, long buf)
39 WorkArea::up_cb(ob, buf);
42 void C_WorkArea_down_cb(FL_OBJECT * ob, long buf)
44 WorkArea::down_cb(ob, buf);
47 void C_WorkArea_scroll_cb(FL_OBJECT * ob, long buf)
49 WorkArea::scroll_cb(ob, buf);
52 int C_WorkArea_work_area_handler(FL_OBJECT * ob, int event,
56 return WorkArea::work_area_handler(ob, event,
63 WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height)
64 : owner(o), workareapixmap(0)
69 fl_freeze_all_forms();
73 lyxerr << "Creating work area: +"
74 << xpos << '+' << ypos << ' '
75 << width << 'x' << height << endl;
78 const int bw = int(abs(float(fl_get_border_width())));
80 // We really want to get rid of figinset_canvas.
81 ::figinset_canvas = figinset_canvas = obj =
82 fl_add_canvas(FL_NORMAL_CANVAS,
83 xpos + 1, ypos + 1, 1, 1, "");
84 fl_set_object_boxtype(obj, FL_NO_BOX);
85 fl_set_object_resize(obj, FL_RESIZE_ALL);
86 fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity);
89 lyxerr << "\tbackground box: +"
90 << xpos << '+' << ypos << ' '
91 << width - 15 << 'x' << height << endl;
92 backgroundbox = obj = fl_add_box(FL_BORDER_BOX,
96 fl_set_object_resize(obj, FL_RESIZE_ALL);
97 fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
103 // up - scrollbar button
104 fl_set_border_width(-1);
106 lyxerr << "\tup button: +"
107 << xpos + width - 15 << '+' << ypos << ' '
108 << 15 << 'x' << 15 << endl;
109 button_up = obj = fl_add_pixmapbutton(FL_TOUCH_BUTTON,
113 fl_set_object_boxtype(obj,FL_UP_BOX);
114 fl_set_object_color(obj,FL_MCOL,FL_BLUE);
115 fl_set_object_resize(obj, FL_RESIZE_ALL);
116 fl_set_object_gravity(obj,NorthEastGravity, NorthEastGravity);
118 fl_set_object_callback(obj,C_WorkArea_up_cb, 0);
119 fl_set_pixmapbutton_data(obj, const_cast<char**>(up_xpm));
121 // Remove the blue feedback rectangle
122 fl_set_pixmapbutton_focus_outline(obj,0);
124 // the scrollbar slider
125 fl_set_border_width(-bw);
126 lyxerr << "\tscrollbar slider: +"
127 << xpos + width - 15 << '+' << ypos + 15 << ' '
128 << 15 << 'x' << height - 30 << endl;
129 scrollbar = obj = fl_add_slider(FL_VERT_SLIDER,
132 15, height - 30, "");
133 fl_set_object_color(obj,FL_COL1,FL_MCOL);
134 fl_set_object_boxtype(obj, FL_UP_BOX);
135 fl_set_object_resize(obj, FL_RESIZE_ALL);
136 fl_set_object_gravity(obj, NorthEastGravity, SouthEastGravity);
138 fl_set_object_callback(obj, C_WorkArea_scroll_cb, 0);
139 fl_set_slider_precision(obj, 0);
141 // down - scrollbar button
142 fl_set_border_width(-1);
144 lyxerr << "\tdown button: +"
145 << xpos + width - 15 << '+' << ypos + height - 15 << ' '
146 << 15 << 'x' << 15 << endl;
147 button_down = obj = fl_add_pixmapbutton(FL_TOUCH_BUTTON,
151 fl_set_object_boxtype(obj,FL_UP_BOX);
152 fl_set_object_color(obj,FL_MCOL,FL_BLUE);
153 fl_set_object_resize(obj, FL_RESIZE_ALL);
154 fl_set_object_gravity(obj, SouthEastGravity, SouthEastGravity);
156 fl_set_object_callback(obj, C_WorkArea_down_cb, 0);
157 fl_set_pixmapbutton_data(obj, const_cast<char**>(down_xpm));
159 fl_set_border_width(-bw);
161 // Remove the blue feedback rectangle
162 fl_set_pixmapbutton_focus_outline(obj,0);
167 // Create the workarea pixmap
168 createPixmap(width - 15 - 2 * bw, height - 2 * bw);
171 painter_.setDisplay(fl_display);
172 painter_.setDrawable(workareapixmap);
175 // We add this object as late as possible to avoit problems
177 lyxerr << "\tfree object: +"
178 << xpos + bw << '+' << ypos + bw << ' '
179 << width - 15 - 2 * bw << 'x' << height - 2 * bw << endl;
180 work_area = obj = fl_add_free(FL_INPUT_FREE,
181 xpos + bw, ypos + bw,
182 width - 15 - 2 * bw, // scrollbarwidth
184 C_WorkArea_work_area_handler);
185 obj->wantkey = FL_KEY_TAB;
186 obj->u_vdata = this; /* This is how we pass the WorkArea
187 to the work_area_handler. */
188 fl_set_object_boxtype(obj,FL_DOWN_BOX);
189 fl_set_object_resize(obj, FL_RESIZE_ALL);
190 fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
192 fl_unfreeze_all_forms();
196 WorkArea::~WorkArea()
199 XFreePixmap(fl_display, workareapixmap);
203 void WorkArea::resize(int xpos, int ypos, int width, int height)
205 fl_freeze_all_forms();
207 const int bw = int(abs(float(fl_get_border_width())));
210 fl_set_object_geometry(backgroundbox, xpos, ypos, width - 15, height);
216 // up - scrollbar button
217 fl_set_object_geometry(button_up, xpos + width - 15,
220 // the scrollbar slider
221 fl_set_object_geometry(scrollbar, xpos + width - 15,
224 // down - scrollbar button
225 fl_set_object_geometry(button_down, xpos + width - 15,
229 // Create the workarea pixmap
230 createPixmap(width - 15 - 2 * bw, height - 2 * bw);
234 painter_.setDrawable(workareapixmap);
238 fl_set_object_geometry(work_area, xpos + bw, ypos + bw,
242 fl_unfreeze_all_forms();
247 void WorkArea::createPixmap(int width, int height)
249 static int cur_width = -1;
250 static int cur_height = -1;
252 if (cur_width == width && cur_height == height && workareapixmap)
259 XFreePixmap(fl_display, workareapixmap);
261 lyxerr << "Creating pixmap (" << width << 'x' << height << ")" << endl;
263 workareapixmap = XCreatePixmap(fl_display,
264 RootWindow(fl_display, 0),
267 fl_get_visual_depth());
268 lyxerr << "\tpixmap=" << workareapixmap << endl;
272 void WorkArea::greyOut() const
274 fl_winset(FL_ObjWin(work_area));
275 fl_rectangle(1, work_area->x, work_area->y,
276 work_area->w, work_area->h, FL_GRAY63);
280 void WorkArea::setFocus() const
282 fl_set_focus_object(work_area->form, work_area);
286 void WorkArea::setScrollbar(double pos, double length_fraction) const
288 fl_set_slider_value(scrollbar, pos);
289 fl_set_slider_size(scrollbar, scrollbar->h * length_fraction);
293 void WorkArea::setScrollbarBounds(double l1, double l2) const
295 fl_set_slider_bounds(scrollbar, l1, l2);
299 void WorkArea::setScrollbarIncrements(float inc) const
301 fl_set_slider_increment(scrollbar, work_area->h - inc, inc);
305 void WorkArea::up_cb(FL_OBJECT * ob, long)
307 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
308 XEvent const * ev2 = fl_last_event();
309 static long time = 0;
310 ev2 = fl_last_event();
311 if (ev2->type == ButtonPress || ev2->type == ButtonRelease)
313 //area->up(time++, fl_get_button_numb(ob));
314 area->owner->UpCB(time++, fl_get_button_numb(ob));
318 void WorkArea::down_cb(FL_OBJECT * ob, long)
320 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
321 XEvent const * ev2 = fl_last_event();
322 static long time = 0;
323 if (ev2->type == ButtonPress || ev2->type == ButtonRelease)
325 //area->down(time++, fl_get_button_numb(ob));
326 area->owner->DownCB(time++, fl_get_button_numb(ob));
330 // Callback for scrollbar slider
331 void WorkArea::scroll_cb(FL_OBJECT * ob, long)
333 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
335 //area->scroll(fl_get_slider_value(ob));
336 area->owner->ScrollCB(fl_get_slider_value(ob));
340 bool Lgb_bug_find_hack = false;
342 int WorkArea::work_area_handler(FL_OBJECT * ob, int event,
344 int /*key*/, void * xev)
346 static int x_old = -1;
347 static int y_old = -1;
348 static long scrollbar_value_old = -1;
350 XEvent * ev = static_cast<XEvent*>(xev);
351 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
357 if (!area->work_area ||
358 !area->work_area->form->visible)
360 lyxerr.debug() << "Workarea event: DRAW" << endl;
361 area->createPixmap(area->workWidth(), area->height());
362 Lgb_bug_find_hack = true;
364 area->owner->workAreaExpose();
365 Lgb_bug_find_hack = false;
369 // Should really have used xbutton.state
370 lyxerr.debug() << "Workarea event: PUSH" << endl;
371 //area->buttonPress(ev->xbutton.x - ob->x,
372 // ev->xbutton.y - ob->y,
373 // ev->xbutton.button);
374 area->owner->WorkAreaButtonPress(ev->xbutton.x - ob->x,
375 ev->xbutton.y - ob->y,
380 // Should really have used xbutton.state
381 lyxerr.debug() << "Workarea event: RELEASE" << endl;
382 //area->buttonRelease(ev->xbutton.x - ob->x,
383 // ev->xbutton.y - ob->y,
384 // ev->xbutton.button);
385 area->owner->WorkAreaButtonRelease(ev->xbutton.x - ob->x,
386 ev->xbutton.y - ob->y,
390 if (!ev || ! area->scrollbar) break;
391 if (ev->xmotion.x != x_old ||
392 ev->xmotion.y != y_old ||
393 fl_get_slider_value(area->scrollbar) != scrollbar_value_old) {
394 lyxerr.debug() << "Workarea event: MOUSE" << endl;
395 //area->motion(ev->xmotion.x - ob->x,
396 // ev->xmotion.y - ob->y,
397 // ev->xbutton.state);
398 area->owner->WorkAreaMotionNotify(ev->xmotion.x - ob->x,
399 ev->xmotion.y - ob->y,
403 // Done by the raw callback:
404 // case FL_KEYBOARD: WorkAreaKeyPress(ob, 0,0,0,ev,0); break;
406 lyxerr.debug() << "Workarea event: FOCUS" << endl;
410 lyxerr.debug() << "Workarea event: UNFOCUS" << endl;
414 lyxerr.debug() << "Workarea event: ENTER" << endl;
418 lyxerr.debug() << "Workarea event: LEAVE" << endl;
423 lyxerr.debug() << "Workarea event: DBLCLICK" << endl;;
424 //area->doubleclick(ev->xbutton.x,
426 // ev->xbutton.button);
430 lyxerr.debug() << "Workarea event: TRPLCLICK" << endl;
431 //area->trippleclick(ev->xbutton.x,
433 // ev->xbutton.button);
437 if (ev->type == SelectionNotify) {
438 lyxerr.debug() << "Workarea event: SELECTION" << endl;
439 //area->selection(area->work_area->form->window, ev);
440 area->owner->WorkAreaSelectionNotify(area->work_area->form->window, ev);
442 lyxerr.debug() << "Workarea event: OTHER" << endl;