Skip to content

Commit

Permalink
Visual highlighting of the selected text in FTextView
Browse files Browse the repository at this point in the history
  • Loading branch information
gansm committed Mar 26, 2024
1 parent 45fea88 commit 8d547c2
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 12 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2023-03-26 Markus Gans <guru.mail@muenster.de>
* Visual highlighting of the selected text in FTextView

2023-03-25 Markus Gans <guru.mail@muenster.de>
* FTextView gets the ability to select text between a start and
end position
Expand Down
10 changes: 10 additions & 0 deletions doc/user-theme.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ class BeeColorTheme final : public finalcut::FWidgetColors
finalcut::FColor::Blue // Emphasis foreground
};
text =
{
finalcut::FColor::Black, // Foreground
finalcut::FColor::LightGray, // Background
finalcut::FColor::White, // Selected foreground
finalcut::FColor::Blue, // Selected background
finalcut::FColor::White, // Selected focused foreground
finalcut::FColor::Cyan // Selected focused background
};
error_box =
{
finalcut::FColor::Black, // Foreground
Expand Down
56 changes: 56 additions & 0 deletions final/fwidgetcolors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void default8ColorTheme::setColorTheme()
{
setTermColors();
setDialogColors();
setTextColors();
setErrorBoxColors();
setTooltipColors();
setShadowColors();
Expand Down Expand Up @@ -97,6 +98,19 @@ inline void default8ColorTheme::setDialogColors()
};
}

inline void default8ColorTheme::setTextColors()
{
text =
{
FColor::Black, // Foreground
FColor::LightGray, // Background
FColor::LightGray, // Selected foreground
FColor::Black, // Selected background
FColor::LightGray, // Selected focused foreground
FColor::Blue // Selected focused background
};
}

inline void default8ColorTheme::setErrorBoxColors()
{
error_box =
Expand Down Expand Up @@ -297,6 +311,7 @@ void default16ColorTheme::setColorTheme()
{
setTermColors();
setDialogColors();
setTextColors();
setErrorBoxColors();
setTooltipColors();
setShadowColors();
Expand Down Expand Up @@ -339,6 +354,19 @@ inline void default16ColorTheme::setDialogColors()
};
}

inline void default16ColorTheme::setTextColors()
{
text =
{
FColor::Black, // Foreground
FColor::White, // Background
FColor::White, // Selected foreground
FColor::DarkGray, // Selected background
FColor::White, // Selected focused foreground
FColor::Blue // Selected focused background
};
}

inline void default16ColorTheme::setErrorBoxColors()
{
error_box =
Expand Down Expand Up @@ -539,6 +567,7 @@ void default8ColorDarkTheme::setColorTheme()
{
setTermColors();
setDialogColors();
setTextColors();
setErrorBoxColors();
setTooltipColors();
setShadowColors();
Expand Down Expand Up @@ -577,6 +606,19 @@ inline void default8ColorDarkTheme::setDialogColors()
};
}

inline void default8ColorDarkTheme::setTextColors()
{
text =
{
FColor::Black, // Foreground
FColor::LightGray, // Background
FColor::LightGray, // Selected foreground
FColor::Black, // Selected background
FColor::LightGray, // Selected focused foreground
FColor::Blue // Selected focused background
};
}

inline void default8ColorDarkTheme::setErrorBoxColors()
{
error_box =
Expand Down Expand Up @@ -777,6 +819,7 @@ void default16ColorDarkTheme::setColorTheme()
{
setTermColors();
setDialogColors();
setTextColors();
setErrorBoxColors();
setTooltipColors();
setShadowColors();
Expand Down Expand Up @@ -815,6 +858,19 @@ inline void default16ColorDarkTheme::setDialogColors()
};
}

inline void default16ColorDarkTheme::setTextColors()
{
text =
{
FColor::Black, // Foreground
FColor::LightGray, // Background
FColor::LightGray, // Selected foreground
FColor::DarkGray, // Selected background
FColor::LightGray, // Selected focused foreground
FColor::Blue // Selected focused background
};
}

inline void default16ColorDarkTheme::setErrorBoxColors()
{
error_box =
Expand Down
15 changes: 15 additions & 0 deletions final/fwidgetcolors.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ class FWidgetColors
FColor emphasis_fg{FColor::Default};
};

struct TextColors
{
FColor fg{FColor::Default};
FColor bg{FColor::Default};
FColor selected_fg{FColor::Default};
FColor selected_bg{FColor::Default};
FColor selected_focus_fg{FColor::Default};
FColor selected_focus_bg{FColor::Default};
};

