|
|
Στις Δευτέρα, 31 Μαΐου 2021 στις 11:17:48 μ.μ. UTC+3, ο χρήστης Ian MacArthur έγραψε:
What is it that you actually want to do?
Maybe there’s an easier way (because the Fl_Text_ family are pretty heavyweight, and can be complex to use...)
However, as far at styling goes for Fl_Text_Display and hence Fl_Text_Editor, basically the way it works is there are two “text” buffers associated with the output, one of which holds the actual text to be displayed, and the other holds the styling information.
These two buffers have to be maintained at "the same length”, such that each glyph in the text buffer has a corresponding style code in the style buffer.
The style codes are typically just codes used to index into the style table. They set face, size, colour, basically.
So... the usual way to change the style is to have the modify callback re-scan the text (e.g. when new text is typed, say) compute the new style state, update the style buffer and trigger a redraw.
But if you just want to re-style the text, all you need to do is change the content of the style buffer and trigger a redraw, which you can do directly from your button callback or wherever, or even programmatically if that suits.
You don't need to do it via the modify call-back at all, unless you are doing that anyway (e.g. as part of a styling text editor that needs to parse the input text to determine the style info.)
Hmm, there was a thread about this just recently, um... yes, ended up with this, though the preceding discussion is probably more useful!
https://groups.google.com/g/fltkgeneral/c/Lms9GP18Ou0/m/fzH_AmBZAQAJ
The final product will be e regular _expression_ matcher . There will be an input to search for a regular _expression_ and then a button that will trigger a callback that will search for any matches in the text and it will height them. For the beginning I just want to have a button that will highlight the digits (as the original texteditor-with-dynamic-colors example) when I press it. I don't want it to trigger automatically when I modify the text. I suppose the highlight_data function does this work but I'm not able to call it outside a class so I cannot call it from the button callback. Probably I don't know some things about C++ and that's why I can't make it work. I will send you the code I'm having and maybe you can help if you want and you have free time of course.
Code: #include <FL/Fl.H> #include <FL/Fl_Button.H> #include <FL/Fl_Group.H> #include <FL/Fl_Input.H> #include <FL/Fl_Text_Editor.H> #include <FL/Fl_Window.H>
// Custom class to demonstrate a specialized text editor class MyEditor : public Fl_Text_Editor { Fl_Text_Buffer *tbuff; // text buffer Fl_Text_Buffer *sbuff; // style buffer
friend void match_cb(Fl_Widget* w, void* e);
// Modify callback handler void ModifyCallback(int pos, // position of update int nInserted, // number of inserted chars int nDeleted, // number of deleted chars int, // number of restyled chars (unused here) const char*) { // text deleted (unused here)
// Nothing inserted or deleted? if (nInserted == 0 && nDeleted == 0) return;
// Characters inserted into tbuff? // Insert same number of chars into style buffer.. // if (nInserted > 0) { char *style = new char[nInserted + 1]; // temp buffer memset(style, 'A', nInserted); // init style to "A"s style[nInserted] = '\0'; // terminate string sbuff->insert(pos, style); // insert "A"s into style buffer delete[] style; // done with temp buffer.. }
// Characters deleted from tbuff? // Delete same number of chars from style buffer.. // if ( nDeleted > 0 ) { sbuff->remove(pos, pos + nDeleted); return; // nothing more to do; deleting won't affect our single char coloring }
// Focus on characters inserted int start = pos; int end = pos + nInserted; //DEBUG fprintf(stderr, "add_modify_callback(): start/end=%d/%d, text='%.*s'\n", start, end, (end-start), tbuff->address(start));
// SIMPLE EXAMPLE: // Color the digits 0-4 in green, 5-9 in red. // for ( int i=start; i<end; i++ ) { unsigned int c = tbuff->char_at(i); if ( strchr("01234", c) ) sbuff->replace(i, i+1, "B"); // style 'B' (green) else if ( strchr("56789", c) ) sbuff->replace(i, i+1, "C"); // style 'C' (red) else sbuff->replace(i, i+1, "A"); // style 'A' (black) } }
static void ModifyCallback_STATIC(int pos, // position of update int nInserted, // number of inserted chars int nDeleted, // number of deleted chars int nRestyled, // number of restyled chars const char *deletedText, // text deleted void *cbarg) { // callback data MyEditor *med = (MyEditor*)cbarg; med->ModifyCallback(pos, nInserted, nDeleted, nRestyled, deletedText); }
public: MyEditor(int X,int Y,int W,int H) : Fl_Text_Editor(X,Y,W,H) { // Style table for the respective styles static const Fl_Text_Editor::Style_Table_Entry stable[] = { // FONT COLOR FONT FACE FONT SIZE // --------------- ----------- -------------- { FL_BLACK, FL_COURIER, 14 }, // A - Black { FL_DARK_GREEN, FL_COURIER, 14 }, // B - Green { FL_RED, FL_COURIER, 14 }, // C - Red }; tbuff = new Fl_Text_Buffer(); // text buffer sbuff = new Fl_Text_Buffer(); // style buffer buffer(tbuff); int stable_size = sizeof(stable)/sizeof(stable[0]); highlight_data(sbuff, stable, stable_size, 'A', 0, 0); }
void text(const char* val) { tbuff->text(val); } };
MyEditor *edit;
void match_cb(Fl_Widget *w, void *data) { // Code there }
int main() { Fl::scheme("gtk+");
// Windows Fl_Window *win = new Fl_Window(720, 480, "Text Editor With Dynamic Coloring");
// Text buffer edit = new MyEditor(10, 70, win->w()-20,win->h()-80); edit->text("In this editor, digits 0-4 are shown in green, 5-9 shown in red.\n" "So here's some numbers 0123456789.\n" "Coloring is handled automatically by the add_modify_callback().\n" "\n" "You can type here to test. ");
// Create the group for the input and the button Fl_Group *group = new Fl_Group(10, 10, 550, 35); Fl_Input *input = new Fl_Input(10, 10, 400, 35); Fl_Button *button = new Fl_Button(420, 10, 95, 35, "Search"); button->callback(match_cb); button->labelsize(25); group->end(); group->resizable(input); // Set the "input" to be resizable
win->resizable(*edit); // Set the editor to be resizable win->size_range(300, 400); // Set the default window size win->show(); return(Fl::run()); }
So yeah I want to make the match_cb callback call the highlight_data function so it changes the color when I press it. Ignore the input widget for now.
--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/b6caa6f7-a1ac-48c0-bb2d-2d6c4250d523n%40googlegroups.com.
[ Direct Link to Message ] | |
|
| |