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
Support for resizeable windows with adaptive UI. #23161
Conversation
This works reasonably(!) well in the tiles and ncurses versions but breaks down when overlay dialog windows, such as the inventory or crafting menus, are open while resizing the window/terminal. |
Yeah, it's the same issue as with the main menu screen. There's no mechanism for rescaling overlay UIs while they are active. There's never been a need for such a thing before. |
|
I hooked into the existing fullscreen toggle to allow toggling windowed mode in tiles. Any issues with that? |
Oh hell yes, this adds standard macOS fullscreen support (clicking fullscreen "traffic light" button). Very nice |
@Leland Well, the fullscreen thing you quoted is actually attached to the keybinding in game. In curses, it toggles off the sidebar(dependent on term sizes for some reason.) It had no functionality in the tiles build. But, I did my best with this to get every platform to allow it's windowing system to work properly. Glad to hear it works fine on OSX! That's the one platform I have no means to test. |
In curses if the size goes below 80x24 it should display For the main menu a timeout with a recalc/redraw similar to the ingame See After that recalc and redraw the window. |
src/wincurse.cpp
Outdated
SelectObject(backbuffer, font);//Load our font into the DC | ||
color_loader<RGBQUAD>().load( windowsPalette ); | ||
if( SetDIBColorTable(backbuffer, 0, windowsPalette.size(), windowsPalette.data() ) == 0 ) { | ||
throw std::runtime_error( "SetDIBColorTable failed" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is throwing from a callback function that is called from non-C++ code. And the exception will leave the C++ code and that basically invokes Undefined Behaviour.
Btw. the call to color_loader::load
above can also throw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was winging it with wincurse.cpp, honestly. Reading M$ Windows API references is like sticking a red hot poker in my eyes. I didn't really expect to get this platform to work at all.
src/sdltiles.cpp
Outdated
return; | ||
} | ||
SDL_RestoreWindow( ::window.get() ); | ||
SDL_SetWindowSize( window.get(), restore_win_w, restore_win_h ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you accessing the global window
in an inconsistent way (with and without ::
prefix)? The prefix is not needed in this function all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly have no idea. I was jumping between this function and WinCreate to work things out, I guess I got my wires crossed. Why exactly is the prefix being used in WinCreate?
src/wincurse.cpp
Outdated
{ | ||
if( WindowDC != NULL ) { | ||
if( ReleaseDC(WindowHandle, WindowDC) == 0 ) { | ||
WindowDC = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting this to 0 (why not nullptr
, it's not of a numeric type, it's a pointer) is quite pointless. It's overridden unconditionally a few lines below anyway. Same with backbuffer
.
@@ -18,6 +18,7 @@ | |||
#include "catacharset.h" | |||
#include "color.h" | |||
|
|||
#include "game.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that so much pure output code now depends on "game.h" and class game
worries me. This is not a good design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I only pulled this header to access game::init_ui. Perhaps there's a better location for it? The game class seems far too involved in handling output in general, in my opinion. Of course, it's also a behemoth that I'm sure no one really wants to suffer through refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also extend our available toolkit with signals. A signal would be an excellent way to handle this situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How so? This is a dependency issue, the primary uses of signals are IPC and asynchronicity, we arent dealing with either of those here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it comes down to it, we are dealing with an asynchronous event. Window resizing is an external event generated by the platform window manager, and a signal and slot approach let's us handle it with ease. It also let's us work around the tight coupling issue and avoid adding in another header just to run a single function.
Edit: I can use this approach to tackle the issues with overlay UI resizing and screen redraws, as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just because there is asynchronous behavior happening somewhere doesn't mean it's suitable to use an asynchronous solution for this particular problem.
In this particular case you are avoiding moving logic out of the game module (which we are in dire need of) and creating a new header by adding a new header and replacing a simple method call with indirection through the OS.
If you want to add support for handling external signals, cool, do that.
Even if we have signal support it is not ok to do communication between different parts of the program with signals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the merge blocker on this the ui code being moved out of game? As far as I can tell, that requires changing the ownership of the windows, which affects all of the ui code using g->w_whatever, as well as requiring some serious changes to game itself.
That'd turn a small feature PR into a massive refactor PR, wouldn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the problem is just the new inclusion of game.h, you can just add a function that accepts no arguments and unconditionally invokes the g->init_ui(), and a later cleanup can move more code into that module.
I probably would have done it for you if I had time at the moment.
Tiles builds seems to be broken now: http://ci.narc.ro/job/Cataclysm-Matrix/7409/Graphics=Tiles,Platform=Windows/console |
Overlay UIs, including the main menu, are not resized properly if active. I'd say that's a seperate, resultant issue, and outside the scope of this PR.
Closes #933