-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
resizable dialog with scrollview #99
Comments
Hello Michael, I'm glad you like FINAL CUT 😊. First, a few remarks about your program:
Unfortunately, I have to inform you that the widget you are trying to generate already exists under the name FTextView 😉. I use it in #include <final/final.h>
using namespace finalcut;
class TextDialogWidget final : public FDialog
{
public:
explicit TextDialogWidget (FWidget* parent = nullptr)
: FDialog(parent)
{
// Fill with a few lines
for (std::size_t n{0}; n < numLines; n++)
{
scrollText << FString(FString("Line = ") << n);
}
}
private:
void initLayout() override
{
setText ("Dialog");
scrollText.ignorePadding();
scrollText.setFocus();
scrollText.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
setMinimizable();
setResizeable();
setMinimumSize (FSize{17, 6});
FDialog::initLayout();
}
void adjustSize()
{
FDialog::adjustSize();
scrollText.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
}
// Data members
FTextView scrollText{this};
std::size_t numLines{42};
};
int main (int argc, char* argv[])
{
FApplication app(argc, argv);
TextDialogWidget dialog(&app);
dialog.setGeometry (FPoint{28, 2}, FSize{18, 15});
app.setMainWidget(&dialog);
dialog.show();
return app.exec();
}
|
I just noticed that you edited your post again. Nice that you found |
Thanks for your fast response! And sorry for my late feedback 😬 The problem with my self-made Besides for learning, there actually was another reason for considering to implement some self-made text viewer. What I need is a scrollable text viewer where I can highlight a certain line, and I also want to place markers in the first column. As a dirty hack I therefore
However, this is certainly not the way it should be done. Of course I could copy the For giving some background: As the screenshot suggest I am writing a debugger for a virtual machine called Users of Although I personally believe that programming is best learned by using the terminal only I therefore implemented a GUI with
Giving them access to a server via Btw, the screenshot below shows the current status. The debugger can execute instruction-by-instruction and a CPU viewer shows the instruction pointer, instruction register and read/writes to general purpose registers. Thanks to FINAL CUT this was really easy to implement. And I am pretty confident that other things e.g. viewers for the memory or I/O will go similarly smooth. |
Wow, I am very impressed with your screenshots. It looks very fancy. The problem with crashes could be caused by the fact that you did not restrict the shrinking of the dialog by using the Another reason for a crash could be an infinite loop caused by (See the last section in chapter Areas) Unfortunately, I have not yet come up with a better solution to prevent unwanted recursion loops.
To create a derived class of I am glad that you have found a working solution to your implementation problems with FINAL CUT. It always makes me happy when my concept and interface design is well received. My intention in implementing the widget API was that it should be user-friendly and easy to learn. FINAL CUT should support developers in their work. A framework should not disturb a user too much in what he wants to do with it. PS: ULM is a nice recursive acronym! I like it :-) |
Hi Michael, I liked your idea with the colors in the text so much that I just implemented it in FTextView (dc1afbb + c5b75e5). Thank you for this great idea. I will also generate a sample program to demonstrate functionality in one following commits. Here is my short explanation of how to use text highlighting in FTextView: finalcut::FTextView scrolltext{parent_widget};
scrolltext.append("Linux is like wigwam: no Gates, no Windows and Apache inside.");
finalcut::FChar fchar{};
fchar.ch[0] = L' ';
fchar.fg_color = FColor::Red;
fchar.bg_color = FColor::Yellow;
fchar.attr.byte[0] = 0;
fchar.attr.byte[1] = 0;
fchar.attr.byte[2] = 0;
fchar.attr.byte[3] = 0;
fchar.attr.bit.italic = true;
scrolltext.addHighlight(0, finalcut::FTextView::FTextHighlight{14, 6, std::move(fchar)});
finalcut::FStyle style1;
style1.setStyle (finalcut::Style::Italic);
scrolltext.addHighlight(0, finalcut::FTextView::FTextHighlight{32, 10, FColor::Green, style1});
finalcut::FStyle style2;
style2.setStyle (finalcut::Style::Underline);
scrolltext.addHighlight(0, finalcut::FTextView::FTextHighlight{47, 6, finalcut::FColorPair(FColor::White, FColor::Blue), style2}); New methods for highlighting: void FTextView::addHighlight (std::size_t line, FTextHighlight&& hgl);
void FTextView::resetHighlight (std::size_t line); The data class FTextHighlight: struct FTextHighlight
{
FTextHighlight (std::size_t i, std::size_t l, FChar&& fchar) noexcept
: index{i}
, length{l}
, attributes{std::move(fchar)}
{ }
FTextHighlight (std::size_t i, std::size_t l, FColor c, const FStyle& s = FStyle()) noexcept
: index{i}
, length{l}
{
attributes.fg_color = c;
attributes.bg_color = getColorTheme()->dialog_bg;
attributes.attr = s.toFAttribute();
}
FTextHighlight (std::size_t i, std::size_t l, const FColorPair& cpair, const FStyle& s = FStyle()) noexcept
: index{i}
, length{l}
{
attributes.fg_color = cpair.getForegroundColor();
attributes.bg_color = cpair.getBackgroundColor();
attributes.attr = s.toFAttribute();
}
std::size_t index{};
std::size_t length{};
FChar attributes{};
}; I have now created an example program that shows how to use text highlighting with the GNU Lesser General Public License (LGPL) text. |
This is great! Thanks for the feature! Today I finally found some time for coding and used your example. This is the result (and a follow question): The almost invisibly grey highlighted line indicates what instruction was executed and the red line indicates what instruction gets executed next. Ideally the complete line would be highlighted. My current hack is to pad each line with spaces such that each line has (for example) 200 characters. Then I get the effect that I want. But I wonder whether there is already a feature to achieve this more elegant? I also hope to find some time to implement a |
You are right. It doesn't work because the trailing whitespaces were not part of the FVTermBuffer object. I have changed this now (16b56a3) so that highlighting is also possible up to the end of the line. constexpr auto EOL = std::numeric_limits<std::size_t>::max();
scrolltext.addHighlight(1, finalcut::FTextView::FTextHighlight{0, EOL, finalcut::FColorPair(FColor::White, FColor::Red)}); I have an idea for your project: |
Great! Works like a charm 👍 Also thanks for your suggestion to use jump arrows like in |
Hi Michael, I just had the idea for Constructors of FTextHighlight (std::size_t index, std::size_t length, const FChar& fchar);
FTextHighlight (std::size_t index, const FChar& fchar);
FTextHighlight (std::size_t index, std::size_t length, const FStyle& style);
FTextHighlight (std::size_t index, const FStyle& style) ;
FTextHighlight (std::size_t index, std::size_t length, FColor fg_color, const FStyle& style = FStyle());
FTextHighlight (std::size_t index, FColor fg_color, const FStyle& style = FStyle());
FTextHighlight (std::size_t index, std::size_t length, const FColorPair& cpair, const FStyle& style = FStyle());
FTextHighlight (std::size_t index, const FColorPair& cpair, const FStyle& style = FStyle()); |
Again, sorry for the late response. I took some time to find time to continue with my project. It is still not finished but now I have reached a stage where it is providing some core functionality:
Here some brief demo showing the execution of a "hello, word!" program (compiled with the ULM C compiler so the code is lengthy and breakpoints are really needed), and a simple "echo" program showing how characters are read from the input buffer ... Untitled.mp4However, I had to apply some hacks to finalcut. Mostly I needed some more access to internal things so I added some methods or changed in some place 'private' to 'protected'. If you are interested I can write down in more detail where and why I made some modifications. However, most of it was just done with the intension "make it work now and think about how to do it right later". I also add the result of 'git diff' this might already give some overview. |
I am back from my vacation and I hope my answer is not too late for you. Thank you for the screencast video. Your implementation looks very consistent and neat. I am very interested in where the FINAL CUT API is too restrictive or a widget cannot be used as expected. Therefore, I have analyzed your diff file with great interest. If I see it correctly, we are talking about the widgets
Proposal: // Direct access to any text line
FTextViewLine& getLine (std::size_t line);
// Usage in programming
auto& text_ref = getLine(20).text;
auto& highlight_ref = getLine(20).highlight;
Proposal: // Get the scroll position (analogous to FScrollView)
FPoint getScrollPos() const;
// Get the size of the visible text
FSize getTextVisibleSize() const; Note: The explicit call of the method dgl.setText("New title");
dgl.redraw(); This call is very economical through FINAL CUT only writes the changes to the terminal. |
Your vacation is well deserved! I think most of your proposals will do the trick for me. About class IOView final : public finalcut::FDialog
{
public:
explicit IOView(finalcut::FWidget * = nullptr);
void notify();
class InputBuffer final : public finalcut::FLineEdit
{
public:
explicit InputBuffer(IOView *);
~InputBuffer();
void onKeyPress(finalcut::FKeyEvent *) override;
bool keyInput(finalcut::FKey key);
void deletePreviousCharacter();
void notify();
private:
IOView *ioView;
};
private:
using MatchList = std::vector<std::size_t>;
using StringPos = std::wstring::size_type;
void initLayout() override;
void adjustSize() override;
void onAccel(finalcut::FAccelEvent *) override;
finalcut::FTextView scrolltext{ this };
finalcut::FLabel inBufLabel{ this };
finalcut::FLabel inputLabel{ this };
InputBuffer input{ this };
finalcut::FLineEdit inBuf{ this };
}; Btw: Last week I made a YouTube video for giving some overview of my lecture. And Final Cut gets mentioned at 13:50. |
Hi Michael, I have now implemented your great hints in code (083ea79).
void inputText (const FString& input);
void deletesCharacter();
void moveCursorToBegin();
void moveCursorToEnd();
void stepCursorForward (std::size_t steps = 1);
void stepCursorBackward (std::size_t steps = 1);
void setOverwriteMode (bool overwrite = true); You can easily recreate the backspace functionality ( stepCursorBackward();
deletesCharacter(); I hope that any modification of the library code is now no longer necessary to implement your application. Many thanks for mentioning FINAL CUT in your education video. |
I finally found some time to adapt my code. Thanks a lot!! With your modifications almost everything works (and I can perfectly live with that):
|
Hi Michael, thank you for the feedback. When I wrote the code, I had just worked with On changes, |
Wow! Thank you Markus for this quick response. Everything works now like a charm! :-) |
I am sudden facing a crash on the solaris machine (gcc 11.2.0, SunOS 5.11). And I can not reproduce it on any Linux and MacOS boxes. I located the problem in codeview.cpp and could the crash with the more minimalistic test program below. It crashes in #include <cinttypes>
#include <final/final.h>
#include <iostream>
class Test : public finalcut::FDialog
{
public:
// Constructor
explicit Test(finalcut::FWidget *parent = nullptr)
: finalcut::FDialog{ parent }
{
finalcut::FString instrStr;
uint64_t addr;
finalcut::FTextView::FTextViewList::size_type line;
// int line;
for (addr = 0, line = 0; addr < 42; addr += 4, ++line) {
instrStr.sprintf("0x%016" PRIX64 ", sizeof(line) = %zu, line = %zu",
addr, sizeof(line), line);
scrolltext.append(instrStr);
auto &highlight = scrolltext.getLine(line).highlight; // <- crash
}
}
void
initLayout() override
{
scrolltext.setGeometry(finalcut::FPoint{ 1, 2 },
finalcut::FSize{ getWidth(), getHeight() - 1 });
}
finalcut::FTextView scrolltext{ this };
};
int
main(int argc, char *argv[])
{
// Create the application object
finalcut::FApplication app{ argc, argv };
Test test{ &app };
test.setSize(finalcut::FSize{ 57, 20 });
test.setShadow();
// Set dialog d as main widget
finalcut::FWidget::setMainWidget(&test);
// Show and start the application
test.show();
return app.exec();
} |
Thanks! Actually I am glad that you can not reproduce the error. And most of all don't see an obvious error in the code. Because I also started to believe that there is a problem with the Solaris system. Unfortunately it a machine that is not maintained by myself. So I will abandon that system for now. |
Dear Markus,
after discovering just recently your amazing library I started to play around with your examples.
I am trying to write a dialog (similar to
examples/scrollview.cpp
) that can display some text file. Of course this can be done with FTextView. But I thought implementing some simplified, self-made variant might be a good way to learn how some of the concepts of finalcut. So my problem is mainly academic and out of curiosity :DIn a first step my plan was to write just a dialog that shows a fixed number of lines, e.g
line = 1
, ...,line = 42
. This worked fine until I tried to make the dialog resizeable. My idea was that once a file is completely read into some buffer I will know the number of lines and number of columns that are needed to display it. Hence, the size of the scrollable area should at least have these "text dimensions".If I understand FScrollView::setGeometry correctly then it also changes the size of the scroll area. So after making the dialog smaller the scrollbars were gone ... My idea was that the overloaded
setGeometry
of my scrollview adjusts the scroll dimensions to the maximum of the current widget size and the "text dimensions". But this seems to be the wrong idea ...Maybe you can point me to some example or give me a hint how to manage this.
Best regards,
Michael
Here the (working) variant using an instance of
FTextView
Here my attempt to achieve the same with a class derived from
FScrollView
:The text was updated successfully, but these errors were encountered: