FLUID: add drag'n'drop for images (#642)

FLUID dnd for desktop images into the design
Documentation for fl_access
This commit is contained in:
Matthias Melcher
2023-01-08 19:43:31 +01:00
committed by GitHub
parent 1324c623fe
commit 7d167b3cf1
2 changed files with 74 additions and 8 deletions
+66 -6
View File
@@ -37,6 +37,7 @@
#include <FL/platform.H> #include <FL/platform.H>
#include <FL/Fl_Menu_Item.H> #include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Round_Button.H> #include <FL/Fl_Round_Button.H>
#include <FL/Fl_Shared_Image.H>
#include "../src/flstring.h" #include "../src/flstring.h"
#include <math.h> #include <math.h>
@@ -1264,17 +1265,16 @@ int Fl_Window_Type::handle(int event) {
static Fl_Type* selection = NULL; static Fl_Type* selection = NULL;
switch (event) { switch (event) {
case FL_DND_ENTER: case FL_DND_ENTER:
Fl::belowmouse(o); // printf("DND enter\n");
case FL_DND_DRAG: case FL_DND_DRAG:
// printf("DND drag\n");
{ {
// find the innermost item clicked on: // find the innermost item clicked on:
selection = this; selection = this;
for (Fl_Type* i=next; i && i->level>level; i=i->next) for (Fl_Type* i=next; i && i->level>level; i=i->next)
if (i->is_group()) { if (i->is_group()) {
Fl_Widget_Type* myo = (Fl_Widget_Type*)i; Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent()) if (Fl::event_inside(myo->o) && myo->o->visible_r()) {
if (!o1->visible()) goto CONTINUE_DND;
if (Fl::event_inside(myo->o)) {
selection = myo; selection = myo;
if (Fl::event_clicks()==1) if (Fl::event_clicks()==1)
reveal_in_browser(myo); reveal_in_browser(myo);
@@ -1286,12 +1286,72 @@ int Fl_Window_Type::handle(int event) {
((Overlay_Window *)o)->redraw_overlay(); ((Overlay_Window *)o)->redraw_overlay();
} }
} }
Fl::belowmouse(o);
return 1;
case FL_DND_RELEASE: case FL_DND_RELEASE:
// printf("DND release\n");
Fl::belowmouse(o);
return 1; return 1;
case FL_PASTE: case FL_PASTE:
// printf("DND paste\n");
{ Fl_Type *prototype = typename_to_prototype(Fl::event_text()); { Fl_Type *prototype = typename_to_prototype(Fl::event_text());
if (prototype==NULL) if (prototype==NULL) {
return 0; // it's not a FLUID type, so it could be the filename of an image
const char *cfn = Fl::event_text();
// printf("DND is filename %s?\n", cfn);
if ((cfn == NULL) || (*cfn == 0)) return 0;
if (strlen(cfn) >= FL_PATH_MAX) return 0;
char fn[FL_PATH_MAX+1];
// some platform prepend "file://" or "computer://" or similar text
const char *sep = strstr(cfn, "://");
if (sep)
strcpy(fn, sep+3);
else
strcpy(fn, cfn);
// remove possibly trailing \r\n
int n = (int)strlen(fn)-1;
if (fn[n] == '\n') fn[n--] = 0;
if (fn[n] == '\r') fn[n--] = 0;
// on X11 and Wayland (?), filenames need to be decoded
#if (defined(FLTK_USE_X11) || defined(FLTK_USE_WAYLAND))
fl_decode_uri(fn);
#endif
// does a file by that name actually exist?
if (fl_access(fn, 4)==-1) return 0;
// but is this an image file?
Fl_Image *img = Fl_Shared_Image::get(fn);
if (!img || (img->ld() < 0)) return 0;
// ok, so it is an image - now add it as image() or deimage() to the widget
// printf("DND check for target %s\n", fn);
Fl_Widget_Type *tgt = NULL;
for (Fl_Type* i=next; i && i->level>level; i=i->next) {
if (i->is_widget()) {
Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
if (Fl::event_inside(myo->o) && myo->o->visible_r())
tgt = myo;
}
}
if (tgt) {
char rel[FL_PATH_MAX+1];
enter_project_dir();
fl_filename_relative(rel, FL_PATH_MAX, fn);
leave_project_dir();
// printf("DND image = %s\n", fn);
if (Fl::get_key(FL_Alt_L) || Fl::get_key(FL_Alt_R)) {
//if (Fl::event_alt()) { // TODO: X11/Wayland does not set the e_state on DND events
tgt->inactive_name(rel);
tgt->compress_deimage_ = 1;
tgt->bind_deimage_ = 0;
} else {
tgt->image_name(rel);
tgt->compress_image_ = 1;
tgt->bind_image_ = 0;
}
select_only(tgt);
tgt->open();
}
return 1;
}
in_this_only = this; in_this_only = this;
popupx = Fl::event_x(); popupx = Fl::event_x();
+8 -2
View File
@@ -449,8 +449,14 @@ int fl_chmod(const char* f, int mode) {
/** Cross-platform function to test a files access() with a UTF-8 encoded /** Cross-platform function to test a files access() with a UTF-8 encoded
name or value. name or value.
This function is especially useful on the Windows platform where the This function is especially useful on the Windows platform where the
standard access() function fails with UTF-8 encoded non-ASCII filenames. standard access() function fails with UTF-8 encoded non-ASCII filenames.
Windows defines the mode values 0 for existence, 2 for writable, 4 for
readable, and 6 of readable and writable. On other systems, the modes
`X_OK`, `W_OK`, and `R_OK` are usually defined as 1, 2, and 4.
Upon successful completion, the value 0 is returned on all platforms.
\param[in] f the UTF-8 encoded filename \param[in] f the UTF-8 encoded filename
\param[in] mode the mode to test \param[in] mode the mode to test