Skip to content
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

Fullscreen enhancements (2563) & dynamic buttons #2577

Merged

Conversation

j-gynn
Copy link
Contributor

@j-gynn j-gynn commented Jul 8, 2024

About The Pull Request

So this started out as fullscreen enhancements and... spiralled.

Summary of Key Changes

  • NEW: subclassed UIManager to allow it to control only a portion of the screen (therefore allowing the game to be offset to the center of the user's screen without having to rewrite every single line of code in the entire codebase).

  • NEW: UISurfaceImageButton. This is a button subclass that accepts a dictionary of surfaces as the button images. It is totally theme-safe, can be reloaded & modified by the manager (update text etc.) and the surfaces stay intact.

  • NEW: Procedurally generated buttons! There are a variety of flavours to suit the various places that buttons live in. It currently uses a kind of "three tile system", similar to a nine-tile system without a Y axis. This means buttons can be any length you want, but their height is locked - no multiline buttons currently. Here's a list of available buttons and what they look like:

    • SQUOVAL - the default button shape, you might prefer to call this "pill" or squircle... but squoval sparks joy so here we are
      image

    • ROUNDED_RECT - the squarish button
      image

    • DROPDOWN - Box edition
      image

    • MAINMENU - Th- the main menu buttons.
      image

    • MENU_LEFT, MENU_MIDDLE, MENU_RIGHT - the little units that make up a lot of our headers
      image

    • HORIZONTAL_TAB - used for tabbing horizontally, not sure what you want from me ;) Not used in many of the places it can go, mostly because I'm not super happy with the implementation. Text doesn't move during the state changes, so they look a little... flat. It's more noticeable with the vertical tab, which is why that has been entirely shelved for now.

      Note that buttons with unique styling or unique elements (blood, scratches, etc.) are not covered in this rework as they will require a much more nuanced approach. I have also not included the "ladder dropdowns" as there are some that are multiple lines long and this approach can only handle buttons with one row of text.

  • NEW: The ClanGen font has had a bit of a spring-clean. Adjustment of some of the letters and their spacing, plus the addition of several constructors for arrows of arbitrary length using Unicode.

    • add_arrow allows an arrow to be inserted into any text box using the ClanGen font. It can create an arrow in lengths from 2 to infinity in steps of 0.5, with an additional option at length 1. All this to say, you'll probably have to eyeball exactly how big to make them, but the back_button uses an arrow length of 3.
  • Screen scaling is now relative to 1x screen dimensions rather than 2x. This is probably what accounts for 50% of the line changes in this PR, as you will note that every single dimension is now half of what it was.

  • NEW: added/updated scaling functions to work with the aforementioned scaling changes.

    • ui_scale (formerly scale) - 90% of use cases want this. It takes a pygame.Rect and scales it accordingly - appropriately scaling negative values for offsets (as anchors can use those) but not scaling negative dimensions as that indicates dynamic scaling.
    • ui_scale_offset - This is essentially the first two values of a pygame.Rect. Scales negative values.
    • ui_scale_dimensions - This is essentially the last two values of a pygame.Rect. Does not scale negative values.
    • ui_scale_value - Acts like a single value of ui_scale_dimensions (DOES scale negatives). Try not to use this - I've found it has to be used most when there's some really cursed screen building going on.
    • ui_scale_blit - Special function to allow for blitting images to the background at the right place whilst accounting for any fullscreen offset.
  • NEW: The background of a screen is now handled by a handful of functions owned by the superclass.

    • add_bgs accepts a dictionary of names and pygame.Surfaces and, optionally, a dictionary that may contain one or more matching names to the first dictionary - this contains the background for fullscreen mode. If one is not provided, the game will take the main background, stretch and blur it to fill the space (see images).
    • set_bg accepts one of the names from the dictionary and sets it as the active background. A value of None can be passed to it - if so, it automatically defaults to the appropriate default background for the current theme (light mode or dark mode).
    • show_bg is called every frame and is used to redraw the background. If in fullscreen, it will blit the fullscreen background too, but if it isn't visible then for performance reasons it isn't blitted. No need.
  • Combined all the theming files into one file. This might annoy some of you, but there is no reason for them to be split up the way they were - it made it hard to find things you were looking for.

    • That said, anything themeish that needs scaling with the UI is stored in resources/theme/fonts/master_screen_scale.json. This is because the game will automagically scale this to the right size on demand and reload it when the user changes screen dimensions. It can't be part of the same file as otherwise things like border thicknesses and corner rounds would also get messed with.
    • To use this new theming setup, ensure that both themes are named the same. The UI scaling theme file will override the base in the event they contain the same keys (e.g. both contain a "dark_bg" colour - the UI scaling file's BG will be the one that displays).
  • NEW: You can toggle between fullscreen and windowed mode without the game crashing to desktop now!

  • NEW: ConfirmDisplayChanges window now appears when you swap display mode. It's a timeout function: if you don't close it within 5 seconds, the changes are reverted.

  • NEW: Fixed windows.py to use the existing functionality of UIWindow to handle blocking input to other buttons. In other words, game.switches["window_open"] is no more. Going forward, ensure that process_event on any UIWindow concludes by return super().process_event(), thereby using the is_blocking functionality that they're built with.

  • Moved the screen settings functions (newly-made toggle_fullscreen and load_manager) out of game_essentials and into scripts/game_structure/screen_settings. This is to facilitate the possibility of loading the UI sooner in the load order so that there's not that big black screen for like 5 seconds on starting the game. Not currently implemented but I really, really wanna do it.

  • Made some fixes to some of the most confusing Screens layouts so that they'll work with dynamic scaling. I tried to leave things alone as much as possible, but... this was so, so much easier. Please use anchors, dynamic scaling and mathematics will thank you.

  • Added try:except wrapping around the save_settings() function to remove the onus from the end-user. It now accepts the calling screen as an argument, which it can use to return the user to the start screen to display an error message.

  • Updated UIImageButton to always have @image_button as the class ID if a string/None value is passed in. This can be overridden by passing in an ObjectID-type item if desired.

  • Cleaned up some parts of the SettingsScreen with the tooltips over credits - these really need refactoring, it's kind of a mess.

  • Added the anchors field to UIModifiedScrollingContainer and IDImageButton to take advantage of anchoring for dynamic screen positioning. This already exists on the superclass, I'm just exposing it again.

  • Due to the way the ingame toggle_fullscreen works, I've had to move the menu_buttons generation to a function that can be called again. We basically kill everything to start again.

Known Issues/Limitations

  • ClanGen font has become very thin. not sure why.
  • I haven't been able to convert all eligible buttons to using the dynamic enbuttoning.
    • Pronouns use the CatButton to store a bit of extra data in there.
    • Leader's Den does some quirky stuff with the object ID - fixed it for outsiders but not for other_clan
    • One of the ladders has to stay because of strange things with exile buttons that we cycle through.

Why This Is Good For ClanGen

Fullscreen has languished a little bit and been undesirable to play on due to the "crunchiness". Hopefully this resolves that!

Linked Issues

Closes #2563
Closes #2603
Closes #2627

Proof of Testing

image
(running on 125% zoom @ 1920 x 1080 - game running at 1x scale)
image
(running on 100% zoom @ 1920 x 1080 - game running at 1.5x scale)

Link to the Discord testing channel

Changelog/Credits

Fullscreen rework & Dynamic Buttons Part 1

j-gynn added 30 commits June 30, 2024 22:27
…an offset. Begun the process of fixing blits.
… super().on_use first now. Added a frame around the main game
… font work by moving everything and deleting the paths
# Conflicts:
#	scripts/game_structure/ui_elements.py
#	scripts/screens/ChooseMentorScreen.py
#	scripts/screens/ListScreen.py
# Conflicts:
#	resources/placements.json
#	scripts/screens/ChangeGenderScreen.py
#	scripts/screens/ChooseAdoptiveParentScreen.py
#	scripts/screens/ChooseMateScreen.py
#	scripts/screens/ChooseMentorScreen.py
#	scripts/screens/ProfileScreen.py
#	scripts/screens/RelationshipScreen.py
#	scripts/screens/RoleScreen.py
#	scripts/screens/SpriteInspectScreen.py
@scribblecrumb scribblecrumb merged commit 9abf6fd into ClanGenOfficial:development Sep 30, 2024
7 checks passed
@j-gynn j-gynn deleted the 2563-fullscreen-enhancements branch September 30, 2024 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants