diff --git a/src/Makefile.am b/src/Makefile.am index eda11fb..22c17cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,8 +77,6 @@ solvespace_SOURCES = \ if HAVE_FLTK solvespace_SOURCES += \ - fltk/xFl_Gl_Window_Group.H \ - fltk/xFl_Gl_Window_Group.cxx \ fltk/fltkmain.cpp \ fltk/fltkutil.cpp diff --git a/src/fltk/fltkmain.cpp b/src/fltk/fltkmain.cpp index 531998c..6120c27 100644 --- a/src/fltk/fltkmain.cpp +++ b/src/fltk/fltkmain.cpp @@ -26,12 +26,13 @@ # endif #endif -#include //#include +#include #include #include #include #include // for fl_gettime() #include +#include #include "solvespace.h" @@ -44,6 +45,7 @@ class Text_Gl_Window; static Fl_Window *GraphicsWnd = NULL; static Graphics_Gl_Window *GraphicsGlWnd = NULL; +static Fl_Window *GraphicsEditControlWindow = NULL; static Fl_Input *GraphicsEditControl = NULL; static Fl_Sys_Menu_Bar *MenuBar = NULL; static Fl_Menu_Item MenuBarItems[120]; @@ -359,16 +361,24 @@ int64_t GetUnixTime(void) return (int64_t)ret; } -class Graphics_Gl_Window : public Fl_Gl_Window_Group +class Graphics_Gl_Window : public Fl_Gl_Window { public: Graphics_Gl_Window(int x, int y, int w, int h) - : Fl_Gl_Window_Group(x, y, w, h) + : Fl_Gl_Window(x, y, w, h) { mode(FL_RGB | FL_DOUBLE); } + virtual int handle(int event) { + if(handle_gl(event) == 0) { + return Fl_Gl_Window::handle(event); + } else { + return 1; + } + } + int handle_gl(int event) { switch(event) @@ -524,7 +534,16 @@ public: return 0; } + virtual void resize(int x, int y,int w, int h) { + Fl_Window::resize(x, y, w, h); + } + protected: + virtual void draw() { + if(damage()) { + draw_gl(); + } + } void draw_gl(void) { @@ -608,16 +627,24 @@ bool MenuBarIsVisible(void) return MenuBarVisible; } -class Text_Gl_Window : public Fl_Gl_Window_Group +class Text_Gl_Window : public Fl_Gl_Window { public: Text_Gl_Window(int x, int y, int w, int h) - : Fl_Gl_Window_Group(x, y, w, h) + : Fl_Gl_Window(x, y, w, h) { mode(FL_RGB | FL_DOUBLE); } + virtual int handle(int event) { + if(handle_gl(event) == 0) { + return Fl_Gl_Window::handle(event); + } else { + return 1; + } + } + int handle_gl(int event) { switch(event) @@ -657,7 +684,16 @@ public: return 0; } + virtual void resize(int x, int y,int w, int h) { + Fl_Window::resize(x, y, w, h); + } + protected: + virtual void draw() { + if(damage()) { + draw_gl(); + } + } void draw_gl(void) { @@ -713,12 +749,11 @@ void ShowGraphicsEditControl(int x, int y, char *s) // Convert to ij (vs. xy) style coordinates, // and compensate for the input widget height due to inverse coord x = x + GraphicsGlWnd->w()/2; - y = -y + GraphicsGlWnd->h()/2 - GraphicsEditControl->h(); + y = -y + GraphicsGlWnd->h()/2 - GraphicsEditControlWindow->h(); - // Use of the :: 0perator to avoid confusion with the Fl_input positon metod. - GraphicsEditControl->Fl_Widget::position(x, y); + GraphicsEditControlWindow->position(x, y); GraphicsEditControl->value(s); - GraphicsEditControl->show(); + GraphicsEditControlWindow->show(); // Grab focus and select all to ease editing GraphicsEditControl->take_focus(); @@ -733,12 +768,12 @@ void HideGraphicsEditControl(void) // this avoid the disapparition of the mouse pointer if it was over the widget GraphicsGlWnd->take_focus(); - GraphicsEditControl->hide(); + GraphicsEditControlWindow->hide(); } bool GraphicsEditControlIsVisible(void) { - return GraphicsEditControl->visible(); + return GraphicsEditControlWindow->visible(); } void InvalidateText(void) @@ -768,6 +803,9 @@ static void WindowCloseHandler(Fl_Window *wnd, void *data) if(wnd == GraphicsWnd) { SolveSpace::MenuFile(GraphicsWindow::MNU_EXIT); } + else if(wnd == GraphicsEditControlWindow) { + HideGraphicsEditControl(); + } else if(wnd == TextWnd) { if(SS.GW.showTextWindow) { GraphicsWindow::MenuView(GraphicsWindow::MNU_SHOW_TEXT_WND); @@ -1123,14 +1161,33 @@ static void CreateMainWindows(void) GraphicsWnd->resizable(GraphicsGlWnd); GraphicsWnd->size_range(Fl::w() / 4, Fl::h() / 4); - GraphicsEditControl = new Fl_Input(0, 20, 120, 30); + GraphicsGlWnd->end(); + GraphicsWnd->end(); + + int w = 120; + int h = 30; + int padding = 5; + + GraphicsEditControlWindow = new Fl_Window( + w + (padding * 2), h + (padding * 2), + "" + ); + + GraphicsEditControlWindow->set_tooltip_window(); + + GraphicsEditControl = new Fl_Input( + (GraphicsEditControlWindow->w() / 2) - (w / 2), + (GraphicsEditControlWindow->h() / 2) - (h / 2), + w, + h + ); + GraphicsEditControl->textfont(SS_FONT_MONOSPACE); GraphicsEditControl->callback(EditControlCallback); GraphicsEditControl->when(FL_WHEN_ENTER_KEY | FL_WHEN_NOT_CHANGED); - GraphicsEditControl->hide(); - GraphicsGlWnd->end(); - GraphicsWnd->end(); + GraphicsEditControlWindow->end(); + GraphicsEditControlWindow->hide(); // Text window diff --git a/src/fltk/xFl_Gl_Window_Group.H b/src/fltk/xFl_Gl_Window_Group.H deleted file mode 100644 index 3c9ee05..0000000 --- a/src/fltk/xFl_Gl_Window_Group.H +++ /dev/null @@ -1,105 +0,0 @@ -// -// "$Id$" -// -// OpenGL window group widget for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2010 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// http://www.fltk.org/COPYING.php -// -// Please report all bugs and problems on the following page: -// -// http://www.fltk.org/str.php -// - -/* \file - Fl_Gl_Window_Group widget . */ - -#ifndef Fl_Gl_Window_Group_H -#define Fl_Gl_Window_Group_H - -#include //#include "Fl_Gl_Window.H" -#include //#include "x.H" - -#define Fl_Gl_Window_Group xFl_Gl_Window_Group - -class Fl_Gl_Window_Group_INTERNAL; - -/** - The Fl_Gl_Window_Group widget is an extended form of Fl_Gl_Window that - can contain child widgets not specially modified to use OpenGL calls. - After the main OpenGL area is drawn, child widgets are each drawn into an - offscreen buffer (using the standard FLTK drawing routines), and then - copied into the OpenGL window using a textured quad. -*/ -class FL_EXPORT Fl_Gl_Window_Group : public Fl_Gl_Window { - - class Fl_Gl_Window_Group_INTERNAL *glstandin; - - Fl_Offscreen offscr; - int offscr_w, offscr_h; - uchar *imgbuf; - - unsigned int texid; - - void init(void); - void adjust_offscr(int w, int h); - -public: - - ~Fl_Gl_Window_Group(void); - - /** - Creates a new Fl_Gl_Window_Group widget using the given size and label string. - */ - Fl_Gl_Window_Group(int W, int H, const char *l=0) - : Fl_Gl_Window(W,H,l) {init();} - - /** - Creates a new Fl_Gl_Window_Group widget using the given position, - size, and label string. - */ - Fl_Gl_Window_Group(int X, int Y, int W, int H, const char *l=0) - : Fl_Gl_Window(X,Y,W,H,l) {init();} - - void show(void); - void hide(void); - void clear(void); - - void flush(void); - - /** - Handles the specified event. - - This method only receives events that were not used by any of the child - widgets. Unlike most handle() methods, this should not call the - inherited handle() method, or else an infinite loop will result. - */ - virtual int handle_gl(int event); - - // override resize - virtual void resize(int x, int y,int w, int h); - -protected: - - void draw(void); - void draw_children(void); - void draw_child(Fl_Widget& widget); - - /** - Draws the main OpenGL area of the Fl_Gl_Window_Group. - - You \e \b must override the draw_gl() method. - */ - virtual void draw_gl(void); -}; - -#endif - -// -// End of "$Id:$". -// diff --git a/src/fltk/xFl_Gl_Window_Group.cxx b/src/fltk/xFl_Gl_Window_Group.cxx deleted file mode 100644 index aa80bf0..0000000 --- a/src/fltk/xFl_Gl_Window_Group.cxx +++ /dev/null @@ -1,272 +0,0 @@ -// -// "$Id$" -// -// OpenGL window group widget for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2010 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// http://www.fltk.org/COPYING.php -// -// Please report all bugs and problems on the following page: -// -// http://www.fltk.org/str.php -// - -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#if 1 //HAVE_GL - -#if !defined(GL_TEXTURE_RECTANGLE) && defined(WIN32) -# define GL_TEXTURE_RECTANGLE 0x84F5 -#endif - -#define Gl_Stand_In Fl_Gl_Window_Group_INTERNAL - -#define RESET_FIELDS() \ - imgbuf = NULL; \ - offscr_w = -1; \ - offscr_h = -1 - -class Gl_Stand_In : public Fl_Box { - - Fl_Gl_Window_Group *glwg; - -public: - - Gl_Stand_In(int W, int H, Fl_Gl_Window_Group *w) - : Fl_Box(0, 0, W, H) { - glwg = w; - } - - int handle(int event) { return glwg->handle_gl(event); } - -protected: - - void draw(void) { Fl::fatal("Never call this"); } - - virtual void dummy(void); -}; - -void Gl_Stand_In::dummy(void) {} - -void Fl_Gl_Window_Group::init(void) { - begin(); // Revert the end() in the Fl_Gl_Window constructor - glstandin = new Gl_Stand_In(w(), h(), this); - texid = 0; - RESET_FIELDS(); -} - -Fl_Gl_Window_Group::~Fl_Gl_Window_Group(void) { - delete glstandin; -} - -void Fl_Gl_Window_Group::adjust_offscr(int w, int h) { - if (imgbuf == NULL) { - // Find maximum width and height across all visible child widgets - // (except for the GL stand-in widget) - Fl_Widget*const* a = array(); - for (int i = children(); i--;) { - Fl_Widget* o = a[i]; - if (o == glstandin) continue; - if (!o->visible()) continue; - int cw = o->w(); - int ch = o->h(); - if (offscr_w < cw) offscr_w = cw; - if (offscr_h < ch) offscr_h = ch; - } - } else { - fl_delete_offscreen(offscr); - } - - if (w > offscr_w) offscr_w = w; - if (h > offscr_h) offscr_h = h; - - offscr = fl_create_offscreen(offscr_w, offscr_h); - - int imgbuf_size = offscr_w * offscr_h * 3; // GL_RGB - imgbuf = (uchar *)realloc(imgbuf, (size_t)imgbuf_size); -} - -void Fl_Gl_Window_Group::show() { - Fl_Gl_Window::show(); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_RECTANGLE); - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glGenTextures(1, &texid); - glBindTexture(GL_TEXTURE_RECTANGLE, texid); - make_current(); -} - -void Fl_Gl_Window_Group::hide() { - glDeleteTextures(1, &texid); - texid = 0; - make_current(); - - Fl_Gl_Window::hide(); -} - -/** - Deletes all child widgets from memory recursively. - - This method differs from the remove() method in that it - affects all child widgets and deletes them from memory. -*/ -void Fl_Gl_Window_Group::clear(void) { - if (imgbuf != NULL) { - fl_delete_offscreen(offscr); - free(imgbuf); - RESET_FIELDS(); - } - remove(glstandin); - Fl_Gl_Window::clear(); - add(glstandin); -} - -int Fl_Gl_Window_Group::handle_gl(int event) { - // Override me - return 0; -} - -void Fl_Gl_Window_Group::resize(int x, int y,int w, int h) -{ - glstandin->resize(x,y,w,h); - Fl_Window::resize(x,y,w,h); -} - -void Fl_Gl_Window_Group::flush(void) { - // Fl_Window::make_current() does this, but not - // Fl_Gl_Window::make_current(), and we can't override make_current() - // and have Fl_Gl_Window::flush() call us - - Fl_Window::make_current(); - Fl_Gl_Window::make_current(); - - Fl_Gl_Window::flush(); -} - -void Fl_Gl_Window_Group::draw(void) { - if (damage()) { - draw_gl(); - draw_children(); - } -} - -/** - Draws all children of the group. -*/ -void Fl_Gl_Window_Group::draw_children(void) { - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glOrtho(0, w(), 0, h(), -1.0, 1.0); - glTranslatef(0.0, h(), 0.0); - glScalef(1.0, -1.0, 1.0); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glViewport(0, 0, w(), h()); - - Fl_Widget*const* a = array(); - for (int i = children(); i--;) draw_child(**a++); - -#if 1 - int err = glGetError(); - if (err != GL_NO_ERROR) { - Fl::warning("OpenGL error after drawing Fl_Gl_Window_Group children: 0x0%X", err); - } -#endif - - make_current(); -} - -/** - This draws a child widget, if it is not clipped. - The damage bits are cleared after drawing. -*/ -void Fl_Gl_Window_Group::draw_child(Fl_Widget& widget) { - if (&widget == glstandin) return; - - if (!widget.visible() || widget.type() >= FL_WINDOW || - !fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) return; - - if (widget.w() > offscr_w || widget.h() > offscr_h) { - adjust_offscr(widget.w(), widget.h()); - } - - int widget_x = widget.x(); - int widget_y = widget.y(); - int widget_w = widget.w(); - int widget_h = widget.h(); - - widget.position(0, 0); - - fl_begin_offscreen(offscr); - fl_rectf(0, 0, widget_w, widget_h, FL_MAGENTA); - widget.clear_damage(FL_DAMAGE_ALL); - widget.draw(); - widget.clear_damage(); - fl_read_image(imgbuf, 0, 0, widget_w, widget_h); - fl_end_offscreen(); - - widget.position(widget_x, widget_y); - -#ifdef USE_GLDRAWPIXELS // Note: glDrawPixels() is deprecated - - glRasterPos2i(widget_x, widget_y); - glPixelZoom(1.0, -1.0); - glDrawPixels(widget_w, widget_h, GL_RGB, GL_UNSIGNED_BYTE, imgbuf); - -#else // ! USE_GLDRAWPIXELS - - glTexImage2D( - GL_TEXTURE_RECTANGLE, - 0, - GL_RGB, - widget_w, widget_h, - 0, - GL_RGB, - GL_UNSIGNED_BYTE, - imgbuf); - -#define CORNER(x,y) glTexCoord2f(x, y); glVertex2f(widget_x + x, widget_y + y) - glBegin(GL_QUADS); - CORNER(0, 0); - CORNER(widget_w, 0); - CORNER(widget_w, widget_h); - CORNER(0, widget_h); - glEnd(); -#undef CORNER - -#endif // ! USE_GLDRAWPIXELS -} - -void Fl_Gl_Window_Group::draw_gl(void) { - Fl::fatal("Fl_Gl_Window_Group::draw_gl() *must* be overriden. Please refer to the documentation."); -} - -#else // ! HAVE_GL - -typedef int no_opengl_support; - -#endif // ! HAVE_GL - -// -// End of "$Id:$". -//