magiblot / tvision

A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support.
Other
1.99k stars 150 forks source link

TDesktop with fixed Window #83

Closed WillianBR closed 1 year ago

WillianBR commented 1 year ago

Main Desktop Customize Goal

I was wondering if somebody manage to create a Window/Dialog to fill all the desktop and block the CLOSE/RESIZE actions.

I'm considering use the TV to create a terminal menu app, to show a custom menu to operator.

Only a few fixed menus will be displayed and the main actions would be show in a window, occuipied all the desktop area.

As the actions will be a few, I'm thinking about use buttons for the action and a static text for long description.

I going through TV source code, but nothing by now!

So, the premisses are:

magiblot commented 1 year ago

Hi Willian!

The ability to move, resize, close and maximize windows is determined by the flags field of the TWindow class. As it can be seen in twindow.cpp, this field is initialized by default to wfMove | wfGrow | wfClose | wfZoom. To disable all these, just set flags = 0. The frame cannot be hidden; you will have to make the window bigger than the desktop so that the frame borders stay out of sight. However, because of palettes, in order to use TButton, TInputLine, etc. you'll have to use a TDialog instead of a plain TWindow.

Buttons can of course be focused with the Tab key. I guess you are thinking about focusing them by hovering the mouse over them; you can probably achieve this by creating a TButton subclass that reacts to evMouseMove events by calling focus(). The same goes for the other views. However, evMouseMove events are only guaranteed to work on Windows.

WillianBR commented 1 year ago

Issue 1

@magiblot Thank you!

I did it. Changing the flag and using getBounds() to compute the Dialog size. And using insert(), instead of exec... to add the dialog into desktop.

Did you can tell if use insert() in a dialog without I destroy it could cause memory leak?

If it is a problem I can subclass and use other ways.

Issue 2

Right now, I'm trying to build your "hello.cpp" test app on a Ubuntu 20.04 WSL (Linux Willian-Ryzen7 4.4.0-19041-Microsoft #2311-Microsoft Tue Nov 08 17:09:00 PST 2022 x86_64 x86_64 x86_64 GNU/Linux) with g++ 9.3.0.

But something is not right!

It fails!

Command:

tvision$ g++ -std=c++17 -O3 -DNDEBUG hello.cpp -o hello -I./include -L/lib/x86_64-linux-gnu/libgcc_s.so.1 -L/opt/lib -lgpm -lncursesw -Wl,-Bstatic build/libtvision.a
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status

ldconfig shows:

tvision$ sudo ldconfig -p|grep gcc
        libgcc_s.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgcc_s.so.1
        libgcc_s.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libgcc_s.so

Searching the FS I got:

/usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/libgcc_s.a
/usr/lib/gcc/x86_64-w64-mingw32/9.3-win32/libgcc_s.a
/usr/lib/gcc/i686-w64-mingw32/9.3-posix/libgcc_s.a
/usr/lib/gcc/i686-w64-mingw32/9.3-win32/libgcc_s.a
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so

I didn't change a bit! It's 100% your code!! My guess is my environment!

This weeked I intende to publish the current code (not so good) on my Github. Just after I add the YAML parser code.

magiblot commented 1 year ago

Hi Willian!

If you insert the dialog into the deskTop, you don't have to destroy it manually later. When the application is exiting, and when the desktop is being destroyed, your dialog will be also destroyed automatically (see TGroup::shutDown() in source/tvision/tgroup.cpp).

I have no idea why you get the linker error, so I suggest you use CMake instead. For example, assuming that you created a new directory for your project and that your source code is in a file named hello.cpp, then create a file named CMakeLists.txt with these contents:

cmake_minimum_required (VERSION 3.5) # This can be raised later if you run into issues.

# Use whatever project name you want
project(willianvision)

# Define output executable and source files
add_executable(hello hello.cpp)

# Import project tvision
add_subdirectory(<path to tvision folder>)

# The 'hello' executable depends on tvision. This will automatically configure the compilation flags
# and include directories necessary for 'hello' to compile successfully.
target_link_libraries(hello PRIVATE tvision)

You'll be able to build your application with these commands:

cmake . -B ./build # Only necessary the first time
cmake --build ./build

And your application will be located in ./build/hello.

WillianBR commented 1 year ago

@magiblot I'll do the test when I get back home.

I have one more question about screens.

I'm connecting the Dev Linux VM with putty (SSH Client). When I resize the putty window, the TV Desktop resize itself. It's good.

How I can detect this behavior and resize my dialog to fit the new size?

My dialog show a lot of TButton's and I have to detect the new size e render only the ones who will fit on the new dialog size.

I'm reading the TV source code right now to find something!

magiblot commented 1 year ago

If the desktop is being resized but your dialog isn't, then you have to change the growMode field of your dialog. In your case, I think the right value would be growMode = gfGrowHiX | gfGrowHiY. You can find the full list of GrowMode masks in include/tvision/views.h.

Additionally, you can detect when a TView gets resized by overriding the virtual void changeBounds(const TRect& bounds) method. For example, if your class inherits from TDialog:

void MyDialog::changeBounds(const TRect &bounds)
{
    TDialog::changeBounds(bounds); // Call the superclass's method.
    // Do other stuff:
    // ...
}

If you need to reposition some of your buttons, you might also achieve this by setting their growMode fields to the right values (which you'll have to figure out).

WillianBR commented 1 year ago

My problem is a little bit more tricky!

My dialog has fixed size! There is no option to resize.

But I wanna know when the Desktop (base window/view) was resized.

It's normal if I'm using SSH. I can see the desktop resizing.

I wanna be aware of such events and resize my dialog and reposition my buttons and static texts.

My code is created a dialog using the desktop size. If the desktop is full screen, it'll fill the free space. If I resize the screen and create a second dialog it'll be small, fitting the desktop.

I wanna be aware and resize the dialog, adding more content.

WillianBR commented 1 year ago

Hi,

I just intercept the event TApplication::changeBounds(bounds). In my custom class, I called the base class and after, I call my dialogs to redraw itself.

By now is working.

I'll keep coding and on this weeked I'll publish the base code on github.com.

After that I'll start working for real in the logic!

Thank you!

WillianBR commented 1 year ago

Thank you for your recommendation about CMake.

I'm using and it prove very handy!

I'm still raising the first bricks, but soner I acheve a basic usable version of the code, I'm going to share.

I'm right now looking a method to allow me enumerate all the windows and dialogs inserted into Desktop.