Skip to content

Commit

Permalink
FTextView gets the ability to select text between a start and end pos…
Browse files Browse the repository at this point in the history
…ition
  • Loading branch information
gansm committed Mar 25, 2024
1 parent 83ba487 commit 45fea88
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 10 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2023-03-25 Markus Gans <guru.mail@muenster.de>
* FTextView gets the ability to select text between a start and
end position

2023-02-14 Markus Gans <guru.mail@muenster.de>
* Optimize FChar operations and processing

Expand Down
3 changes: 2 additions & 1 deletion final/util/fstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ class FString
{
public:
// Using-declarations
using size_type = std::wstring::size_type;
using difference_type = std::wstring::difference_type;
using iterator = std::wstring::iterator;
using const_iterator = std::wstring::const_iterator;
using reference = std::wstring::reference;
using const_reference = std::wstring::const_reference;
using difference_type = std::wstring::difference_type;

// Constructors
FString () = default;
Expand Down
59 changes: 50 additions & 9 deletions final/widget/ftextview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,58 @@ auto FTextView::getText() const -> FString

for (auto&& line : data)
{
if ( ! line.text.isEmpty() )
if ( line.text.isEmpty() )
continue;

if ( iter != s.begin() )
{
if ( iter != s.begin() )
{
*iter = '\n';
++iter;
}

std::copy (line.text.begin(), line.text.end(), iter);
iter += std::distance(line.text.begin(), line.text.end());
*iter = '\n'; // Add newline character
++iter;
}

std::copy (line.text.begin(), line.text.end(), iter);
iter += std::distance(line.text.begin(), line.text.end());
}

return s;
}

//----------------------------------------------------------------------
auto FTextView::getSelectedText() const -> FString
{
bool wrong_column_order = false;

if ( selection_start.row == selection_end.row )
{
if ( selection_start.column == selection_end.column )
return {};

if ( selection_start.column > selection_end.column )
wrong_column_order = true;
}

const auto start_row = std::min(selection_start.row, selection_end.row);
const auto end_row = std::max(selection_start.row, selection_end.row);
const auto start_col = wrong_column_order ? selection_end.column
: selection_start.column;
const auto end_col = wrong_column_order ? selection_start.column
: selection_end.column;
const auto first = &getLine(start_row);
const auto last = &getLine(end_row);
const auto end = last + 1;
auto iter = first;
FString s{};

while ( iter != end )
{
if ( iter == first )
s = FString(iter->text.toWString().substr(start_col)) + '\n';
else if ( iter == last )
s += iter->text.left(end_col + 1) + '\n';
else
s += iter->text + '\n'; // Add newline character

++iter;
}

return s;
Expand Down
44 changes: 44 additions & 0 deletions final/widget/ftextview.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ class FTextView : public FWidget
using FTextViewList = std::vector<FTextViewLine>;
using FWidget::setGeometry;

struct FTextPosition
{
FTextViewList::size_type row{};
FString::size_type column{};
};

// Constructor
explicit FTextView (FWidget* = nullptr);

Expand All @@ -176,7 +182,11 @@ class FTextView : public FWidget
auto getScrollPos() const -> FPoint;
auto getTextVisibleSize() const -> FSize;
auto getText() const -> FString;
auto getSelectedText() const -> FString;
auto getSelectionStart() -> FTextPosition;
auto getSelectionEnd() -> FTextPosition;
auto getLine (FTextViewList::size_type) -> FTextViewLine&;
auto getLine (FTextViewList::size_type) const -> const FTextViewLine&;
auto getLines() const & -> const FTextViewList&;

// Mutators
Expand All @@ -186,6 +196,9 @@ class FTextView : public FWidget
void setText (const FString&);
void addHighlight (std::size_t, const FTextHighlight&);
void resetHighlight (std::size_t);
void setSelectionStart (const FTextViewList::size_type, const FString::size_type);
void setSelectionEnd (const FTextViewList::size_type, const FString::size_type);
void resetSelection();
void scrollToX (int);
void scrollToY (int);
void scrollTo (const FPoint&);
Expand Down Expand Up @@ -264,6 +277,8 @@ class FTextView : public FWidget
FTextViewList data{};
FScrollbarPtr vbar{nullptr};
FScrollbarPtr hbar{nullptr};
FTextPosition selection_start{};
FTextPosition selection_end{};
KeyMap key_map{};
bool update_scrollbar{true};
int xoffset{0};
Expand Down Expand Up @@ -327,14 +342,43 @@ inline auto FTextView::getScrollPos() const -> FPoint
inline auto FTextView::getTextVisibleSize() const -> FSize
{ return {getTextWidth(), getTextHeight()}; }

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

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

//----------------------------------------------------------------------
inline auto FTextView::getLine (FTextViewList::size_type line) -> FTextViewLine&
{ return data.at(line); }

//----------------------------------------------------------------------
inline auto FTextView::getLine (FTextViewList::size_type line) const -> const FTextViewLine&
{ return data.at(line); }

//----------------------------------------------------------------------
inline auto FTextView::getLines() const & -> const FTextViewList&
{ return data; }

//----------------------------------------------------------------------
inline void FTextView::setSelectionStart ( const FTextViewList::size_type row
, const FString::size_type col )
{ selection_start = {row, col}; }

//----------------------------------------------------------------------
inline void FTextView::setSelectionEnd ( const FTextViewList::size_type row
, const FString::size_type col )
{ selection_end = {row, col}; }

//----------------------------------------------------------------------
inline void FTextView::resetSelection()
{
selection_start = {0U, 0U};
selection_end = {0U, 0U};
}

//----------------------------------------------------------------------
inline void FTextView::scrollTo (const FPoint& pos)
{ scrollTo(pos.getX(), pos.getY()); }
Expand Down

0 comments on commit 45fea88

Please sign in to comment.