From ccaaa1eb03919cc6efce813447535fb4a595a092 Mon Sep 17 00:00:00 2001 From: Stelios Bounanos Date: Tue, 16 Feb 2010 19:14:36 +0000 Subject: [PATCH] Add RX text scrollbar hints * Add an Fl_Scrollbar subclass that can remember scroll values and draw them on the slider background * Mark the scrollbar position when entering a clickable frequency marker or logging a QSO --- src/dialogs/fl_digi.cxx | 2 + src/include/FTextRXTX.h | 2 + src/include/FTextView.h | 2 +- src/widgets/FTextRXTX.cxx | 86 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index cc34e46f..278d9adb 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -1737,6 +1737,7 @@ void qsoSave_cb(Fl_Widget *b, void *) submit_log(); if (progdefaults.ClearOnSave) clearQSO(); + ReceiveText->mark(FTextBase::XMIT); restoreFocus(); } @@ -4779,6 +4780,7 @@ void note_qrg(bool no_dup, const char* prefix, const char* suffix, trx_mode mode if (prefix && *prefix) ReceiveText->add(prefix); ReceiveText->add(buf, FTextBase::QSY); + ReceiveText->mark(); if (suffix && *suffix) ReceiveText->add(suffix); } diff --git a/src/include/FTextRXTX.h b/src/include/FTextRXTX.h index 5e45e909..47304b9c 100644 --- a/src/include/FTextRXTX.h +++ b/src/include/FTextRXTX.h @@ -16,6 +16,8 @@ public: void set_quick_entry(bool b); bool get_quick_entry(void) { return quick_entry; } + void mark(FTextBase::TEXT_ATTR attr = CLICK_START); + void clear(void); void setFont(Fl_Font f, int attr = NATTR); diff --git a/src/include/FTextView.h b/src/include/FTextView.h index 874c37ab..c19271af 100644 --- a/src/include/FTextView.h +++ b/src/include/FTextView.h @@ -57,7 +57,7 @@ public: virtual int handle(int event); virtual void handle_context_menu(void) { } - void clear(void) { tbuf->text(""); sbuf->text(""); } + virtual void clear(void) { tbuf->text(""); sbuf->text(""); } void set_word_wrap(bool b); bool get_word_wrap(void) { return wrap; } diff --git a/src/widgets/FTextRXTX.cxx b/src/widgets/FTextRXTX.cxx index 54325757..f1554d4a 100644 --- a/src/widgets/FTextRXTX.cxx +++ b/src/widgets/FTextRXTX.cxx @@ -69,6 +69,29 @@ using namespace std; + +// Fl_Scrollbar wrapper to draw marks on the slider background. +// Currently only implemented for a vertical scrollbar. +class MVScrollbar : public Fl_Scrollbar +{ + struct mark_t { + double pos; + Fl_Color color; + mark_t(double pos_, Fl_Color color_) : pos(pos_), color(color_) { } + }; + +public: + MVScrollbar(int X, int Y, int W, int H, const char* l = 0) + : Fl_Scrollbar(X, Y, W, H, l) { } + + void draw(void); + void mark(Fl_Color c) { marks.push_back(mark_t(maximum() - 1.0, c)); } + void clear(void) { marks.clear(); } + +private: + vector marks; +}; + static void show_font_warning(FTextBase* w); Fl_Menu_Item FTextRX::menu[] = { @@ -111,6 +134,14 @@ FTextRX::FTextRX(int x, int y, int w, int h, const char *l) context_menu = menu; init_context_menu(); menu[RX_MENU_QUICK_ENTRY].clear(); + + // Replace the scrollbar widget + MVScrollbar* mvsb = new MVScrollbar(mVScrollBar->x(), mVScrollBar->y(), + mVScrollBar->w(), mVScrollBar->h(), NULL); + mvsb->callback(mVScrollBar->callback(), mVScrollBar->user_data()); + remove(mVScrollBar); + delete mVScrollBar; + Fl_Group::add(mVScrollBar = mvsb); } FTextRX::~FTextRX() @@ -210,6 +241,19 @@ void FTextRX::set_quick_entry(bool b) menu[RX_MENU_QUICK_ENTRY].clear(); } +void FTextRX::mark(FTextBase::TEXT_ATTR attr) +{ + if (attr == NATTR) + attr = CLICK_START; + static_cast(mVScrollBar)->mark(styles[attr].color); +} + +void FTextRX::clear(void) +{ + FTextBase::clear(); + static_cast(mVScrollBar)->clear(); +} + void FTextRX::setFont(Fl_Font f, int attr) { FTextBase::setFont(f, attr); @@ -1050,3 +1094,45 @@ static void show_font_warning(FTextBase* w) *warn = false; } } + + +// ---------------------------------------------------------------------------- + + +void MVScrollbar::draw(void) +{ + Fl_Scrollbar::draw(); + + if (marks.empty()) + return; + + assert((type() & FL_HOR_SLIDER) == 0); + + // Calculate the slider knob position and height. For a vertical scrollbar, + // the scroll buttons' height is the scrollbar width and the minimum knob + // height is half that. + int H = h() - Fl::box_dh(box()) - 2 * w(); // internal height (minus buttons) + int slider_h = (int)(slider_size() * H + 0.5); + int min_h = (w() - Fl::box_dw(box())) / 2 + 1; + if (slider_h < min_h) + slider_h = min_h; + double val = (Fl_Slider::value() - minimum()) / (maximum() - minimum()); + int slider_y = (int)(val * (H - slider_h) + 0.5) + w(); // relative to y() + // This would draw a green rectangle around the slider knob: + // fl_color(FL_GREEN); + // fl_rect(x(), y() + slider_y, w() - Fl::box_dw(box()), slider_h); + + int x1 = x() + Fl::box_dx(box()), x2 = x1 + w() - Fl::box_dw(box()) - 1, ypos; + // Convert stored scrollbar values to vertical positions and draw + // lines inside the widget if they don't overlap with the knob area. + for (vector::const_iterator i = marks.begin(); i != marks.end(); ++i) { + ypos = w() + H * i->pos / maximum(); + // Don't draw over slider knob + if ((ypos > slider_y && ypos < slider_y + slider_h) || + (ypos < slider_y + slider_h && ypos > slider_y)) + continue; + ypos += y(); + fl_color(i->color); + fl_line(x1, ypos, x2, ypos); + } +}