From 23077d0291426037b6b120cf765664b4487c9330 Mon Sep 17 00:00:00 2001 From: Leifa <26681464+TrickyLeifa@users.noreply.github.com> Date: Sat, 13 Jul 2024 15:31:51 +0200 Subject: Resize mode patch (#1019) * Fix transformation mode for layers Resolve #997 * always use smooth transform resampling for stretched images * Used fixed frame size * Implemented resize mode changes Resolve #999 * Added alias to pixel resize mode * Added user option --------- Co-authored-by: in1tiate <32779090+in1tiate@users.noreply.github.com> --- data/ui/options_dialog.ui | 503 +++++++++++++++++++++------------------- src/animationlayer.cpp | 28 ++- src/animationlayer.h | 5 +- src/aoapplication.h | 4 +- src/courtroom.cpp | 6 +- src/datatypes.h | 7 + src/options.cpp | 20 +- src/options.h | 9 +- src/text_file_functions.cpp | 31 +-- src/widgets/aooptionsdialog.cpp | 22 +- src/widgets/aooptionsdialog.h | 3 +- 11 files changed, 341 insertions(+), 297 deletions(-) diff --git a/data/ui/options_dialog.ui b/data/ui/options_dialog.ui index bcdb7a44..882092ea 100644 --- a/data/ui/options_dialog.ui +++ b/data/ui/options_dialog.ui @@ -39,93 +39,122 @@ 0 - -555 + -385 394 - 872 + 878 - - + + + + Sets the theme used in-game. If the new theme changes the lobby's look as well, you'll need to reload the Lobby for the changes to take effect, such as by joining a server and leaving it. + - + Theme: - - + + + + + - Stop music when double-clicking a category. If this is disabled, use the right-click context menu to stop music. + Sets a 'subtheme', which will stack on top of the current theme and replace anything it can. Keep it at 'server' to let the server decide. Keep it at 'default' to keep it unchanging. - Stop Music w/ Category: + Subtheme: - - + + + + + + + Refresh the theme and update all of the ui elements to match. + - + Reload Theme - - - - - + + - Sets the default scaling method, if there is not one already defined specifically for the character. + Open the theme folder of the currently selected theme. - Scaling: + Open Theme Folder - - + + - Turn this on to allow characters to define their own custom chat box designs. + <html><head/><body><p>The factor by which to scale the size of the UI</p></body></html> - Custom Chatboxes: + UI Scaling Factor - - + + + + 1 + + + 8 + + + + + - Allows screen effects. Disable this if you have concerns or issues with photosensitivity and/or seizures. + If ticked, themes will be allowed to have animated elements. - Allow Effects: + Animated Theme: - - + + - - - - Open the theme folder of the currently selected theme. + + + + QFrame::HLine - - Open Theme Folder + + QFrame::Sunken - - + + - Overrides the base URL to retrieve server information from. + Minimum amount of time (in miliseconds) an IC message must stay on screen before the next IC message is shown, acting as a 'queue'. Set to 0 to disable this behavior. - Alternate Server List: + Text Stay Time: + + + + + + + ms + + + 10000 @@ -136,39 +165,30 @@ - - - - ms - - - 500 + + + + - - + + - Sets the theme used in-game. If the new theme changes the lobby's look as well, you'll need to reload the Lobby for the changes to take effect, such as by joining a server and leaving it. + Amount of time (in miliseconds) spent on each letter when the in-character text is being displayed. - Theme: + Text crawl: - - - - - - - - - - Send screen-shaking, flashes and sounds as defined in the char.ini over the network. Only works for servers that support this functionality. + + + + ms - - Network Frame Effects: + + 500 @@ -192,41 +212,45 @@ - - - - If ticked, themes will be allowed to have animated elements. + + + + QFrame::HLine - - Animated Theme: + + QFrame::Sunken - - + + - Amount of time (in miliseconds) spent on each letter when the in-character text is being displayed. + Your OOC name will be automatically set to this value when you join a server. - Text crawl: + Default username: - - + + + + 30 + + + + + - Refresh the theme and update all of the ui elements to match. + Gives the default value for the in-game 'Custom shownames' tickbox, which in turn determines whether the client should display custom in-character names. - Reload Theme + Custom shownames: - - - - - + + @@ -242,111 +266,103 @@ - - - - + + + + + + + QFrame::HLine + + + QFrame::Sunken - - - - - + + - Turn this on to allow characters to define their own stickers (unique images that show up over the chatbox - like avatars or shownames). + Overrides the base URL to retrieve server information from. - Stickers: + Alternate Server List: - - + + + + + - Turn this on to prevent preanimation checkbox from clearing after playing the emote. + Allows others on Discord to see what server you are in, what character are you playing, and how long you have been playing for. - Sticky Preanims: + Discord: - - - - ms - - - 10000 + + + + - - + + - Gives the default value for the in-game 'Custom shownames' tickbox, which in turn determines whether the client should display custom in-character names. + Sets the language if you don't want to use your system language. - Custom shownames: + Language: - - + + + + + - Turn this on to prevent the effects dropdown from clearing the effect after playing it. + Allows screenshaking. Disable this if you have concerns or issues with photosensitivity and/or seizures. - Sticky Effects: + Allow Screenshake: - - + + - - - - Minimum amount of time (in miliseconds) an IC message must stay on screen before the next IC message is shown, acting as a 'queue'. Set to 0 to disable this behavior. - - - Text Stay Time: - - - - - + + - Sets the language if you don't want to use your system language. + Allows screen effects. Disable this if you have concerns or issues with photosensitivity and/or seizures. - Language: + Allow Effects: - - + + - - - - + + + + Send screen-shaking, flashes and sounds as defined in the char.ini over the network. Only works for servers that support this functionality. - - - - - + Network Frame Effects: @@ -357,13 +373,20 @@ - - + + - If the SFX dropdown has an SFX selected, send the custom SFX alongside the message even if Preanim is OFF. + Use the markup colors in the server IC chatlog. - Always Send SFX: + Colors in IC Log: + + + + + + + @@ -377,182 +400,146 @@ - - + + - - - - Your OOC name will be automatically set to this value when you join a server. - - - Default username: - - - - - + + - Allows screenshaking. Disable this if you have concerns or issues with photosensitivity and/or seizures. + Turn this on to prevent the effects dropdown from clearing the effect after playing it. - Allow Screenshake: + Sticky Effects: - - + + - - + + - Allows others on Discord to see what server you are in, what character are you playing, and how long you have been playing for. + Turn this on to prevent preanimation checkbox from clearing after playing the emote. - Discord: + Sticky Preanims: - - - - Use the markup colors in the server IC chatlog. - + + - Colors in IC Log: + - - + + - Sets a 'subtheme', which will stack on top of the current theme and replace anything it can. Keep it at 'server' to let the server decide. Keep it at 'default' to keep it unchanging. + Turn this on to allow characters to define their own custom chat box designs. - Subtheme: + Custom Chatboxes: - - + + - - + + + + Turn this on to allow characters to define their own stickers (unique images that show up over the chatbox - like avatars or shownames). + - + Stickers: - - + + - - - - - - - QFrame::HLine - - - QFrame::Sunken - - - - - - - QFrame::HLine + + + + Whether or not to resume playing animations from where they left off. Turning off might reduce lag. - - QFrame::Sunken + + Continuous Playback: - - + + - - + + - If ticked, Evidence needs a double-click to view rather than a single click. + Stop music when double-clicking a category. If this is disabled, use the right-click context menu to stop music. - Evidence Double Click: - - - - - - - QFrame::HLine - - - QFrame::Sunken + Stop Music w/ Category: - - + + - - + + - Whether or not to resume playing animations from where they left off. Turning off might reduce lag. + If the SFX dropdown has an SFX selected, send the custom SFX alongside the message even if Preanim is OFF. - Continuous Playback: + Always Send SFX: - - - - 30 + + + + - - - - 1 + + + + If ticked, Evidence needs a double-click to view rather than a single click. - - 8 + + Evidence Double Click: - - - - <html><head/><body><p>The factor by which to scale the size of the UI</p></body></html> - + + - UI Scaling Factor + @@ -573,14 +560,14 @@ - + - + If ticked, some windows restore their last known position where they were closed. @@ -590,6 +577,38 @@ + + + + <html><head/><body><p>The scaling algorithm to be used when upscaling or downscaling images.</p><p>Automatic: The image will be scaled based on the image's predetermined scaling algorithm.<br/>Pixelated: The image will be scaled using a nearest neighbor algorithm.<br/>Smooth: The image will be scaled using a bilinear algorithm.</p></body></html> + + + Image Scaling + + + + + + + <html><head/><body><p>The scaling algorithm to be used when upscaling or downscaling images.</p><p>Automatic: The image will be scaled based on the image's predetermined scaling algorithm.<br/>Pixelated: The image will be scaled using a nearest neighbor algorithm.<br/>Smooth: The image will be scaled using a bilinear algorithm.</p></body></html> + + + + Automatic + + + + + Pixelated + + + + + Smooth + + + + @@ -944,7 +963,7 @@ Use this when you have added an asset that takes precedence over another existin - If ticked, new messages will appear separated, with the message coming on the next line after the name. + If ticked, new messages will appear separated, with the message coming on the next line after the name. When unticked, it displays it as 'name: message'. @@ -962,7 +981,7 @@ When unticked, it displays it as 'name: message'. - The distance in pixels between each entry in the IC log. + The distance in pixels between each entry in the IC log. Default: 0. diff --git a/src/animationlayer.cpp b/src/animationlayer.cpp index 9e771246..a1084eda 100644 --- a/src/animationlayer.cpp +++ b/src/animationlayer.cpp @@ -168,9 +168,9 @@ void AnimationLayer::setFlipped(bool enabled) m_flipped = enabled; } -void AnimationLayer::setTransformationMode(Qt::TransformationMode mode) +void AnimationLayer::setResizeMode(RESIZE_MODE mode) { - m_transformation_mode_hint = mode; + m_resize_mode = mode; } void AnimationLayer::setMinimumDurationPerFrame(int duration) @@ -229,7 +229,7 @@ void AnimationLayer::calculateFrameGeometry() { m_mask_rect = QRect(); m_scaled_frame_size = QSize(); - m_transformation_mode = m_transformation_mode_hint; + m_transformation_mode = Qt::SmoothTransformation; QSize widget_size = size(); if (!widget_size.isValid() || !m_frame_size.isValid()) @@ -240,7 +240,6 @@ void AnimationLayer::calculateFrameGeometry() if (m_stretch_to_fit) { m_scaled_frame_size = widget_size; - m_transformation_mode = Qt::SmoothTransformation; } else { @@ -253,11 +252,20 @@ void AnimationLayer::calculateFrameGeometry() double scale = double(widget_size.height()) / double(m_scaled_frame_size.height()); m_scaled_frame_size *= scale; + + if (m_frame_size.height() < widget_size.height()) + { + m_transformation_mode = Qt::FastTransformation; + } } - if (m_transformation_mode_hint == Qt::FastTransformation) + if (m_resize_mode == PIXEL_RESIZE_MODE) { - m_transformation_mode = widget_size.height() < m_frame_size.height() ? Qt::SmoothTransformation : Qt::FastTransformation; + m_transformation_mode = Qt::FastTransformation; + } + else if (m_resize_mode == SMOOTH_RESIZE_MODE) + { + m_transformation_mode = Qt::SmoothTransformation; } displayCurrentFrame(); @@ -451,7 +459,7 @@ void CharacterAnimationLayer::loadCharacterEmote(QString character, QString file setFileName(file_path); setPlayOnce(play_once); - setTransformationMode(ao_app->get_scaling(ao_app->get_emote_property(character, fileName, "scaling"))); + setResizeMode(ao_app->get_scaling(ao_app->get_emote_property(character, fileName, "scaling"))); setStretchToFit(ao_app->get_emote_property(character, fileName, "stretch").startsWith("true")); if (synchronize_frame && previous_frame_count == frameCount()) { @@ -600,7 +608,7 @@ void BackgroundAnimationLayer::loadAndPlayAnimation(QString fileName) } VPath design_path = ao_app->get_background_path("design.ini"); - setTransformationMode(ao_app->get_scaling(ao_app->read_design_ini("scaling", design_path))); + setResizeMode(ao_app->get_scaling(ao_app->read_design_ini("scaling", design_path))); setStretchToFit(ao_app->read_design_ini("stretch", design_path).startsWith("true")); if (is_different_file) @@ -621,7 +629,7 @@ void SplashAnimationLayer::loadAndPlayAnimation(QString p_filename, QString p_ch { QString file_path = ao_app->get_image(p_filename, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname, p_charname, "placeholder"); setFileName(file_path); - setTransformationMode(ao_app->get_misc_scaling(p_miscname)); + setResizeMode(ao_app->get_misc_scaling(p_miscname)); startPlayback(); } @@ -688,7 +696,7 @@ void StickerAnimationLayer::loadAndPlayAnimation(QString fileName) QString file_path = ao_app->get_image("sticker/" + fileName, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, misc_file); setFileName(file_path); - setTransformationMode(ao_app->get_misc_scaling(misc_file)); + setResizeMode(ao_app->get_misc_scaling(misc_file)); startPlayback(); } } // namespace kal diff --git a/src/animationlayer.h b/src/animationlayer.h index c0d9332f..79ffcfa6 100644 --- a/src/animationlayer.h +++ b/src/animationlayer.h @@ -1,6 +1,7 @@ #pragma once #include "animationloader.h" +#include "datatypes.h" #include #include @@ -68,7 +69,7 @@ public: void setStretchToFit(bool enabled); void setResetCacheWhenStopped(bool enabled); void setFlipped(bool enabled); - void setTransformationMode(Qt::TransformationMode mode); + void setResizeMode(RESIZE_MODE mode); void setMinimumDurationPerFrame(int duration); void setMaximumDurationPerFrame(int duration); @@ -92,7 +93,7 @@ private: bool m_flipped = false; int m_minimum_duration = 0; int m_maximum_duration = 0; - Qt::TransformationMode m_transformation_mode_hint = Qt::FastTransformation; + RESIZE_MODE m_resize_mode = AUTO_RESIZE_MODE; Qt::TransformationMode m_transformation_mode = Qt::FastTransformation; AnimationLoader *m_loader = nullptr; QSize m_frame_size; diff --git a/src/aoapplication.h b/src/aoapplication.h index e90579de..d040408d 100644 --- a/src/aoapplication.h +++ b/src/aoapplication.h @@ -307,10 +307,10 @@ public: QString get_emote_property(QString p_char, QString p_emote, QString p_property); // Return a transformation mode from a string ("smooth" for smooth, anything else for fast) - Qt::TransformationMode get_scaling(QString p_scaling); + RESIZE_MODE get_scaling(QString p_scaling); // Returns the scaling type for p_miscname - Qt::TransformationMode get_misc_scaling(QString p_miscname); + RESIZE_MODE get_misc_scaling(QString p_miscname); // ====== // These are all casing-related settings. diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 6def0b5e..cea7ba07 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -159,7 +159,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) ui_music_list->setObjectName("ui_music_list"); ui_music_display = new kal::InterfaceAnimationLayer(ao_app, this); - ui_music_display->setTransformationMode(Qt::SmoothTransformation); + ui_music_display->setResizeMode(SMOOTH_RESIZE_MODE); ui_music_display->setAttribute(Qt::WA_TransparentForMouseEvents); ui_music_display->setObjectName("ui_music_display"); @@ -3152,8 +3152,8 @@ void Courtroom::do_effect(QString fx_path, QString fx_sound, QString p_char, QSt { return; } - ui_vp_effect->setTransformationMode(ao_app->get_scaling(ao_app->get_effect_property(fx_path, p_char, p_folder, "scaling"))); ui_vp_effect->setStretchToFit(ao_app->get_effect_property(fx_path, p_char, p_folder, "stretch").startsWith("true")); + ui_vp_effect->setResizeMode(ao_app->get_scaling(ao_app->get_effect_property(fx_path, p_char, p_folder, "scaling"))); ui_vp_effect->setFlipped(ao_app->get_effect_property(fx_path, p_char, p_folder, "respect_flip").startsWith("true") && m_chatmessage[FLIP].toInt() == 1); bool looping = ao_app->get_effect_property(fx_path, p_char, p_folder, "loop").startsWith("true"); @@ -4221,7 +4221,7 @@ void Courtroom::chat_tick() f_char = m_chatmessage[CHAR_NAME]; f_custom_theme = ao_app->get_chat(f_char); } - ui_vp_chat_arrow->setTransformationMode(ao_app->get_misc_scaling(f_custom_theme)); + ui_vp_chat_arrow->setResizeMode(ao_app->get_misc_scaling(f_custom_theme)); ui_vp_chat_arrow->loadAndPlayAnimation("chat_arrow", f_custom_theme); // Chat stopped being processed, indicate that. QString f_message_filtered = filter_ic_text(f_message, true, -1, m_chatmessage[TEXT_COLOR].toInt()); if (Options::getInstance().customChatboxEnabled()) diff --git a/src/datatypes.h b/src/datatypes.h index 30b384e8..0bc6b20f 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -99,6 +99,13 @@ enum MUSIC_EFFECT SYNC_POS = 4 }; +enum RESIZE_MODE +{ + AUTO_RESIZE_MODE, + PIXEL_RESIZE_MODE, + SMOOTH_RESIZE_MODE, +}; + class PlayerData { public: diff --git a/src/options.cpp b/src/options.cpp index fbcf01e2..3af8b5d7 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -550,16 +550,6 @@ void Options::setAnimatedThemeEnabled(bool value) config.setValue("animated_theme", value); } -QString Options::defaultScalingMode() const -{ - return config.value("default_scaling", "fast").toString(); -} - -void Options::setDefaultScalingMode(QString value) -{ - config.setValue("default_scaling", value); -} - QStringList Options::mountPaths() const { return config.value("mount_paths").value(); @@ -620,6 +610,16 @@ void Options::setLanguage(QString value) config.setValue("language", value); } +RESIZE_MODE Options::resizeMode() const +{ + return RESIZE_MODE(config.value("resize_mode", AUTO_RESIZE_MODE).toInt()); +} + +void Options::setResizeMode(RESIZE_MODE value) +{ + config.setValue("resize_mode", value); +} + QStringList Options::callwords() const { QStringList l_callwords = config.value("callwords", QStringList{}).toStringList(); diff --git a/src/options.h b/src/options.h index f28dfcd3..f96f994b 100644 --- a/src/options.h +++ b/src/options.h @@ -1,5 +1,6 @@ #pragma once +#include "datatypes.h" #include "network/serverinfo.h" #include @@ -224,10 +225,6 @@ public: bool animatedThemeEnabled() const; void setAnimatedThemeEnabled(bool value); - // Get the default scaling method - QString defaultScalingMode() const; - void setDefaultScalingMode(QString value); - // Get a list of custom mount paths QStringList mountPaths() const; void setMountPaths(QStringList value); @@ -252,6 +249,10 @@ public: QString language() const; void setLanguage(QString value); + // The scaling algorithm to use on images. + RESIZE_MODE resizeMode() const; + void setResizeMode(RESIZE_MODE value); + // Callwords notify the user when the word/words are used in a game message. QStringList callwords() const; void setCallwords(QStringList value); diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index 763efb58..97e632e3 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -175,18 +175,22 @@ QString AOApplication::read_design_ini(QString p_identifier, QString p_design_pa return ""; } -Qt::TransformationMode AOApplication::get_scaling(QString p_scaling) +RESIZE_MODE AOApplication::get_scaling(QString p_scaling) { - if (p_scaling.isEmpty()) + RESIZE_MODE mode = Options::getInstance().resizeMode(); + if (mode == AUTO_RESIZE_MODE) { - p_scaling = Options::getInstance().defaultScalingMode(); + if (p_scaling == "smooth") + { + mode = SMOOTH_RESIZE_MODE; + } + else if (p_scaling == "pixel" || p_scaling == "fast") + { + mode = PIXEL_RESIZE_MODE; + } } - if (p_scaling == "smooth") - { - return Qt::SmoothTransformation; - } - return Qt::FastTransformation; + return mode; } QPoint AOApplication::get_button_spacing(QString p_identifier, QString p_file) @@ -536,7 +540,7 @@ QString AOApplication::get_emote_property(QString p_char, QString p_emote, QStri return f_result; } -Qt::TransformationMode AOApplication::get_misc_scaling(QString p_miscname) +RESIZE_MODE AOApplication::get_misc_scaling(QString p_miscname) { if (p_miscname != "") { @@ -545,12 +549,11 @@ Qt::TransformationMode AOApplication::get_misc_scaling(QString p_miscname) { misc_transform_mode = read_design_ini("scaling", get_misc_path(p_miscname, "config.ini")); } - if (misc_transform_mode == "smooth") - { - return Qt::SmoothTransformation; - } + + return get_scaling(misc_transform_mode); } - return Qt::FastTransformation; + + return AUTO_RESIZE_MODE; } QString AOApplication::get_category(QString p_char) diff --git a/src/widgets/aooptionsdialog.cpp b/src/widgets/aooptionsdialog.cpp index db3c8788..2c7b4e28 100644 --- a/src/widgets/aooptionsdialog.cpp +++ b/src/widgets/aooptionsdialog.cpp @@ -111,12 +111,24 @@ void AOOptionsDialog::setWidgetData(QComboBox *widget, const QString &value) qWarning() << "value" << value << "not found for widget" << widget->objectName(); } +template <> +void AOOptionsDialog::setWidgetData(QComboBox *widget, const RESIZE_MODE &value) +{ + widget->setCurrentIndex(value); +} + template <> QString AOOptionsDialog::widgetData(QComboBox *widget) const { return widget->currentData().toString(); } +template <> +RESIZE_MODE AOOptionsDialog::widgetData(QComboBox *widget) const +{ + return RESIZE_MODE(widget->currentIndex()); +} + template <> void AOOptionsDialog::setWidgetData(QGroupBox *widget, const bool &value) { @@ -344,7 +356,7 @@ void AOOptionsDialog::setupUI() FROM_UI(QLineEdit, ms_textbox); FROM_UI(QCheckBox, discord_cb); FROM_UI(QComboBox, language_combobox); - FROM_UI(QComboBox, scaling_combobox); + FROM_UI(QComboBox, resize_combobox); FROM_UI(QCheckBox, shake_cb); FROM_UI(QCheckBox, effects_cb); FROM_UI(QCheckBox, framenetwork_cb); @@ -382,13 +394,7 @@ void AOOptionsDialog::setupUI() ui_language_combobox->addItem("日本語", "jp"); ui_language_combobox->addItem("Русский", "ru"); - registerOption("scaling_combobox", &Options::defaultScalingMode, &Options::setDefaultScalingMode); - - // Populate scaling dropdown. This is necessary as we need the user data - // embeeded into the entry. - ui_scaling_combobox->addItem(tr("Pixel"), "fast"); - ui_scaling_combobox->addItem(tr("Smooth"), "smooth"); - + registerOption("resize_combobox", &Options::resizeMode, &Options::setResizeMode); registerOption("shake_cb", &Options::shakeEnabled, &Options::setShakeEnabled); registerOption("effects_cb", &Options::effectsEnabled, &Options::setEffectsEnabled); registerOption("framenetwork_cb", &Options::networkedFrameSfxEnabled, &Options::setNetworkedFrameSfxEnabled); diff --git a/src/widgets/aooptionsdialog.h b/src/widgets/aooptionsdialog.h index eb64a539..20c95a3f 100644 --- a/src/widgets/aooptionsdialog.h +++ b/src/widgets/aooptionsdialog.h @@ -63,8 +63,7 @@ private: QCheckBox *ui_discord_cb; QLabel *ui_language_label; QComboBox *ui_language_combobox; - QLabel *ui_scaling_label; - QComboBox *ui_scaling_combobox; + QComboBox *ui_resize_combobox; QCheckBox *ui_shake_cb; QCheckBox *ui_effects_cb; QCheckBox *ui_framenetwork_cb; -- cgit