struct ErrorBoxColors
{
FColor fg{FColor::Default};
Expand Down Expand Up @@ -193,6 +203,7 @@ class FWidgetColors
// Data members
NonContextualColors term{};
DialogColors dialog{};
TextColors text{};
ErrorBoxColors error_box{};
NonContextualColors tooltip{};
NonContextualColors shadow{};
Expand Down Expand Up @@ -248,6 +259,7 @@ class default8ColorTheme final : public FWidgetColors
private:
void setTermColors();
void setDialogColors();
void setTextColors();
void setErrorBoxColors();
void setTooltipColors();
void setShadowColors();
Expand Down Expand Up @@ -303,6 +315,7 @@ class default16ColorTheme final : public FWidgetColors
private:
void setTermColors();
void setDialogColors();
void setTextColors();
void setErrorBoxColors();
void setTooltipColors();
void setShadowColors();
Expand Down Expand Up @@ -358,6 +371,7 @@ class default8ColorDarkTheme final : public FWidgetColors
private:
void setTermColors();
void setDialogColors();
void setTextColors();
void setErrorBoxColors();
void setTooltipColors();
void setShadowColors();
Expand Down Expand Up @@ -413,6 +427,7 @@ class default16ColorDarkTheme final : public FWidgetColors
private:
void setTermColors();
void setDialogColors();
void setTextColors();
void setErrorBoxColors();
void setTooltipColors();
void setShadowColors();
Expand Down
44 changes: 38 additions & 6 deletions final/widget/ftextview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ void FTextView::setGeometry ( const FPoint& pos, const FSize& size
void FTextView::resetColors()
{
const auto& wc = getColorTheme();
setForegroundColor (wc->dialog.fg);
setBackgroundColor (wc->dialog.bg);
setForegroundColor (wc->text.fg);
setBackgroundColor (wc->text.bg);
FWidget::resetColors();
}

Expand Down Expand Up @@ -591,12 +591,14 @@ inline void FTextView::printLine (std::size_t y)
line_buffer.print() << FString{trailing_whitespace, L' '};
}

printHighlighted (line_buffer, data[n].highlight);
addHighlighting (line_buffer, data[n].highlight);
addSelection (line_buffer, n);
print(line_buffer);
}

//----------------------------------------------------------------------
inline void FTextView::printHighlighted ( FVTermBuffer& line_buffer
, const std::vector<FTextHighlight>& highlight )
inline void FTextView::addHighlighting ( FVTermBuffer& line_buffer
, const std::vector<FTextHighlight>& highlight )
{
for (auto&& hgl : highlight)
{
Expand All @@ -616,8 +618,38 @@ inline void FTextView::printHighlighted ( FVTermBuffer& line_buffer
fchar.attr = hgl.attributes.attr;
}
}
}

print(line_buffer);
//----------------------------------------------------------------------
inline void FTextView::addSelection (FVTermBuffer& line_buffer, std::size_t n)
{
if ( ! hasSelectedText() || n < selection_start.row || n > selection_end.row )
return;

const std::size_t pos = static_cast<std::size_t>(xoffset) + 1;
const std::size_t start_col = (selection_start.column > pos)
? selection_start.column - pos : 0U;
const std::size_t end_col = (selection_end.column >= pos)
? selection_end.column - pos + 1 : 0U;
const auto& wc = getColorTheme();
const auto has_focus = hasFocus();
const auto& selected_fg = has_focus
? wc->text.selected_focus_fg
: wc->text.selected_fg;
const auto& selected_bg = has_focus
? wc->text.selected_focus_bg
: wc->text.selected_bg;
const std::size_t start_index = (n == selection_start.row) ? start_col : 0U;
const std::size_t end_index = (n == selection_end.row)
? std::min(end_col, line_buffer.getLength())
: line_buffer.getLength();
auto select = [&selected_fg, &selected_bg] (auto& fchar)
{
fchar.fg_color = selected_fg;
fchar.bg_color = selected_bg;
};

std::for_each (&line_buffer[start_index], &line_buffer[end_index], select);
}

//----------------------------------------------------------------------
Expand Down
23 changes: 17 additions & 6 deletions final/widget/ftextview.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ class FTextView : public FWidget
auto getTextVisibleSize() const -> FSize;
auto getText() const -> FString;
auto getSelectedText() const -> FString;
auto getSelectionStart() -> FTextPosition;
auto getSelectionEnd() -> FTextPosition;
auto getSelectionStart() const -> FTextPosition;
auto getSelectionEnd() const -> FTextPosition;
auto getLine (FTextViewList::size_type) -> FTextViewLine&;
auto getLine (FTextViewList::size_type) const -> const FTextViewLine&;
auto getLines() const & -> const FTextViewList&;
Expand All @@ -207,6 +207,9 @@ class FTextView : public FWidget
void scrollToEnd();
void scrollBy (int, int);

// Inquiry
auto hasSelectedText() const -> bool;

// Methods
void hide() override;
void clear();
Expand Down Expand Up @@ -253,8 +256,9 @@ class FTextView : public FWidget
void drawText();
auto canSkipDrawing() const -> bool;
void printLine (std::size_t);
void printHighlighted ( FVTermBuffer&
, const std::vector<FTextHighlight>& );
void addHighlighting ( FVTermBuffer&
, const std::vector<FTextHighlight>& );
void addSelection (FVTermBuffer&, std::size_t);
auto useFDialogBorder() const -> bool;
auto isPrintable (wchar_t) const -> bool;
auto splitTextLines (const FString&) const -> FStringList;
Expand Down Expand Up @@ -343,11 +347,11 @@ inline auto FTextView::getTextVisibleSize() const -> FSize
{ return {getTextWidth(), getTextHeight()}; }

//----------------------------------------------------------------------
inline auto FTextView::getSelectionStart() -> FTextPosition
inline auto FTextView::getSelectionStart() const -> FTextPosition
{ return selection_start; }

//----------------------------------------------------------------------
inline auto FTextView::getSelectionEnd() -> FTextPosition
inline auto FTextView::getSelectionEnd() const -> FTextPosition
{ return selection_end; }

//----------------------------------------------------------------------
Expand Down Expand Up @@ -383,6 +387,13 @@ inline void FTextView::resetSelection()
inline void FTextView::scrollTo (const FPoint& pos)
{ scrollTo(pos.getX(), pos.getY()); }

//---------------------------------------------------------------
inline auto FTextView::hasSelectedText() const -> bool
{
return selection_start.row != selection_end.row
|| selection_start.column != selection_end.column;
}

//----------------------------------------------------------------------
template <typename T>
void FTextView::append (const std::initializer_list<T>& list)
Expand Down

0 comments on commit 8d547c2

Please sign in to comment.