I am using FLTK 1.3.5 and I would like to use the Multiline_Input
object. I wonder if there is a way to automatically put a newline when the inserted text reaches the end of the input field, instead of doing it manually (check the uploaded images for an example). Moreover, the newline should be put at the end of a word. I searched here on SO and on the web, but I was not able to find anything useful.
Here it is the code used to generate the images above.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Multiline_Input.H>
int main(int argc, char **argv) {
Fl_Window *G_win = 0;
G_win = new Fl_Window(200,200,"Test multi input");
Fl_Multiline_Input* in;
in = new Fl_Multiline_Input(50,50,120,100," Test:");
G_win->end();
G_win->show(argc, argv);
return Fl::run();
}
Following Basile's suggestion, I investigated more on handling events and then I came up with a solution.
I derivated a class from the original Fl_Multiline_Input
which basically controls that the char[]
in Fl_Multiline_input->value()
does not overcome the maximum width given by the geometry (considering the current Fl_font
). Maybe it is not the best solution but, hey, it works! Of course, more performant/elegant strategies are more than welcome.
The code is down below.
#include "mymulti.hpp"
/*
This is needed for converting a std::string
to a char[] (required by Fl_Input). Again,
maybe more performant alternative are out there...
*/
char* str2char(std::string S){
char *out;
out = (char*) malloc ((S.size()+1)*sizeof(char));
strcpy(out,&S[0]);
out[S.size()] = '\0';
return out;
}
mymulti::mymulti(int x, int y, int h, int l):Fl_Multiline_Input(x, y, h,l)
{}
int mymulti::handle(int event)
{
switch (event) {
// When a key is pressed and the widget is waiting for input
case FL_KEYBOARD:
return handle_key(event, Fl::event_key());
default:
return Fl_Multiline_Input::handle(event);
};
}
int mymulti::handle_key(int event, int key) {
if (key==FL_BackSpace)
// Allowing Fl_Multiline_Input to handle the delection of characters
return Fl_Multiline_Input::handle(event);
else{
// Converting to std::string just because manipulation is easer
std::string s(this->value());
std::string s2;
/*
Search for the last newline char:
the subsequent substring must be shorter
than the width of the input field
*/
std::size_t found = s.find_last_of("\n");
if (found<std::string::npos)
s2= s.substr (found);
else
s2 = s;
/*
Mean length of a char (lower case)
under the current fl_font. One can add
uppercase letters and/or numbers and/or
other symbols.
*/
double lc = fl_width("abcdefghijklmnopqrstuvwxyz")/26;
// Maximum length for the substring
int string_length = this->w()/lc -1;
// if the substring is longer than the max allowed length, then add a newline
if (s2.length()>string_length)
s+="\n";
// Update the input field
this->value(str2char(s));
return Fl_Multiline_Input::handle(event);
}
}