mirror of
https://github.com/fltk/fltk.git
synced 2026-05-20 04:31:25 +08:00
Help_View: Improve target line management
This commit is contained in:
+8
-13
@@ -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); }
|
||||
|
||||
+21
-58
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user