gansm / finalcut

A text-based widget toolkit
https://github.com/gansm/finalcut/wiki/First-steps#first-steps-with-the-final-cut-widget-toolkit
GNU Lesser General Public License v3.0
981 stars 52 forks source link

Enabling text selection #137

Open rifatsahiner opened 6 months ago

rifatsahiner commented 6 months ago

Dear Markus, First of all thanks for the amazing library. I have made myself a log viewer with finalcut for my server side project. Here is a screenshot;

logger

Everything is great but its currently lacking text selection, which is crucial for a log viewer. I should be able to copy log text and paste to editor search during development. What is the best way you can think of for doing this? These are what I think possible;

Log-view test code is here if you want to check; https://github.com/rifatsahiner/tui-logger

Thanks in advance Rıfat

gansm commented 5 months ago

Hi Rıfat, sorry for my late reply, but I've been on vacation for the last few weeks and about 9500 kilometers away from my PC. You wrote a great application. It's always interesting to see what creative implementations programmers realize with FINAL CUT.

I have extended FTextView with the possibility of selecting text between a start and an end position and extracting this text separately (45fea88). Visual highlighting of the selected text and selection with the mouse are currently not implemented.  

The data structure of a unique text position:

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

 

New FTextView methods:

Method Description
auto getSelectedText() const -> FString; Extracts the selected text between the start and end position into an FString object
auto getSelectionStart() const -> FTextPosition; Gets the start position of the selected text
auto getSelectionEnd() const -> FTextPosition; Gets the end position of the selected text
void setSelectionStart (const FTextViewList::size_type row, const FString::size_type col); Sets the start position of the selected text
void setSelectionEnd (const FTextViewList::size_type row, const FString::size_type col); Sets the end position of the selected text
void resetSelection(); Remove text selection

If your terminal supports OSC-52, you can copy the text (extracted with getSelectedText()) to the system clipboard.

An OSC-52 example with the Unix shell:

printf "\033]52;c;$(printf "%s" "Hello, World!" | base64)\a"

 

Update:

Added visual highlighting of the selected text in FTextView (8d547c2).

grafik

rifatsahiner commented 5 months ago

Hi Markus, thanks for the swift solution. I hope you had a great vacation, surely you are deserving it :+1: I will utilize something out with this new 'selected-text' feature with clipboard usage as you have recommended (eventually a cursor text selection would be great 🙏). I also made a list of minor suggestions about the widgets while experimenting on them;

These are all my humble suggestions, all are workaround-able. I can carry them to a new issue or separate issues if its better.

Thanks.

gansm commented 5 months ago

Hi Rıfat, the mouse selection implementation is now implemented in the FTextView. You can enable it with setSelectable(). The implementation was more complex than I expected, so I had to add a distinction between a clicked or a mouse-wheel-selected widget.

Your suggestions:

FTextView::append overload with r-value ref FString/wstring

FTextView has an overloaded append method with a std::initializer_list template. You can use it to pass a rvalue.

template <typename T>
void append (const std::initializer_list<T>& list);

Example:

scrolltext.append(L"rvalues");

Passing a whole FTextViewList to FTextView which will clear the content and redraw with new FTextViewList (easier for whole content manipulation like search etc.)

I have added a setLines() method to FTextView (0078fd6).

Text orientation for FSwitch

I'm not sure what you have in mind here. Do you want the text to be on the right, top, or bottom?

A getItemIndexByData/Text like method to be able to select/remove/edit an item of FComboBox for dynamic item manipulation in run-time.

Can you be more specific about what you mean by that?

Scrollable views scroll vertically with wheel up/down but does not horizontally with wheel left/right (also with touchpad two-finger left/right)

I just added support for left and right scrolling with the mouse (3dbdeee). Currently, this feature seems to be implemented only in xterm. I developed and tested this feature with a Logitech RX250 mouse.

Customization for dialog title-bar button menu

#include <final/final.h>

using namespace finalcut;

auto main (int argc, char* argv[]) -> int
{
  finalcut::FApplication app{argc, argv};
  FDialog dgl{&app};
  dgl.setPos ({12, 4});
  dgl.setSize ({30, app.getHeight() - 14});
  FLabel label{&dgl};
  label << finalcut::UniChar::BlackUpPointingTriangle
        << std::wstring{L"\n"}
        << finalcut::UniChar::BoxDrawingsUpAndRight
        << finalcut::FString{2, finalcut::UniChar::BoxDrawingsHorizontal}
        << " Own menu entries";
  label.setGeometry (FPoint{1, 1}, FSize{20, 2});

  for (auto child : dgl)
  {
    if ( child->isWidget() && child->isInstanceOf("FMenu") )
    {
      auto fmenu_widget = static_cast<FWidget*>(child);
      auto line = new FMenuItem(fmenu_widget);
      line->setSeparator();
      auto menu_entry = new FMenuItem("My &own entry", fmenu_widget);
    }
  }

  finalcut::FWidget::setMainWidget(&dgl);
  dgl.show();
  return app.exec();
}

grafik        grafik