diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 2005-03-20 17:41:56 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2005-03-20 17:41:56 +0000 |
| commit | 0bc98fd29efa40f4828813fd490c2afe6e2e7c4f (patch) | |
| tree | 73a27040211c17adb95b79f5ba3510714de570f9 | |
| parent | 4e965380bc872a5da745d64a5d9deb901fa2979c (diff) | |
Preliminary template save support in FLUID, plus some bug fixes.
fluid/Fl_Type.h:
- Added read_image() declaration to Fl_Window_Type class.
fluid/Fl_Window_Type.cxx:
- Added Overlay_Window::read_image() and
Fl_Window_Type::read_image() functions.
- Fl_Window_Type::fix_overlay(): update menu indices.
- toggle_overlays(): update menu indices.
fluid/fluid.cxx:
- save_template_cb(): Added to save to
~/.fltk/fltk.org/fluid/templates, along with PNG screenshot
of first window.
- "Save To" instead of "Save to".
- Use fl_alert() for errors, not fl_message().
- Add "File/Save Template..." and "File/Print..." (not yet
implemented) menu items.
- toggle_widgetbin_cb(): update menu indices.
fluid/undo.cxx:
- Update menu item indices.
- Don't need extra slash in undo checkpoint filename.
src/Fl_PNG_Image.cxx:
- Fix typo in #endif comment.
src/Fl_Window.cxx:
- Fl_Window::draw(): save/restore flags() when changing label.
- Fl_Window::iconlabel(): save/restore flags() when changing label.
src/fl_rect.cxx:
- fl_not_clipped(): don't use current window for gross clipping.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4147 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | CHANGES | 5 | ||||
| -rw-r--r-- | fluid/Fl_Type.h | 3 | ||||
| -rw-r--r-- | fluid/Fl_Window_Type.cxx | 47 | ||||
| -rw-r--r-- | fluid/fluid.cxx | 127 | ||||
| -rw-r--r-- | fluid/undo.cxx | 6 | ||||
| -rw-r--r-- | src/Fl_PNG_Image.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_Window.cxx | 8 | ||||
| -rw-r--r-- | src/fl_rect.cxx | 8 |
8 files changed, 187 insertions, 19 deletions
@@ -2,6 +2,11 @@ CHANGES IN FLTK 1.1.7 - Documentation fixes (STR #648, STR #692, STR #730, STR #744, STR #745) + - fl_not_clipped() incorrectly used the current window + dimensions for gross clipping, which interfered with + off-screen rendering. + - Fl_Window::draw() and Fl_Window::iconlabel() could leak + memory if copy_label() was used on the window. - fl_shortcut_label() now shows letter shortcuts in uppercase, e.g. "Ctrl+N" instead of "Ctrl+n" to be consistent with other toolkits. diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h index 535c4a88f..03f7ed3d5 100644 --- a/fluid/Fl_Type.h +++ b/fluid/Fl_Type.h @@ -470,7 +470,8 @@ public: void open(); - void fix_overlay(); // update the bounding box, etc + void fix_overlay(); // Update the bounding box, etc + uchar *read_image(int &ww, int &hh); // Read an image of the window virtual void write_properties(); virtual void read_property(const char *); diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index 31cc08601..9f2702b54 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -31,6 +31,7 @@ #include <FL/Fl_Overlay_Window.H> #include <FL/fl_message.H> #include <FL/fl_draw.H> +#include <FL/x.H> #include <FL/Fl_Menu_Item.H> #include "Fl_Widget_Type.h" #include "undo.h" @@ -247,6 +248,7 @@ public: int handle(int); Overlay_Window(int W,int H) : Fl_Overlay_Window(W,H) {Fl_Group::current(0);} void resize(int,int,int,int); + uchar *read_image(int &ww, int &hh); }; void Overlay_Window::draw() { const int CHECKSIZE = 8; @@ -264,6 +266,36 @@ void Overlay_Window::draw() { Fl_Overlay_Window::draw(); } +extern Fl_Window *main_window; + +// Read an image of the overlay window +uchar *Overlay_Window::read_image(int &ww, int &hh) { + // Create an off-screen buffer for the window... + main_window->make_current(); + + ww = w(); + hh = h(); + + Fl_Offscreen offscreen = fl_create_offscreen(ww, hh); + uchar *pixels; + + // Redraw the window into the offscreen buffer... + fl_begin_offscreen(offscreen); + + redraw(); + draw(); + + // Read the screen image... + pixels = fl_read_image(0, 0, 0, ww, hh); + + fl_end_offscreen(); + + // Cleanup and return... + fl_delete_offscreen(offscreen); + + return pixels; +} + void Overlay_Window::draw_overlay() { window->draw_overlay(); } @@ -341,6 +373,15 @@ void Fl_Window_Type::open() { w->size_range(gridx, gridy, Fl::w(), Fl::h(), gridx, gridy, 0); } +// Read an image of the window +uchar *Fl_Window_Type::read_image(int &ww, int &hh) { + Overlay_Window *w = (Overlay_Window *)o; + + // Read the screen image... + return (w->read_image(ww, hh)); +} + + // control panel items: void modal_cb(Fl_Light_Button* i, void* v) { @@ -932,7 +973,7 @@ extern Fl_Menu_Item Main_Menu[]; // Calculate new bounding box of selected widgets: void Fl_Window_Type::fix_overlay() { - Main_Menu[38].label("Hide O&verlays"); + Main_Menu[40].label("Hide O&verlays"); overlays_invisible = 0; recalc = 1; ((Overlay_Window *)(this->o))->redraw_overlay(); @@ -947,8 +988,8 @@ void redraw_overlays() { void toggle_overlays(Fl_Widget *,void *) { overlays_invisible = !overlays_invisible; - if (overlays_invisible) Main_Menu[38].label("Show O&verlays"); - else Main_Menu[38].label("Hide O&verlays"); + if (overlays_invisible) Main_Menu[40].label("Show O&verlays"); + else Main_Menu[40].label("Hide O&verlays"); for (Fl_Type *o=Fl_Type::first; o; o=o->next) if (o->is_window()) { diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx index 6cd47e5df..b4fb4907f 100644 --- a/fluid/fluid.cxx +++ b/fluid/fluid.cxx @@ -40,6 +40,7 @@ #include <stdio.h> #include <stdlib.h> #include <errno.h> +#include <sys/stat.h> #include "../src/flstring.h" #include "alignment_panel.h" @@ -61,6 +62,18 @@ #include "Fl_Type.h" +extern "C" +{ +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) +# include <zlib.h> +# ifdef HAVE_PNG_H +# include <png.h> +# else +# include <libpng/png.h> +# endif // HAVE_PNG_H +#endif // HAVE_LIBPNG && HAVE_LIBZ +} + static Fl_Help_Dialog *help_dialog = 0; Fl_Preferences fluid_prefs(Fl_Preferences::USER, "fltk.org", "fluid"); @@ -145,12 +158,11 @@ void save_cb(Fl_Widget *, void *v) { const char *c = filename; if (v || !c || !*c) { fl_ok = "Save"; - c=fl_file_chooser("Save to:", "FLUID Files (*.f[ld])", c); + c=fl_file_chooser("Save To:", "FLUID Files (*.f[ld])", c); fl_ok = "OK"; if (!c) return; - if (!access(c, 0)) - { + if (!access(c, 0)) { const char *basename; if ((basename = strrchr(c, '/')) != NULL) basename ++; @@ -169,13 +181,112 @@ void save_cb(Fl_Widget *, void *v) { set_filename(c); } if (!write_file(c)) { - fl_message("Error writing %s: %s", c, strerror(errno)); + fl_alert("Error writing %s: %s", c, strerror(errno)); return; } set_modflag(0); undo_save = undo_current; } +void save_template_cb(Fl_Widget *, void *) { + const char *c = fl_input("Template Name:"); + if (!c) return; + + char filename[1024]; + fluid_prefs.getUserdataPath(filename, sizeof(filename)); + + strlcat(filename, "templates", sizeof(filename)); + if (access(filename, 0)) mkdir(filename, 0777); + + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, c, sizeof(filename)); + + char *ext = filename + strlen(filename); + if (ext >= (filename + sizeof(filename) - 5)) { + fl_alert("The template name \"%s\" is too long!", c); + return; + } + + strcpy(ext, ".fl"); + +// printf("save_template_cb: template filename=\"%s\"\n", filename); + + if (!access(filename, 0)) { + if (fl_choice("The template \"%s\" already exists.\n" + "Do you want to replace it?", "Cancel", + "Replace", NULL, c) == 0) return; + } + + if (!write_file(filename)) { + fl_alert("Error writing %s: %s", filename, strerror(errno)); + return; + } + +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) + // Get the screenshot, if any... + Fl_Type *t; + + for (t = Fl_Type::first; t; t = t->next) { + // Find the first window... + if (t->is_window()) break; + } + + if (!t) return; + + // Grab a screenshot... + Fl_Window_Type *wt = (Fl_Window_Type *)t; + uchar *pixels; + int w, h; + + if ((pixels = wt->read_image(w, h)) == NULL) return; + +// printf("save_template_cb: pixels=%p, w=%d, h=%d...\n", pixels, w, h); + + // Save to a PNG file... + strcpy(ext, ".png"); + +// printf("save_template_cb: screenshot filename=\"%s\"\n", filename); + + FILE *fp; + + if ((fp = fopen(filename, "wb")) == NULL) { + delete[] pixels; + fl_alert("Error writing %s: %s", filename, strerror(errno)); + return; + } + + png_structp pptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + png_infop iptr = png_create_info_struct(pptr); + png_bytep ptr = (png_bytep)pixels; + + png_init_io(pptr, fp); + png_set_IHDR(pptr, iptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_sRGB(pptr, iptr, PNG_sRGB_INTENT_PERCEPTUAL); + + png_write_info(pptr, iptr); + + for (int i = h; i > 0; i --, ptr += w * 3) { + png_write_row(pptr, ptr); + } + + png_write_end(pptr, iptr); + png_destroy_write_struct(&pptr, &iptr); + + fclose(fp); + +# if 0 // The original PPM output code... + strcpy(ext, ".ppm"); + fp = fopen(filename, "wb"); + fprintf(fp, "P6\n%d %d 255\n", w, h); + fwrite(pixels, w * h, 3, fp); + fclose(fp); +# endif // 0 + + delete[] pixels; +#endif // HAVE_LIBPNG && HAVE_LIBZ +} + void exit_cb(Fl_Widget *,void *) { if (modflag) switch (fl_choice("Do you want to save changes to this user\n" @@ -607,7 +718,7 @@ Fl_Menu_Item Main_Menu[] = { {"&File",0,0,0,FL_SUBMENU}, {"&New", FL_CTRL+'n', new_cb, 0}, {"&Open...", FL_CTRL+'o', open_cb, 0}, - {"Open &Previous",0,0,0,FL_SUBMENU}, + {"Open Pre&vious",0,0,0,FL_SUBMENU}, {relative_history[0], FL_CTRL+'0', open_history_cb, absolute_history[0]}, {relative_history[1], FL_CTRL+'1', open_history_cb, absolute_history[1]}, {relative_history[2], FL_CTRL+'2', open_history_cb, absolute_history[2]}, @@ -622,6 +733,8 @@ Fl_Menu_Item Main_Menu[] = { {"&Insert...", FL_CTRL+'i', open_cb, (void*)1, FL_MENU_DIVIDER}, {"&Save", FL_CTRL+'s', save_cb, 0}, {"Save &As...", FL_CTRL+FL_SHIFT+'s', save_cb, (void*)1}, + {"Save &Template...", 0, save_template_cb, (void*)2, FL_MENU_DIVIDER}, + {"&Print...", FL_CTRL+'p', 0}, {"Write &Code...", FL_CTRL+FL_SHIFT+'c', write_cb, 0}, {"&Write Strings...", FL_CTRL+FL_SHIFT+'w', write_strings_cb, 0, FL_MENU_DIVIDER}, {"&Quit", FL_CTRL+'q', exit_cb}, @@ -721,10 +834,10 @@ void toggle_widgetbin_cb(Fl_Widget *, void *) { if (widgetbin_panel->visible()) { widgetbin_panel->hide(); - Main_Menu[39].label("Show Widget &Bin..."); + Main_Menu[41].label("Show Widget &Bin..."); } else { widgetbin_panel->show(); - Main_Menu[39].label("Hide Widget &Bin"); + Main_Menu[41].label("Hide Widget &Bin"); } } diff --git a/fluid/undo.cxx b/fluid/undo.cxx index 9aae0ac08..1982ffa7e 100644 --- a/fluid/undo.cxx +++ b/fluid/undo.cxx @@ -41,8 +41,8 @@ extern Fl_Preferences fluid_prefs; // FLUID preferences extern Fl_Menu_Item Main_Menu[]; // Main menu -#define UNDO_ITEM 23 // Undo menu item index -#define REDO_ITEM 24 // Redo menu item index +#define UNDO_ITEM 25 // Undo menu item index +#define REDO_ITEM 26 // Redo menu item index // @@ -67,7 +67,7 @@ static char *undo_filename(int level, char *buf, int bufsize) { if (!undo_path[0]) fluid_prefs.getUserdataPath(undo_path, sizeof(undo_path)); - snprintf(buf, bufsize, "%s/undo_%d_%d.fl", undo_path, getpid(), level); + snprintf(buf, bufsize, "%sundo_%d_%d.fl", undo_path, getpid(), level); return buf; } diff --git a/src/Fl_PNG_Image.cxx b/src/Fl_PNG_Image.cxx index d07a37dfd..3aa76e4b5 100644 --- a/src/Fl_PNG_Image.cxx +++ b/src/Fl_PNG_Image.cxx @@ -47,7 +47,7 @@ extern "C" # else # include <libpng/png.h> # endif // HAVE_PNG_H -#endif // HAVE_LIBPNG ** HAVE_LIBZ +#endif // HAVE_LIBPNG && HAVE_LIBZ } diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx index 414074138..f8fb10253 100644 --- a/src/Fl_Window.cxx +++ b/src/Fl_Window.cxx @@ -92,6 +92,7 @@ int Fl_Window::y_root() const { void Fl_Window::draw() { const char *savelabel = label(); + uchar saveflags = flags(); int savex = x(); x(0); int savey = y(); y(0); // Make sure we don't draw the window title in the window background... @@ -99,13 +100,18 @@ void Fl_Window::draw() { Fl_Group::draw(); // Restore the label... Fl_Widget::label(savelabel); + set_flag(saveflags); y(savey); x(savex); } void Fl_Window::label(const char *name) {label(name, iconlabel());} -void Fl_Window::iconlabel(const char *iname) {label(label(), iname);} +void Fl_Window::iconlabel(const char *iname) { + uchar saveflags = flags(); + label(label(), iname); + set_flag(saveflags); +} // the Fl::atclose pointer is provided for back compatability. You // can now just change the callback for the window instead. diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx index 272c45332..a1c06f3b6 100644 --- a/src/fl_rect.cxx +++ b/src/fl_rect.cxx @@ -29,6 +29,7 @@ // that minimal update works. #include <config.h> +#include <FL/Fl.H> #include <FL/Fl_Widget.H> #include <FL/fl_draw.H> #include <FL/x.H> @@ -534,12 +535,14 @@ void fl_push_clip(int x, int y, int w, int h) { #endif } if (rstackptr < STACK_MAX) rstack[++rstackptr] = r; + else Fl::warning("fl_push_clip: clip stack overflow!\n"); fl_restore_clip(); } // make there be no clip (used by fl_begin_offscreen() only!) void fl_push_no_clip() { if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0; + else Fl::warning("fl_push_no_clip: clip stack overflow!\n"); fl_restore_clip(); } @@ -548,14 +551,13 @@ void fl_pop_clip() { if (rstackptr > 0) { Fl_Region oldr = rstack[rstackptr--]; if (oldr) XDestroyRegion(oldr); - } + } else Fl::warning("fl_pop_clip: clip stack underflow!\n"); fl_restore_clip(); } // does this rectangle intersect current clip? int fl_not_clipped(int x, int y, int w, int h) { - if (x+w <= 0 || y+h <= 0 || x > Fl_Window::current()->w() - || y > Fl_Window::current()->h()) return 0; + if (x+w <= 0 || y+h <= 0) return 0; Fl_Region r = rstack[rstackptr]; #ifdef WIN32 if (!r) return 1; |
