Help_View: Improve target line management

This commit is contained in:
Matthias Melcher
2025-07-02 17:54:32 +02:00
parent a05ae33e20
commit e4d43a3951
2 changed files with 29 additions and 71 deletions
+8 -13
View File
@@ -32,6 +32,10 @@
#include "fl_draw.H" #include "fl_draw.H"
#include "filename.H" #include "filename.H"
#include <map>
#include <vector>
#include <string>
class Fl_Shared_Image; class Fl_Shared_Image;
// //
// Fl_Help_Func type - link callback function for files... // Fl_Help_Func type - link callback function for files...
@@ -122,12 +126,6 @@ protected:
Fl_Help_Font_Style elts_[MAX_FL_HELP_FS_ELTS]; ///< font elements Fl_Help_Font_Style elts_[MAX_FL_HELP_FS_ELTS]; ///< font elements
}; };
/** Fl_Help_Target structure */
struct Fl_Help_Target {
char name[32]; ///< Target name
int y; ///< Y offset of target
};
/** /**
The Fl_Help_View widget displays HTML text. Most HTML 2.0 The Fl_Help_View widget displays HTML text. Most HTML 2.0
@@ -221,9 +219,7 @@ class FL_EXPORT Fl_Help_View : public Fl_Group { // Help viewer widget
alinks_; ///< Allocated links alinks_; ///< Allocated links
Fl_Help_Link *links_; ///< Links Fl_Help_Link *links_; ///< Links
int ntargets_, ///< Number of targets std::map<std::string, int> target_line_map_; ///< Map of targets for fast access
atargets_; ///< Allocated targets
Fl_Help_Target *targets_; ///< Targets
// FIXME: do we really need this size? // FIXME: do we really need this size?
char directory_[2 * FL_PATH_MAX + 15]; ///< Directory for current file char directory_[2 * FL_PATH_MAX + 15]; ///< Directory for current file
@@ -261,10 +257,9 @@ class FL_EXPORT Fl_Help_View : public Fl_Group { // Help viewer widget
Fl_Help_Block *add_block(const char *s, int xx, int yy, int ww, int hh, uchar border = 0); Fl_Help_Block *add_block(const char *s, int xx, int yy, int ww, int hh, uchar border = 0);
void add_link(const char *n, int xx, int yy, int ww, int hh); void add_link(const char *n, int xx, int yy, int ww, int hh);
void add_target(const char *n, int yy); void add_target(const char *n, int yy);
static int compare_targets(const Fl_Help_Target *t0, const Fl_Help_Target *t1);
int do_align(Fl_Help_Block *block, int line, int xx, int a, int &l); int do_align(Fl_Help_Block *block, int line, int xx, int a, int &l);
protected: protected:
void draw() FL_OVERRIDE; void draw() override;
private: private:
void format(); void format();
void format_table(int *table_width, int *columns, const char *table); void format_table(int *table_width, int *columns, const char *table);
@@ -275,7 +270,7 @@ private:
Fl_Shared_Image *get_image(const char *name, int W, int H); Fl_Shared_Image *get_image(const char *name, int W, int H);
int get_length(const char *l); int get_length(const char *l);
public: public:
int handle(int) FL_OVERRIDE; int handle(int) override;
private: private:
void hv_draw(const char *t, int x, int y, int entity_extra_length = 0); void hv_draw(const char *t, int x, int y, int entity_extra_length = 0);
@@ -323,7 +318,7 @@ public:
*/ */
void link(Fl_Help_Func *fn) { link_ = fn; } void link(Fl_Help_Func *fn) { link_ = fn; }
int load(const char *f); int load(const char *f);
void resize(int,int,int,int) FL_OVERRIDE; void resize(int,int,int,int) override;
/** Gets the size of the help view. */ /** Gets the size of the help view. */
int size() const { return (size_); } int size() const { return (size_); }
void size(int W, int H) { Fl_Widget::size(W, H); } void size(int W, int H) { Fl_Widget::size(W, H); }
+21 -58
View File
@@ -84,6 +84,15 @@ static int quote_char(const char *);
static void scrollbar_callback(Fl_Widget *s, void *); static void scrollbar_callback(Fl_Widget *s, void *);
static void hscrollbar_callback(Fl_Widget *s, void *); static void hscrollbar_callback(Fl_Widget *s, void *);
static std::string to_lower(const std::string &str) {
std::string lower_str;
lower_str.reserve(str.size());
for (char c : str) {
lower_str += fl_tolower(c);
}
return lower_str;
}
// This function skips 'n' bytes *within* a string, i.e. it checks // This function skips 'n' bytes *within* a string, i.e. it checks
// for a NUL byte as string terminator. // for a NUL byte as string terminator.
// If a NUL byte is found before 'n' bytes have been scanned it returns // If a NUL byte is found before 'n' bytes have been scanned it returns
@@ -451,34 +460,10 @@ void Fl_Help_View::add_link(const char *n, // I - Name of link
void Fl_Help_View::add_target(const char *n, // I - Name of target void Fl_Help_View::add_target(const char *n, // I - Name of target
int yy) // I - Y position of target int yy) // I - Y position of target
{ {
Fl_Help_Target *temp; // New target std::string target = to_lower(n); // Convert target name to lower case
target_line_map_[target] = yy; // Store the target line in the map
if (ntargets_ >= atargets_)
{
atargets_ += 16;
if (atargets_ == 16)
targets_ = (Fl_Help_Target *)malloc(sizeof(Fl_Help_Target) * atargets_);
else
targets_ = (Fl_Help_Target *)realloc(targets_, sizeof(Fl_Help_Target) * atargets_);
}
temp = targets_ + ntargets_;
temp->y = yy;
strlcpy(temp->name, n, sizeof(temp->name));
ntargets_ ++;
} }
/** Compares two targets.*/
int // O - Result of comparison
Fl_Help_View::compare_targets(const Fl_Help_Target *t0, // I - First target
const Fl_Help_Target *t1) // I - Second target
{
return (strcasecmp(t0->name, t1->name));
}
/** Computes the alignment for a line in a block.*/ /** Computes the alignment for a line in a block.*/
int // O - New line int // O - New line
@@ -1261,7 +1246,7 @@ void Fl_Help_View::format() {
done = 1; done = 1;
nblocks_ = 0; nblocks_ = 0;
nlinks_ = 0; nlinks_ = 0;
ntargets_ = 0; target_line_map_.clear();
size_ = 0; size_ = 0;
bgcolor_ = color(); bgcolor_ = color();
textcolor_ = textcolor(); textcolor_ = textcolor();
@@ -1992,10 +1977,6 @@ void Fl_Help_View::format() {
// printf("margins.depth_=%d\n", margins.depth_); // printf("margins.depth_=%d\n", margins.depth_);
if (ntargets_ > 1)
qsort(targets_, ntargets_, sizeof(Fl_Help_Target),
(compare_func_t)compare_targets);
int dx = Fl::box_dw(b) - Fl::box_dx(b); int dx = Fl::box_dw(b) - Fl::box_dx(b);
int dy = Fl::box_dh(b) - Fl::box_dy(b); int dy = Fl::box_dh(b) - Fl::box_dy(b);
int ss = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size(); int ss = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
@@ -2556,14 +2537,7 @@ Fl_Help_View::free_data() {
nlinks_ = 0; nlinks_ = 0;
links_ = 0; links_ = 0;
} }
target_line_map_.clear();
if (ntargets_) {
free(targets_);
atargets_ = 0;
ntargets_ = 0;
targets_ = 0;
}
} // free_data() } // free_data()
/** Gets an alignment attribute. */ /** Gets an alignment attribute. */
@@ -3275,10 +3249,6 @@ Fl_Help_View::Fl_Help_View(int xx, // I - Left position
nlinks_ = 0; nlinks_ = 0;
links_ = (Fl_Help_Link *)0; links_ = (Fl_Help_Link *)0;
atargets_ = 0;
ntargets_ = 0;
targets_ = (Fl_Help_Target *)0;
directory_[0] = '\0'; directory_[0] = '\0';
filename_[0] = '\0'; filename_[0] = '\0';
@@ -3492,23 +3462,16 @@ Fl_Help_View::resize(int xx, // I - New left position
void void
Fl_Help_View::topline(const char *n) // I - Target name Fl_Help_View::topline(const char *n) // I - Target name
{ {
Fl_Help_Target key, // Target name key std::string target_name = to_lower(n); // Convert to lower case
*target; // Pointer to matching target auto tl = target_line_map_.find(target_name);
if (tl != target_line_map_.end()) {
// Found the target name, scroll to the line
if (ntargets_ == 0) topline(tl->second);
return; } else {
topline(0);
strlcpy(key.name, n, sizeof(key.name)); }
target = (Fl_Help_Target *)bsearch(&key, targets_, ntargets_, sizeof(Fl_Help_Target),
(compare_func_t)compare_targets);
if (target != NULL)
topline(target->y);
} }
/** Scrolls the text to the indicated position, given a pixel line. /** Scrolls the text to the indicated position, given a pixel line.
If the given pixel value \p top is out of range, then the text is If the given pixel value \p top is out of range, then the text is