summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2025-07-02 17:54:32 +0200
committerMatthias Melcher <github@matthiasm.com>2025-07-02 17:54:43 +0200
commite4d43a395131a456ca36dbb58b541fddb7c281b2 (patch)
treecd3187aacb3a3d0d9f7dc90ebae003a8e9ac3404
parenta05ae33e20b09ab952ddbbf6762d5cfec77e4943 (diff)
Help_View: Improve target line management
-rw-r--r--FL/Fl_Help_View.H21
-rw-r--r--src/Fl_Help_View.cxx79
2 files changed, 29 insertions, 71 deletions
diff --git a/FL/Fl_Help_View.H b/FL/Fl_Help_View.H
index a544e366d..c647b77b9 100644
--- a/FL/Fl_Help_View.H
+++ b/FL/Fl_Help_View.H
@@ -32,6 +32,10 @@
#include "fl_draw.H"
#include "filename.H"
+#include <map>
+#include <vector>
+#include <string>
+
class Fl_Shared_Image;
//
// 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_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
@@ -221,9 +219,7 @@ class FL_EXPORT Fl_Help_View : public Fl_Group { // Help viewer widget
alinks_; ///< Allocated links
Fl_Help_Link *links_; ///< Links
- int ntargets_, ///< Number of targets
- atargets_; ///< Allocated targets
- Fl_Help_Target *targets_; ///< Targets
+ std::map<std::string, int> target_line_map_; ///< Map of targets for fast access
// FIXME: do we really need this size?
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);
void add_link(const char *n, int xx, int yy, int ww, int hh);
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);
protected:
- void draw() FL_OVERRIDE;
+ void draw() override;
private:
void format();
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);
int get_length(const char *l);
public:
- int handle(int) FL_OVERRIDE;
+ int handle(int) override;
private:
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; }
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. */
int size() const { return (size_); }
void size(int W, int H) { Fl_Widget::size(W, H); }
diff --git a/src/Fl_Help_View.cxx b/src/Fl_Help_View.cxx
index 572318def..de05675d8 100644
--- a/src/Fl_Help_View.cxx
+++ b/src/Fl_Help_View.cxx
@@ -84,6 +84,15 @@ static int quote_char(const char *);
static void scrollbar_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
// for a NUL byte as string terminator.
// 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
int yy) // I - Y position of target
{
- Fl_Help_Target *temp; // New target
-
-
- 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_ ++;
+ std::string target = to_lower(n); // Convert target name to lower case
+ target_line_map_[target] = yy; // Store the target line in the map
}
-/** 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.*/
int // O - New line
@@ -1261,7 +1246,7 @@ void Fl_Help_View::format() {
done = 1;
nblocks_ = 0;
nlinks_ = 0;
- ntargets_ = 0;
+ target_line_map_.clear();
size_ = 0;
bgcolor_ = color();
textcolor_ = textcolor();
@@ -1992,10 +1977,6 @@ void Fl_Help_View::format() {
// 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 dy = Fl::box_dh(b) - Fl::box_dy(b);
int ss = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
@@ -2556,14 +2537,7 @@ Fl_Help_View::free_data() {
nlinks_ = 0;
links_ = 0;
}
-
- if (ntargets_) {
- free(targets_);
-
- atargets_ = 0;
- ntargets_ = 0;
- targets_ = 0;
- }
+ target_line_map_.clear();
} // free_data()
/** Gets an alignment attribute. */
@@ -3275,10 +3249,6 @@ Fl_Help_View::Fl_Help_View(int xx, // I - Left position
nlinks_ = 0;
links_ = (Fl_Help_Link *)0;
- atargets_ = 0;
- ntargets_ = 0;
- targets_ = (Fl_Help_Target *)0;
-
directory_[0] = '\0';
filename_[0] = '\0';
@@ -3492,23 +3462,16 @@ Fl_Help_View::resize(int xx, // I - New left position
void
Fl_Help_View::topline(const char *n) // I - Target name
{
- Fl_Help_Target key, // Target name key
- *target; // Pointer to matching target
-
-
- if (ntargets_ == 0)
- return;
-
- 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);
+ std::string target_name = to_lower(n); // Convert to lower case
+ auto tl = target_line_map_.find(target_name);
+ if (tl != target_line_map_.end()) {
+ // Found the target name, scroll to the line
+ topline(tl->second);
+ } else {
+ topline(0);
+ }
}
-
/** 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