qxgedit-1.0.1/PaxHeaders/CMakeLists.txt0000644000000000000000000000013214772452451015007 xustar0030 mtime=1743410473.472256432 30 atime=1743410473.472256432 30 ctime=1743410473.472256432 qxgedit-1.0.1/CMakeLists.txt0000644000175000001440000001151114772452451014776 0ustar00rncbcuserscmake_minimum_required (VERSION 3.15) project (QXGEdit VERSION 1.0.1 DESCRIPTION "Qt XG Editor" HOMEPAGE_URL "https://qxgedit.sourceforge.io" LANGUAGES C CXX) set (PROJECT_TITLE "${PROJECT_NAME}") string (TOLOWER "${PROJECT_TITLE}" PROJECT_NAME) set (PROJECT_COPYRIGHT "Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved.") set (PROJECT_DOMAIN "rncbc.org") execute_process ( COMMAND git describe --tags --dirty --abbrev=6 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_DESCRIBE_OUTPUT RESULT_VARIABLE GIT_DESCRIBE_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE) if (GIT_DESCRIBE_RESULT EQUAL 0) set (GIT_VERSION "${GIT_DESCRIBE_OUTPUT}") string (REGEX REPLACE "^[^0-9]+" "" GIT_VERSION "${GIT_VERSION}") string (REGEX REPLACE "-g" "git." GIT_VERSION "${GIT_VERSION}") string (REGEX REPLACE "[_|-]" "." GIT_VERSION "${GIT_VERSION}") execute_process ( COMMAND git rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_REVPARSE_OUTPUT RESULT_VARIABLE GIT_REVPARSE_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE) if (GIT_REVPARSE_RESULT EQUAL 0 AND NOT GIT_REVPARSE_OUTPUT STREQUAL "main") set (GIT_VERSION "${GIT_VERSION} [${GIT_REVPARSE_OUTPUT}]") endif () set (PROJECT_VERSION "${GIT_VERSION}") endif () if (CMAKE_BUILD_TYPE MATCHES "Debug") set (CONFIG_DEBUG 1) set (CONFIG_BUILD_TYPE "debug") else () set (CONFIG_DEBUG 0) set (CONFIG_BUILD_TYPE "release") set (CMAKE_BUILD_TYPE "Release") endif () set (CONFIG_PREFIX "${CMAKE_INSTALL_PREFIX}") include (GNUInstallDirs) set (CONFIG_BINDIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_BINDIR}") set (CONFIG_LIBDIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_LIBDIR}") set (CONFIG_DATADIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_DATADIR}") set (CONFIG_MANDIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_MANDIR}") # Enable ALSA Sequencer native support option. option (CONFIG_ALSA_MIDI "Use ALSA MIDI Sequencer native interface (default=yes)" 1) # Enable RtMidi cross-platform library support option. option (CONFIG_RTMIDI "Use RtMidi library interface (default=no)" 0) # Enable unique/single instance. option (CONFIG_XUNIQUE "Enable unique/single instance (default=yes)" 1) # Enable debugger stack-trace option (assumes --enable-debug). option (CONFIG_STACKTRACE "Enable debugger stack-trace (default=no)" 0) # Enable Wayland support option. option (CONFIG_WAYLAND "Enable Wayland support (EXPERIMENTAL) (default=no)" 0) # Enable Qt6 build preference. option (CONFIG_QT6 "Enable Qt6 build (default=yes)" 1) # Fix for new CMAKE_REQUIRED_LIBRARIES policy. if (POLICY CMP0075) cmake_policy (SET CMP0075 NEW) endif () # Check for Qt... if (CONFIG_QT6) find_package (Qt6 QUIET) if (NOT Qt6_FOUND) set (CONFIG_QT6 0) endif () endif () if (CONFIG_QT6) find_package (QT QUIET NAMES Qt6) else () find_package (QT QUIET NAMES Qt5) endif () find_package (Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Widgets Svg) if (CONFIG_XUNIQUE) find_package (Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network) endif () find_package (Qt${QT_VERSION_MAJOR}LinguistTools) include (CheckIncludeFile) include (CheckIncludeFiles) include (CheckIncludeFileCXX) include (CheckFunctionExists) include (CheckLibraryExists) # Checks for header files. if (UNIX AND NOT APPLE) check_include_files ("fcntl.h;unistd.h;signal.h" HAVE_SIGNAL_H) endif () # Find package modules include (FindPkgConfig) # Toggle whether for native ALSA or RtMmidi libraries. if (CONFIG_RTMIDI) set (CONFIG_ALSA_MIDI 0) endif () # Check for ALSA libraries. if (CONFIG_ALSA_MIDI) pkg_check_modules (ALSA REQUIRED IMPORTED_TARGET alsa) if (NOT ALSA_FOUND) message (FATAL_ERROR "*** ALSA library not found.") endif () endif () # Check for RtMIDI libraries. if (CONFIG_RTMIDI) pkg_check_modules (RTMIDI REQUIRED IMPORTED_TARGET rtmidi) if (NOT RTMIDI_FOUND) message (FATAL_ERROR "*** RtMidi library not found.") endif () endif () add_subdirectory (skulpture) add_subdirectory (src) # Finally check whether Qt is statically linked. if (QT_FEATURE_static) set(QT_VERSION "${QT_VERSION}-static") endif () # Configuration status macro (SHOW_OPTION text value) if (${value}) message ("${text}: yes") else () message ("${text}: no") endif () endmacro () message ("\n ${PROJECT_TITLE} ${PROJECT_VERSION} (Qt ${QT_VERSION})") message ("\n Build target . . . . . . . . . . . . . . . . . . .: ${CONFIG_BUILD_TYPE}\n") show_option (" ALSA MIDI Sequencer native support . . . . . . . ." CONFIG_ALSA_MIDI) show_option (" RtMidi cross-platform support (EXPERIMENTAL) . . ." CONFIG_RTMIDI) message ("") show_option (" Unique/Single instance support . . . . . . . . . ." CONFIG_XUNIQUE) show_option (" Debugger stack-trace (gdb) . . . . . . . . . . . ." CONFIG_STACKTRACE) message ("\n Install prefix . . . . . . . . . . . . . . . . . .: ${CONFIG_PREFIX}\n") qxgedit-1.0.1/PaxHeaders/ChangeLog0000644000000000000000000000013214772452451014021 xustar0030 mtime=1743410473.472256432 30 atime=1743410473.472256432 30 ctime=1743410473.472256432 qxgedit-1.0.1/ChangeLog0000644000175000001440000002500714772452451014015 0ustar00rncbcusersQXGEdit - Qt XG Editor ---------------------- ChangeLog 1.0.1 2025-03-31 An Early Spring'25 Release. - Fixed command line parsing (QCommandLineParser/Option) to not exiting the application with a segfault when showing help and version information. - Prepping up next development cycle (Qt >= 6.8) 1.0.0 2024-06-19 An Unthinkable Release. - Making up the unthinkable (aka. v1.0.0) 0.9.91 2024-05-01 A Spring'24 Release Candidate 2. - Prepping the unthinkable (aka. v1.0.0-rc2) - Updated to latest framework level (Qt >= 6.7) 0.9.90 2024-04-10 A Spring'24 Release Candidate. - Prepping the unthinkable (aka. v1.0.0-rc1) - Custom color themes are now file based (*.conf); legacy still preserved ntl. 0.9.12 2024-01-24 A Winter'24 Release. - Introducing cross-platform support via RtMidi. - Updated copyright headers into the New Year (2024). 0.9.11 2023-09-09 An End-of-Summer'23 Release. - Preppings to next development cycle (Qt >= 6.6) 0.9.10 2023-06-01 A Spring'23 Release. - Micro-adjustments to the View > Options... dialog layout. - Prepping into the next development cycle (with Qt >= 6.5). 0.9.9 2023-03-23 An Early-Spring'23 Release. - Drum Setup is being made possible for any drum-kit, with some provided default values, not just for the default Standard Kit anymore. 0.9.8 2022-12-28 An End-of-Year'22 Release. - Just bumping into the next develop cycle/season. 0.9.7 2022-10-03 An Early-Autumn'22 Release. - Add current system user-name to the singleton/unique application instance identifier. - Fixed the styles plug-ins path resolution on self-container(ized) formats eg. AppImage and possibly Flatpak. 0.9.6 2022-04-02 A Spring'22 Release. - Added missing file code to desktop exec entry. - Main application icon is now presented in scalable format (SVG). - Migrated command line parsing to QCommandLineParser/Option (Qt >= 5.2) 0.9.5 2022-01-09 A Winter'22 Release. - Dropped autotools (autoconf, automake, etc.) build system. 0.9.4 2021-07-03 An Early-Summer'21 Release. - All builds default to Qt6 (Qt >= 6.1) where available. - CMake is now the official build system. 0.9.3 2021-05-11 A Spring'21 Release. - All packaging builds switching to CMake. 0.9.2 2021-03-14 An End-of-Winter'21 Release. - Bumped version micro/dot number into the next develop cycle. 0.9.1 2021-02-07 A Winter'21 Release. - Fixed Chorus and Variation effect types, when loading from a raw SysEx file (.syx). - Early preparations for the New Year develop(ment) cycle. 0.9.0 2020-12-17 A Winter'20 Release. - Early fixing to build for Qt >= 6.0.0 and comply with C++17 standard. 0.6.3 2020-07-31 A Summer'20 Release. - Early fixing to build for Qt >= 5.15.0. 0.6.2 2020-03-24 A Spring'20 Release. - A scalable (.svg) icon version has been added. - Make man page compression reproducible (after request by Jelle van der Waa, while on the Vee-Ones, thanks). - Bumped copyright headers into the New Year (2020). 0.6.1 2019-12-22 The Winter'19 Release. - Custom color (palette) theme editor introduced; color (palette) theme changes are now effective immediately, except on default. - Second attempt to fix the yet non-official though CMake build configuration. - When using autotools and ./configure --with-qt=..., it is also necessary to adjust the PKG_CONFIG_PATH environment variable (after a merge request by plcl aka. Pedro López-Cabanillas, while on qmidinet, thanks). 0.6.0 2019-10-17 An Autumn'19 Release. - Added alternate yet non-official CMake build option. - Fix HiDPI display screen effective support (Qt >= 5.6). - Refactored all singleton/unique application instance setup logic away from X11/Xcb hackery. - Make sure compiler flags comply to c++11 as standard. 0.5.5 2019-07-12 A Summer'19 Release. - Updated for the newer Qt5 development tools (>= 5.13). - Configure updated to check for qtchooser availability. - Corrected display of note names on the lowest octave, as from "C -1" (0) through "B -1" (11). - Minor update to Debian packaging control file. 0.5.4 2019-04-11 A Spring-Break'19 Release. - Re-defined all main application UNIX signal handling. 0.5.3 2019-03-11 Pre-LAC2019 Release Frenzy. - HiDPI display screen support (Qt >= 5.6). - Old deprecated Qt4 build support is no more. - AppStream metadata updated to be the most compliant with latest freedesktop.org specification and recommendation. 0.5.2 2018-07-22 A Summer'18 Release. - AppData/AppStream metadata is now settled under an all permisssive license (FSFAP). - Corrected default handling of MULTIPART > Main > Control > Volume and also MULTIPART > Control > Pitch Bend > LFO ... - Fixed for some g++ >= 8.1.1 warnings and quietness. 0.5.1 2018-05-21 Pre-LAC2018 release frenzy. - Corrected wrong handling of the MULTIPART Detune parameter. - Trying to get CC14 MSB+LSB (course+fine) running status on, no matter whether each pairing event are under 200ms apart. - A little hardening on the configure (autoconf) macro side. 0.5.0 2017-12-16 End of Autum'17 release. - Desktop entry specification file is now finally independent from build/configure template chains. - Updated target path for freedesktop.org's AppStream metainfo file (formerly AppData). - Changing the View/Options.../General/Widget style theme now takes effect immediately unless it's to "(default)". 0.4.3 2017-04-27 Pre-LAC2017 release frenzy. - Added French man page (by Olivier Humbert, thanks). - Added one decimal digit to the randomize percentage input spin-boxes on the General Options dialog. - Make builds reproducible byte for byte, by getting rid of the configure build date and time stamps. 0.4.2 2016-11-14 A Fall'16 release. - Fixed a potential crash on the singleton/unique application instance setup. - MIDI RPN/NRPN running status and RPN NULL reset command are now supported (input only). - Almost complete overhaul on the configure script command line options, wrt. installation directories specification, eg. --prefix, --bindir, --libdir, --datadir and --mandir. - Remove extra 'Keywords' entry and fix spelling (patches by Jaromír Mikeš, thanks). 0.4.1 2016-09-14 End of Summer'16 release. - Dropped the --enable-qt5 from configure as found redundant given that's the build default anyway (suggestion by Guido Scholz, while for Qtractor, thanks). 0.4.0 2016-04-05 Spring'16 release frenzy. - Prevent x11extras module from use on non-X11/Unix plaforms. - French (fr) translations update (by Olivier Humbert, thanks). - Fixed port on MIDI 14-bit controllers input caching. 0.3.0 2015-09-21 Summer'15 release frenzy. - Single/unique application instance control adapted to Qt5/X11. - Prefer Qt5 over Qt4 by default with configure script. - Complete rewrite of Qt4 vs. Qt5 configure builds. - A new top-level widget window geometry state save and restore sub-routine is now in effect. - Added "Keywords" to desktop file; fix passing debian flags on configure (patches by Jaromír Mikeš, thanks). - Fixed for some strict tests for Qt4 vs. Qt5 configure builds. - Added application description as freedesktop.org's AppData. 0.2.0 2015-03-04 Fifth public release. - In a glance, all GUI toolbox pages converted into tabs. - Introducing a brand new user preference on eye-candy: cf. View/Options.../Display/Widget style theme. - Most graphics now rendered with anti-aliased lines. - A man page has beed added. - Allow the build system to include an user specified LDFLAGS. - Fix port origin on MIDI RPN/NRPN 14-bit controllers input. 0.1.2 2013-12-31 A fifth of a Jubilee. - A potential memory override crash-bug was flagged by gcc 4.8, on something like 'iteration 16u invokes undefined behavior [-Waggressive-loop-optimizations]' and then finally fixed. - More preparations for Qt5 configure build. - Primeval support for MIDI RPN/NRPN 14-bit controllers input. - Fixed an incremental value stickiness, which were affecting some parameters step changes from up/down spin-box widgets (eg. Master Tune). - Preparations for Qt5 migration. - Skulpture style plugin is now deployed to a rather standard location on install (default: PREFIX/qt4/plugins/styles). - Uservoice name preset drop-down list is now sorted. - MIDI note names and their respective octave numbers are now compliant with the ISO standard where middle C (60) is now C4 (was C3). - Added include to shut up gcc 4.7 build failures. - Make(ing) -jN parallel builds now available for the masses. - Updated to recent Skulpture style version 2.4.0. - Fixed Makefile.in handling of installation directories to the configure script eg. --datadir. 0.1.1 2011-09-17 Third public release. - Make sure Uservoice elements are selected only when available. - Debugging stacktrace now applies to all working threads. - libX11 is now being added explicitly to the build link phase, as seen necessary on some bleeding-edge distros eg. Fedora 13, Debian 6. - Moving from old deprecated Qt3'ish custom event post handling into regular asynchronous signal/slot strategy. - General standard dialog buttons layout is now in place. 0.1.0 2010-04-21 Second public release. - Initial widget geometry and visibility persistence logic has been slightly revised as much to avoid crash failures due to wrong main widget hidden state. - General source tree layout and build configuration change. - Make build compilation work for gcc >= 4.4.0, by adding some missing standard C99 includes. - LADISH Level 1 support has been added: SIGUSR1 signal trap just makes it a shortcut to File/Save. - Uservoice (QS300) AmpEG Attack, Decay Level 1 and 2 parameters now have a bit cleaner, clearer out-of-the-box default values. - Uservoice (QS300) preset combo-box drop-down list now gets its current item selection set alright. - Global configuration state is now explicitly saved/committed to disk when Options dialog changes are accepted and applied. - Variation part parameter is now a drop-down combo-box. - New reset button for reverb, chorus and variation parameters. - Randomization of all current vparameter values is now available, allowing for great experimentation and exploration of brand new sound settings (just try View/Randomize). - All graphics lines are now slightly gray colored, instead of plain black or white, or whatever the current theme text color. - Added user confirmation for QS300 user voice preset replacement; preset files are not deleted from file-system anymore. 0.0.1 2009-09-19 First public release. qxgedit-1.0.1/PaxHeaders/LICENSE0000644000000000000000000000013214772452451013254 xustar0030 mtime=1743410473.472256432 30 atime=1743410473.472256432 30 ctime=1743410473.472256432 qxgedit-1.0.1/LICENSE0000644000175000001440000004310314772452451013245 0ustar00rncbcusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. qxgedit-1.0.1/PaxHeaders/README0000644000000000000000000000013214772452451013127 xustar0030 mtime=1743410473.472256432 30 atime=1743410473.472256432 30 ctime=1743410473.472256432 qxgedit-1.0.1/README0000644000175000001440000000456214772452451013126 0ustar00rncbcusersQXGEdit - Qt XG Editor ---------------------- QXGEdit is a Qt GUI for editing MIDI System Exclusive files for XG devices (eg. Yamaha DB50XG). Website: https://qxgedit.sourceforge.io http://qxgedit.sourceforge.net Project page: https://sourceforge.net/projects/qxgedit Weblog: https://www.rncbc.org QXGEdit is free, open-source software, distributed under the terms of the GNU General Public License (GPL) [3] version 2 or later. Requirements ------------ The software requirements for build and runtime are listed as follows: Mandatory: [1] Qt framework, C++ class library and tools for cross-platform application and UI development https://qt.io/ [2] ALSA, Advanced Linux Sound Architecture https://www.alsa-project.org/ Optional: [3] RtMidi, A set of (cross-platform) C++ classes that provide a common API for realtime MIDI input/output. https://github.com/thestk/rtmidi Usage: cmake -DCONFIG_RTMIDI=ON ... Installation ------------ Unpack the tarball and in the extracted source directory: cmake [-DCMAKE_INSTALL_PREFIX=] -B build cmake --build build [--parallel ] and optionally, as root: [sudo] cmake --install build Note that the default installation path () is /usr/local . Configuration ------------- QXGEdit holds its settings and configuration state per user, in a file located as $HOME/.config/rncbc.org/QXGEdit.conf . Normally, there's no need to edit this file, as it is recreated and rewritten everytime qxgedit is run. Bugs ---- Plenty still although this may be considered beta software already. ;) Support ------- QXGEdit is open source free software. For bug reports, feature requests, discussion forums, mailling lists, or any other matter related to the development of this piece of software, please use the Sourceforge project page (https://sourceforge.net/projects/qxgedit). You can also find timely and closer contact information on my personal web site (https://www.rncbc.org). References ---------- [1] Qt framework, C++ class library and tools for cross-platform application and UI development https://qt.io/ [2] ALSA, Advanced Linux Sound Architecture https://www.alsa-project.org/ [3] GNU General Public License https://www.gnu.org/copyleft/gpl.html Enjoy. rncbc aka Rui Nuno Capela rncbc at rncbc dot org https://www.rncbc.org qxgedit-1.0.1/PaxHeaders/skulpture0000644000000000000000000000013214772452451014230 xustar0030 mtime=1743410473.473607941 30 atime=1743410473.472716786 30 ctime=1743410473.473607941 qxgedit-1.0.1/skulpture/0000755000175000001440000000000014772452451014275 5ustar00rncbcusersqxgedit-1.0.1/skulpture/PaxHeaders/sk_plugin.h0000644000000000000000000000013214772452451016451 xustar0030 mtime=1743410473.472882643 30 atime=1743410473.472882643 30 ctime=1743410473.472882643 qxgedit-1.0.1/skulpture/sk_plugin.h0000644000175000001440000000271014772452451016441 0ustar00rncbcusers/* * sk_plugin.h - Classical Three-Dimensional Artwork for Qt 5 * * Copyright (c) 2017-2021 rncbc aka Rui Nuno Capela * Copyright (c) 2007, 2008 Christoph Feck * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef SKULPTURE_PLUGIN_H #define SKULPTURE_PLUGIN_H 1 /*-----------------------------------------------------------------------*/ #include class SkulptureStylePlugin : public QStylePlugin { #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "skulpture.json") #endif public: QStringList keys() const; QStyle *create(const QString &key); }; /*-----------------------------------------------------------------------*/ #endif // SKULPTURE_PLUGIN_H qxgedit-1.0.1/skulpture/PaxHeaders/CMakeLists.txt0000644000000000000000000000013214772452451017045 xustar0030 mtime=1743410473.472716786 30 atime=1743410473.472716786 30 ctime=1743410473.472716786 qxgedit-1.0.1/skulpture/CMakeLists.txt0000644000175000001440000000173014772452451017036 0ustar00rncbcuserscmake_minimum_required(VERSION 3.10) set (NAME skulpturestyle) set (CMAKE_INCLUDE_CURRENT_DIR ON) set (CMAKE_AUTOUIC ON) set (CMAKE_AUTOMOC ON) set (CMAKE_AUTORCC ON) find_package (QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package (Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) set (HEADERS sk_plugin.h sk_factory.h skulpture_p.h skulpture.h ) set (SOURCES skulpture.cpp ) set (OTHER_FILES skulpture.json ) set_property (SOURCE ${SOURCES} PROPERTY SKIP_AUTOMOC ON) add_library (${NAME} MODULE ${HEADERS} ${SOURCES} ${OTHER_FILES} ) set_target_properties (${NAME} PROPERTIES CXX_STANDARD 11) target_link_libraries (${NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) if (UNIX AND NOT APPLE AND NOT CONFIG_DEBUG) add_custom_command(TARGET ${NAME} POST_BUILD COMMAND strip lib${NAME}.so) endif () if (UNIX AND NOT APPLE) install (TARGETS ${NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/qt${QT_VERSION_MAJOR}/plugins/styles) endif () qxgedit-1.0.1/skulpture/PaxHeaders/skulpture.cpp0000644000000000000000000000013214772452451017047 xustar0030 mtime=1743410473.473607941 30 atime=1743410473.472882643 30 ctime=1743410473.473607941 qxgedit-1.0.1/skulpture/skulpture.cpp0000644000175000001440000151175114772452451017052 0ustar00rncbcusers/* * Skulpture - Classical Three-Dimensional Artwork for Qt 5 * * Copyright (c) 2017-2021 rncbc aka Rui Nuno Capela * Copyright (c) 2007-2010 Christoph Feck * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ // ### This file is a mess #include "skulpture_p.h" #include #include #include #include #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) #include #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /*-----------------------------------------------------------------------*/ SkulptureStyle::SkulptureStyle() : d(new Private) { d->q = this; } SkulptureStyle::~SkulptureStyle() { delete d; } /*-----------------------------------------------------------------------*/ void SkulptureStyle::polish(QApplication *application) { // ParentStyle::polish(application); // return; #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) QString recursionCheck = QLatin1String("\n/* -skulpture-recursion-check- */\n"); if (!d->styleSheetFileName.isEmpty()) { QString oldStyle = application->styleSheet(); if (!oldStyle.contains(recursionCheck)) { QFile file(d->styleSheetFileName); if (file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); QString newStyle = stream.readAll(); application->setStyleSheet(newStyle + recursionCheck + oldStyle); } } } #endif ParentStyle::polish(application); application->installEventFilter(d->shortcut_handler); #if 0 QPalette palette; polish(palette); application->setPalette(palette); #endif // if (application->inherits("KApplication")) { // qDebug() << "KApplication is a" << application->metaObject()->className() << "(" << "object name:" << application->objectName() << ")"; // } // QFontMetrics fm = QFontMetrics(QFont()); // printf("h:%d, s:%d, xh:%d, xb:%d, Xb:%d, Xyb: %d\n", fm.height(), fm.lineSpacing(), fm.xHeight(), fm.boundingRect(QChar('x', 0)).height(), fm.boundingRect(QChar('X', 0)).height(), fm.boundingRect(QLatin1String("Xy")).height()); } void SkulptureStyle::unpolish(QApplication *application) { application->removeEventFilter(d->shortcut_handler); ParentStyle::unpolish(application); } /*-----------------------------------------------------------------------*/ enum SidebarViewMode { DefaultSidebar, TransparentSidebar }; static void polishSidebarView(QAbstractItemView *view, SidebarViewMode viewMode) { QWidget *viewport = view->viewport(); QPalette palette = view->palette(); if (viewMode == TransparentSidebar) { if (viewport->autoFillBackground()) { viewport->setAutoFillBackground(false); QPalette::ColorRole textRole = viewport->foregroundRole(); if (textRole != QPalette::WindowText) { palette.setBrush(QPalette::Active, textRole, palette.brush(QPalette::Active, QPalette::WindowText)); palette.setBrush(QPalette::Inactive, textRole, palette.brush(QPalette::Inactive, QPalette::WindowText)); palette.setBrush(QPalette::Disabled, textRole, palette.brush(QPalette::Disabled, QPalette::WindowText)); viewport->setPalette(palette); } } view->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); } else { if (viewport->autoFillBackground()) { palette.setBrush(QPalette::Active, QPalette::Window, palette.brush(QPalette::Active, QPalette::Base)); palette.setBrush(QPalette::Inactive, QPalette::Window, palette.brush(QPalette::Inactive, QPalette::Base)); palette.setBrush(QPalette::Disabled, QPalette::Window, palette.brush(QPalette::Disabled, QPalette::Base)); } else { viewport->setAutoFillBackground(true); } view->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); viewport->setPalette(palette); } } /*-----------------------------------------------------------------------*/ #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) static WidgetShadow *findShadow(QWidget *widget) { QWidget *parent = widget->parentWidget(); if (parent) { QList shadows = parent->findChildren(); Q_FOREACH (WidgetShadow *shadow, shadows) { if (shadow->widget() == widget) { return shadow; } } } return 0; } #endif void SkulptureStyle::polish(QWidget *widget) { // ParentStyle::polish(widget); // return; #if 1 //printf("polishing a \"%s\" (which is a \"%s\")\n", widget->metaObject()->className(), widget->metaObject()->superClass()->className()); #if 0 QPalette palette = widget->palette(); polish(palette); widget->setPalette(palette); #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (QMdiArea *area = qobject_cast(widget)) { area->installEventFilter(d); } if (qobject_cast(widget)) { WidgetShadow *shadow = findShadow(widget); if (!shadow) { widget->installEventFilter(d); if (widget->parentWidget()) { WidgetShadow *shadow = new WidgetShadow(widget->parentWidget()); shadow->setWidget(widget); shadow->updateZOrder(); shadow->show(); } } } #endif #if 1 if (QLCDNumber *lcd = qobject_cast(widget)) { QPalette palette; palette.setColor(QPalette::Base, QColor(220, 230, 210)); palette.setColor(QPalette::WindowText, QColor(60, 60, 60)); // lcd->setPalette(palette); // lcd->installEventFilter(d); // lcd->setContentsMargins(8, 8, 8, 8); lcd->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); lcd->setSegmentStyle(QLCDNumber::Flat); } #endif #if 1 if (QDialog *dialog = qobject_cast(widget)) { dialog->installEventFilter(d); } #endif #if 0 if (QMainWindow *window = qobject_cast(widget)) { window->setBackgroundRole(QPalette::Dark); } if (QDockWidget *dock = qobject_cast(widget)) { dock->installEventFilter(d); } if (QStatusBar *bar = qobject_cast(widget)) { bar->installEventFilter(d); } #endif if (QToolBox *toolBox = qobject_cast(widget)) { toolBox->setBackgroundRole(QPalette::Window); // toolBox->setContentsMargins(2, 2, 2, 2); // toolBox->installEventFilter(d); toolBox->layout()->setSpacing(0); } if (widget->inherits("KTitleWidget")) { // widget->setMaximumHeight(0); #if 0 QPalette palette = widget->palette(); palette.setColor(QPalette::Base, palette.color(QPalette::Window)); palette.setColor(QPalette::Text, palette.color(QPalette::WindowText)); widget->setPalette(palette); #endif } if (qobject_cast(widget)) { widget->installEventFilter(d); widget->setAttribute(Qt::WA_OpaquePaintEvent, false); } if (QFrame *frame = qobject_cast(widget)) { switch (frame->frameShape()) { case QFrame::Panel: case QFrame::WinPanel: case QFrame::Box: frame->setFrameShape(QFrame::StyledPanel); break; case QFrame::HLine: case QFrame::VLine: frame->setEnabled(false); break; default: break; } if (frame->frameShadow() == QFrame::Plain && frame->backgroundRole() == QPalette::Base) { if (frame->parentWidget() && frame->parentWidget()->inherits("KTitleWidget")) { frame->setBackgroundRole(QPalette::Window); } } #if 1 if (!strcmp(widget->metaObject()->className(), "QListWidget") && widget->parentWidget() && !strcmp(widget->parentWidget()->metaObject()->className(), "Sidebar")) { //(static_cast(widget))->setFrameStyle(QFrame::Plain | QFrame::StyledPanel); (static_cast(widget))->setFrameStyle(QFrame::NoFrame); } if (!strcmp(widget->metaObject()->className(), "Kontact::Navigator")) { // (static_cast(widget))->viewport()->setBackgroundRole(QPalette::Base); // (static_cast(widget))->viewport()->setAutoFillBackground(true); (static_cast(widget))->setFrameStyle(QFrame::Plain | QFrame::StyledPanel); // polishSidebarView(static_cast(widget), d->transparentPlacesPanel ? TransparentSidebar : DefaultSidebar); } if (widget->inherits("SidebarTreeView")) { polishSidebarView(static_cast(widget), DefaultSidebar); } if (widget->inherits("KHTMLView")) { // QPalette palette = widget->palette(); // palette.setColor(QPalette::Window, palette.color(QPalette::Base)); // ((QAbstractScrollArea *) widget)->viewport()->setPalette(palette); // printf("frame style is 0x%08x\n", ((QFrame *) widget)->frameStyle()); if (d->expensiveShadows) { (static_cast (widget))->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); } } #endif #if 1 if (widget->inherits("KFilePlacesView")) { polishSidebarView(static_cast(widget), d->transparentPlacesPanel ? TransparentSidebar : DefaultSidebar); } #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) if (widget->inherits("QPlainTextEdit")) { QPlainTextEdit *edit = static_cast(widget); // QPalette palette = edit->palette(); // palette.setColor(QPalette::Window, QColor(245, 245, 245)); // edit->setPalette(palette); // edit->viewport()->setPalette(palette); edit->setBackgroundVisible(false); edit->viewport()->installEventFilter(d); edit->installEventFilter(d); widget->setAttribute(Qt::WA_Hover, true); } #endif #if 1 if (QTextEdit *edit = qobject_cast(widget)) { #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) if (!qstrcmp(widget->metaObject()->className(), "SampleEdit")) { QWidget *bg = new QWidget(widget); bg->lower(); bg->setObjectName(QLatin1String("sample_background")); bg->setGeometry(2, 2, widget->width() - 4, widget->height() - 4); bg->setAutoFillBackground(true); bg->show(); } else #endif { //d->mapper.setMapping(edit, edit); //connect(edit, SIGNAL(textChanged()), &d->mapper, SLOT(map())); //connect(&d->mapper, SIGNAL(mapped(QWidget *)), d, SLOT(textEditSourceChanged(QWidget *))); d->updateTextEditMargins(edit); } edit->viewport()->installEventFilter(d); edit->installEventFilter(d); widget->setAttribute(Qt::WA_Hover, true); if (qstrcmp(widget->metaObject()->className(), "IRCInput")) { if (!d->allowTabulations) { edit->setTabChangesFocus(true); } } #if 0 if (QTextBrowser *browser = qobject_cast(widget)) { connect(browser, SIGNAL(sourceChanged()), &d->mapper, SLOT(map())); } #endif } #endif } #if 0 if (QComboBox *combo = qobject_cast(widget)) { if (!combo->isEditable()) { combo->setBackgroundRole(QPalette::Button); combo->setForegroundRole(QPalette::ButtonText); } } if (qobject_cast(widget) || qobject_cast(widget)) { widget->setBackgroundRole(QPalette::Window); widget->setForegroundRole(QPalette::WindowText); } #endif if (qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget)) { widget->setAttribute(Qt::WA_Hover, true); } #if 0 if (d->allowScrollBarSliderToCoverArrows && qobject_cast(widget)) { widget->installEventFilter(d); } #endif #if 0 if (widget->inherits("Q3ProgressBar")) { widget->installEventFilter(d); if (widget->isVisible()) { d->setAnimated(widget, true); } } #endif if (QProgressBar *pbar = qobject_cast(widget)) { pbar->installEventFilter(d); if (pbar->isVisible() && !widget->inherits("StatusBarSpaceInfo")) { d->setAnimated(pbar, true); } } #if 1 if (qobject_cast(widget)) { widget->installEventFilter(d); } if (QToolBar *toolbar = qobject_cast(widget)) { QFont font; font.setPointSizeF(font.pointSizeF() / (1.19)); QList children = toolbar->findChildren(); Q_FOREACH (QToolButton *child, children) { if (!child->icon().isNull()) { child->setFont(font); } } connect(toolbar, SIGNAL(orientationChanged(Qt::Orientation)), d, SLOT(updateToolBarOrientation(Qt::Orientation))); toolbar->setBackgroundRole(QPalette::Window); } if (widget->inherits("Q3ToolBar")) { widget->setBackgroundRole(QPalette::Window); } #endif #if 0 // FIXME does not work if (QMenu *menu = qobject_cast(widget)) { #if 1 QFont font; QFont oldfont; oldfont.setPointSizeF(oldfont.pointSizeF() * 1.0001); font.setPointSizeF(font.pointSizeF() / (1.19 /* * 1.19*/)); font.setBold(true); menu->setFont(font); /* QAction *action = menu->menuAction(); action->setFont(oldfont); QList children = action->findChildren(); Q_FOREACH (QAction *child, children) { child->setFont(oldfont); }*/ #else menu->setStyleSheet(QLatin1String("font-size: 6.5")/*.arg(menu->font().pointSizeF() / (1.19 * 1.19))*/); #endif } #endif #if 0 // FIXME does not work if (QGroupBox *group = qobject_cast(widget)) { QFont oldfont; #if 0 if (group->testAttribute(Qt::WA_SetFont)) { QFont oldfont = group->fontInfo(); } #endif QFont font = oldfont; font.setPointSizeF(font.pointSizeF() * 1.19); font.setBold(true); group->setFont(font); QList children = group->findChildren(); Q_FOREACH (QWidget *child, children) { if (1 || !(child->testAttribute(Qt::WA_SetFont))) { printf("reset\n"); child->setFont(oldfont); } } } #endif #if 1 if (widget->inherits("Q3Header")) { QFont font; font.setPointSizeF(font.pointSizeF() / (1.19 /* 1.19*/)); font.setBold(true); widget->setFont(font); } #endif if (QAbstractScrollArea *area = qobject_cast(widget)) { if (QAbstractItemView *iv = qobject_cast(widget)) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) // ### Qt issue // iv->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); // iv->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); // QApplication::setWheelScrollLines(64); iv = iv; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) iv->viewport()->setAttribute(Qt::WA_Hover); if (QTreeView *tree = qobject_cast(widget)) { iv->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); if (tree->uniformRowHeights()) { iv->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); } } else if (QListView *list = qobject_cast(widget)) { if (list->uniformItemSizes()) { iv->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); iv->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); } } else if (qobject_cast(widget)) { iv->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); iv->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); } #endif #if 1 if (QHeaderView *header = qobject_cast(widget)) { QFont font; font.setPointSizeF(font.pointSizeF() / (1.19 /* 1.19*/)); font.setBold(true); header->setFont(font); // FIXME workaround for Qt 4.3 header->headerDataChanged(header->orientation(), 0, 0); header->updateGeometry(); } #endif } if (area->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken)) { d->installFrameShadow(area); } } if (d->expensiveShadows) { if (widget->inherits("Konsole::TerminalDisplay") || widget->inherits("KTextEditor::View") || widget->inherits("KHTMLView")) { // ((QFrame *) widget)->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); d->installFrameShadow(widget); } } #if 0 if (widget->inherits("KTextEditor::View")) { QWidget *parent = widget->parentWidget(); if (parent) { QFrame *frame = new QFrame(parent); if (frame) { frame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); widget->setParent(frame); } } } #endif #if 1 if (widget->inherits("KCharSelectTable")) { QPalette palette; widget->setPalette(palette); } #endif #if 1 if (widget->inherits("KFadeWidgetEffect")) { widget->installEventFilter(d); } #endif if (widget->inherits("Q3ScrollView")) { QFrame *frame = qobject_cast(widget); if (frame && frame->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken)) { d->installFrameShadow(widget); } } #endif #if 0 if (QTabWidget *tab = qobject_cast(widget)) { if (QToolButton *button = qobject_cast(tab->cornerWidget(Qt::TopRightCorner))) { button->setAutoRaise(true); } if (QToolButton *button = qobject_cast(tab->cornerWidget(Qt::TopLeftCorner))) { button->setAutoRaise(true); } } #endif #if 1 if (QToolButton *button = qobject_cast(widget)) { if (qobject_cast(button->parentWidget())) { button->setAutoRaise(true); } } #endif if (!qstrcmp(widget->metaObject()->className(), "QToolBoxButton")) { widget->setAttribute(Qt::WA_Hover, true); } if (!qstrcmp(widget->metaObject()->className(), "KLineEditButton")) { widget->installEventFilter(d); widget->setAttribute(Qt::WA_Hover, true); } if (qobject_cast(widget)) { widget->unsetCursor(); widget->installEventFilter(d); widget->setMouseTracking(true); } if (QLayout *layout = widget->layout()) { // explicitely check public layout classes, QMainWindowLayout doesn't work here if (qobject_cast(layout) #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) || qobject_cast(layout) #endif || qobject_cast(layout) || qobject_cast(layout)) { d->polishLayout(layout); } } if (!qstrcmp(widget->metaObject()->className(), "InfoSidebarPage") || !qstrcmp(widget->metaObject()->className(), "InformationPanel")) { widget->installEventFilter(d); } #if 0//(QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) if (widget->inherits("KTabWidget") && widget->property("closeButtonEnabled").toBool()) { widget->setProperty("tabsClosable", true); widget->setProperty("closeButtonEnabled", false); connect(widget, SIGNAL(tabCloseRequested(int)), widget, SIGNAL(closeRequest(int))); } if (widget->inherits("KTabBar")) { widget->setProperty("tabsClosable", true); connect(widget, SIGNAL(tabCloseRequested(int)), widget, SIGNAL(closeRequest(int))); } #endif if (d->visualizeLayouts) { widget->installEventFilter(d); } ParentStyle::polish(widget); } void SkulptureStyle::unpolish(QWidget *widget) { ParentStyle::unpolish(widget); if (d->visualizeLayouts) { widget->removeEventFilter(d); } // return; if (qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) // || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget)) { widget->setAttribute(Qt::WA_Hover, false); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (qobject_cast(widget)) { widget->removeEventFilter(d); } if (QMdiSubWindow *win = qobject_cast(widget)) { win->removeEventFilter(d); WidgetShadow *shadow = findShadow(win); if (shadow) { shadow->hide(); shadow->setParent(0); shadow->deleteLater(); } } #endif #if 1 if (QDialog *dialog = qobject_cast(widget)) { dialog->removeEventFilter(d); } #endif #if 0 if (QLCDNumber *lcd = qobject_cast(widget)) { lcd->removeEventFilter(d); } if (QToolBox *toolBox = qobject_cast(widget)) { toolBox->removeEventFilter(d); } if (QDockWidget *dock = qobject_cast(widget)) { dock->removeEventFilter(d); } if (QStatusBar *status = qobject_cast(widget)) { status->removeEventFilter(d); } #endif #if 0 if (/*d->allowScrollBarSliderToCoverArrows &&*/ qobject_cast(widget)) { widget->installEventFilter(d); } #endif if (QProgressBar *pbar = qobject_cast(widget)) { pbar->removeEventFilter(d); d->setAnimated(pbar, false); return; } if (QAbstractScrollArea *area = qobject_cast(widget)) { area->removeEventFilter(d); if (/*QAbstractItemView *iv =*/qobject_cast(widget)) { #if 1 if (QHeaderView *header = qobject_cast(widget)) { QFont font; // font.setPointSizeF(font.pointSizeF() / (1.19 * 1.19)); // font.setBold(true); header->setFont(font); // FIXME workaround for Qt 4.3 header->headerDataChanged(header->orientation(), 0, 0); header->updateGeometry(); } #endif } /* if (QMdiArea *area = qobject_cast(widget)) { area->viewport()->removeEventFilter(d); } */ d->removeFrameShadow(area); } if (d->expensiveShadows) { if (widget->inherits("Konsole::TerminalDisplay") || widget->inherits("KTextEditor::View") || widget->inherits("KHTMLView")) { widget->removeEventFilter(d); d->removeFrameShadow(widget); } } if (widget->inherits("Q3ScrollView")) { widget->removeEventFilter(d); d->removeFrameShadow(widget); } #if 1 if (widget->inherits("KFadeWidgetEffect")) { widget->removeEventFilter(d); } #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) if (widget->inherits("QPlainTextEdit")) { QPlainTextEdit *edit = static_cast(widget); edit->viewport()->removeEventFilter(d); edit->removeEventFilter(d); } #endif if (qobject_cast(widget)) { widget->removeEventFilter(d); widget->setAttribute(Qt::WA_OpaquePaintEvent, true); } if (QTextEdit *edit = qobject_cast(widget)) { #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) if (!qstrcmp(widget->metaObject()->className(), "SampleEdit")) { QList children = widget->children(); Q_FOREACH (QObject *child, children) { if (child->objectName() == QLatin1String("sample_background")) { child->setParent(0); child->deleteLater(); } } } else #endif { //d->mapper.removeMappings(edit); } edit->viewport()->removeEventFilter(d); edit->removeEventFilter(d); } if (QToolBar *toolbar = qobject_cast(widget)) { QFont font; // font.setPointSizeF(font.pointSizeF() / (1.19)); QList children = toolbar->findChildren(); Q_FOREACH (QToolButton *child, children) { if (!child->icon().isNull()) { child->setFont(font); } } disconnect(toolbar, SIGNAL(orientationChanged(Qt::Orientation)), d, SLOT(updateToolBarOrientation(Qt::Orientation))); } if (!qstrcmp(widget->metaObject()->className(), "KLineEditButton")) { widget->removeEventFilter(d); } if (qobject_cast(widget)) { widget->setMouseTracking(false); widget->removeEventFilter(d); widget->setCursor(Qt::IBeamCursor); } if (!d->postEventWidgets.isEmpty()) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) d->postEventWidgets.removeOne(widget); #else d->postEventWidgets.removeAll(widget); #endif } if ((QWidget *) d->oldEdit == widget) { d->oldEdit = 0; } if (!qstrcmp(widget->metaObject()->className(), "InfoSidebarPage") || !qstrcmp(widget->metaObject()->className(), "InformationPanel")) { widget->removeEventFilter(d); } if (qobject_cast(widget)) { widget->removeEventFilter(d); } } /*-----------------------------------------------------------------------*/ extern void lineEditMouseMoved(QLineEdit *lineEdit, QMouseEvent *event); void SkulptureStyle::Private::processPostEventWidgets() { QWidget *widget; while (!postEventWidgets.isEmpty() && (widget = postEventWidgets.takeFirst())) { if (QTextEdit *edit = qobject_cast(widget)) { handleCursor(edit); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) else if (QPlainTextEdit *edit = qobject_cast(widget)) { handleCursor(edit); } #endif } } void SkulptureStyle::Private::addPostEventWidget(QWidget *widget) { if (qobject_cast(widget) #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) || qobject_cast(widget) #endif ) { if (!postEventWidgets.contains(widget)) { bool signal = postEventWidgets.isEmpty(); postEventWidgets.append(widget); if (signal) { QTimer::singleShot(0, this, SLOT(processPostEventWidgets())); } } } } static void visualizeLayoutSpacing(QLayout *layout, QPainter *painter) { layout->activate(); QColor color; int spacing = -1; #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) if (QFormLayout *formLayout = qobject_cast(layout)) { spacing = formLayout->spacing(); } else #endif if (QGridLayout *gridLayout = qobject_cast(layout)) { spacing = gridLayout->spacing(); } else if (QBoxLayout *boxLayout = qobject_cast(layout)) { spacing = boxLayout->spacing(); } else { spacing = layout->spacing(); } if (spacing == 0) { color = Qt::green; } else if (spacing > 0) { color = Qt::red; } if (color.isValid()) { color.setAlpha(30); painter->fillRect(layout->geometry(), color); } else { painter->setPen(QColor(0, 150, 0, 50)); painter->drawRect(layout->geometry().adjusted(0, 0, -1, -1)); } if (qobject_cast(layout)) { painter->setPen(QColor(200, 0, 0, 150)); painter->drawRect(layout->geometry().adjusted(0, 0, -1, -1)); } for (int i = 0; i < layout->count(); ++i) { if (QLayout *childLayout = layout->itemAt(i)->layout()) { visualizeLayoutSpacing(childLayout, painter); } } } bool SkulptureStyle::Private::eventFilter(QObject *watched, QEvent *event) { #if 0 // can't happen, because widgets are the only ones to install it if (!watched->isWidgetType()) { return QObject::eventFilter(watched, event); } #endif QWidget *widget = reinterpret_cast(watched); #if 0 if (event->type() != QEvent::UpdateRequest && event->type() != QEvent::Paint) { qDebug() << "handling" << event->type() << "for object" << widget->objectName() << "which is a" << widget->metaObject()->className() << " which is a" << widget->metaObject()->superClass()->className(); } #endif #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) if (QMenu *menu = qobject_cast(widget)) { if (runtimeQtVersion() < QT_VERSION_CHECK(4, 6, 0)) { return menuEventFilter(menu, event); } } #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (qobject_cast(widget)) { WidgetShadow *shadow = findShadow(widget); switch (event->type()) { case QEvent::Move: case QEvent::Resize: if (shadow) { shadow->updateGeometry(); } break; case QEvent::ZOrderChange: if (shadow) { shadow->updateZOrder(); } break; case QEvent::Hide: case QEvent::Destroy: if (shadow) { shadow->setParent(0); shadow->hide(); shadow->deleteLater(); } break; case QEvent::Show: if (!shadow) { if (widget->parentWidget()) { shadow = new WidgetShadow(widget->parentWidget()); shadow->setWidget(widget); shadow->updateZOrder(); } } else { shadow->updateZOrder(); } default: break; } } #endif if (event->type() == QEvent::Hide || event->type() == QEvent::Destroy) { if (!postEventWidgets.isEmpty()) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) postEventWidgets.removeOne(widget); #else postEventWidgets.removeAll(widget); #endif } if ((QWidget *) oldEdit == widget) { oldEdit = 0; } } else if (event->type() != QEvent::Paint) { addPostEventWidget(widget); if (QWidget *parent = widget->parentWidget()) { addPostEventWidget(parent); if ((parent = parent->parentWidget())) { addPostEventWidget(parent); } } } switch (event->type()) { case QEvent::Paint: #if 1 // highlight current line in QTextEdit / QPlainTextEdit if (widget->objectName() == QLatin1String("qt_scrollarea_viewport")) { if (QTextEdit *edit = qobject_cast(widget->parent())) { #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) if (!qstrcmp(edit->metaObject()->className(), "SampleEdit")) { QList children = edit->children(); Q_FOREACH (QObject *child, children) { if (child->objectName() == QLatin1String("sample_background")) { QWidget *bg = qobject_cast(child); if (bg) { QPalette palette = edit->palette(); palette.setColor(QPalette::Window, palette.color(QPalette::Base)); bg->setPalette(palette); } } } } #endif // updateTextEditMargins(edit); paintCursorLine(edit); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) else if (widget->parent()->inherits("QPlainTextEdit")) { paintCursorLine(static_cast(widget->parent())); } #endif } #endif #if 1 if (visualizeLayouts) { if (!widget->font().isCopyOf(QApplication::font())) { if (widget->font() == QApplication::font()) { QPainter painter(widget); painter.fillRect(widget->rect(), QColor(255, 0, 0, 200)); } } if (!widget->palette().isCopyOf(QApplication::palette())) { if (true/*widget->palette() == QApplication::palette()*/) { QPainter painter(widget); painter.fillRect(widget->rect(), QColor(0, 200, 255, 200)); } } #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) if (!widget->styleSheet().isEmpty()) { QPainter painter(widget); painter.fillRect(widget->rect(), QColor(255, 0, 255, 100)); } #endif if (QLayout *layout = widget->layout()) { if (!(qobject_cast(widget))) { // explicitely check public layout classes, QMainWindowLayout doesn't work here if (qobject_cast(layout) #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) || qobject_cast(layout) #endif || qobject_cast(layout) || qobject_cast(layout)) { QPainter painter(widget); visualizeLayoutSpacing(layout, &painter); } } } } #endif #if 0 if (QDialog *dialog = qobject_cast(widget)) { QPainter painter(dialog); QRect r = dialog->rect(); QLinearGradient dialogGradient1(r.topLeft(), r.bottomRight()); dialogGradient1.setColorAt(0.0, QColor(255, 255, 255, 30)); dialogGradient1.setColorAt(1.0, QColor(0, 0, 0, 10)); // painter.fillRect(r, dialogGradient1); QRadialGradient dialogGradient2(r.left() + r.width() / 2, r.top(), r.height()); dialogGradient2.setColorAt(0.0, QColor(255, 255, 225, 160)); dialogGradient2.setColorAt(1.0, QColor(0, 0, 0, 0)); // painter.fillRect(r, dialogGradient2); QLinearGradient dialogGradient3(r.topLeft(), r.bottomLeft()); dialogGradient3.setColorAt(0.0, QColor(255, 255, 255, 30)); dialogGradient3.setColorAt(1.0, QColor(0, 0, 0, 20)); painter.fillRect(r, dialogGradient3); paintThinFrame(&painter, dialog->rect().adjusted(0, 0, 0, 0), dialog->palette(), 60, -20); paintThinFrame(&painter, dialog->rect().adjusted(1, 1, -1, -1), dialog->palette(), -20, 60); } #endif #if 0 if (QStatusBar *status = qobject_cast(widget)) { QPainter painter(status); paintThinFrame(&painter, status->rect(), status->palette(), -20, 60); } if (QToolBox *toolBox = qobject_cast(widget)) { QPainter painter(toolBox); paintThinFrame(&painter, toolBox->rect(), toolBox->palette(), 60, -20); paintThinFrame(&painter, toolBox->rect().adjusted(1, 1, -1, -1), toolBox->palette(), -60, 140); } if (QLCDNumber *lcd = qobject_cast(watched)) { // TODO nicer digits, antialiased, slight italics } if (QDockWidget *dock = qobject_cast(widget)) { // ### rendering a frame around dock widgets does not work, because // the subwidgets are placed at the edges. } #endif if (!qstrcmp(widget->metaObject()->className(), "InfoSidebarPage") || !qstrcmp(widget->metaObject()->className(), "InformationPanel")) { QPainter painter(widget); paintThinFrame(&painter, widget->rect().adjusted(0, 0, 0, 0), widget->palette(), 60, -20); paintThinFrame(&painter, widget->rect().adjusted(1, 1, -1, -1), widget->palette(), -20, 60); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (!qstrcmp(widget->metaObject()->className(), "KLineEditButton")) { QPainter painter(widget); QStyleOption option; option.initFrom(widget); QIcon::Mode iconMode = QIcon::Normal; if (option.state & QStyle::State_Enabled && option.state & QStyle::State_MouseOver) { //iconMode = QIcon::Active; // painter.fillRect(widget->rect(), Qt::red); } else { //iconMode = QIcon::Disabled; painter.setOpacity(0.2); } QRect r = QRect(widget->rect().center() - QPoint(6, 5), QSize(12, 12)); painter.drawPixmap(r, q->standardIcon(QStyle::SP_TitleBarCloseButton, &option, widget).pixmap(12, 12, iconMode)); event->accept(); return true; } if (widget->inherits("KFadeWidgetEffect")) { // widget->hide(); event->accept(); // widget->removeEventFilter(this); return true; } break; #endif case QEvent::MouseMove: if (QLineEdit *lineEdit = qobject_cast(watched)) { lineEditMouseMoved(lineEdit, static_cast(event)); } break; case QEvent::Show: if (QProgressBar *pbar = qobject_cast(watched)) { if (!widget->inherits("StatusBarSpaceInfo")) { setAnimated(pbar, true); } } /* fall through */ case QEvent::Move: case QEvent::Resize: if (QTextEdit *edit = qobject_cast(widget)) { #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) if (!qstrcmp(widget->metaObject()->className(), "SampleEdit")) { QList children = widget->children(); Q_FOREACH (QObject *child, children) { if (child->objectName() == QLatin1String("sample_background")) { QWidget *bg = qobject_cast(child); if (bg) { bg->setGeometry(2, 2, widget->width() - 4, widget->height() - 4); } } } } else #endif { textEditSourceChanged(edit); } } #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) else if (qobject_cast(widget)) { QList shadows = widget->findChildren(); Q_FOREACH (WidgetShadow *shadow, shadows) { shadow->updateGeometry(); } } #endif if (qobject_cast(widget) || widget->inherits("Q3ScrollView") #if 1 || widget->inherits("Konsole::TerminalDisplay") || widget->inherits("KTextEditor::View") || widget->inherits("KHTMLView") #endif ) { updateFrameShadow(widget); } break; case QEvent::Destroy: case QEvent::Hide: setAnimated(reinterpret_cast(watched), false); break; #if 0 case QEvent::MouseButtonRelease: if (allowScrollBarSliderToCoverArrows && qobject_cast(widget)) { widget->update(); } break; #endif default: break; } return QObject::eventFilter(watched, event); } /*-----------------------------------------------------------------------*/ #define SkulptureDrawFunction(function, selectortype, optiontype, array) \ \ void SkulptureStyle::function(selectortype element, const optiontype *option, QPainter *painter, const QWidget *widget) const \ { \ if (uint(element) < array_elements(array)) { \ const Private::DrawElementEntry *entry = &array[element]; \ if (entry->func && option && (!entry->type || option->type == entry->type)) { \ entry->func(painter, option, widget, this); \ return; \ } \ } \ ParentStyle::function(element, option, painter, widget); \ } SkulptureDrawFunction(drawPrimitive, PrimitiveElement, QStyleOption, d->draw_primitive_entry) SkulptureDrawFunction(drawControl, ControlElement, QStyleOption, d->draw_element_entry) //SkulptureDrawFunction(drawComplexControl, ComplexControl, QStyleOptionComplex, d->draw_complex_entry) /*-----------------------------------------------------------------------*/ //#include "skulpture.moc" /* * skulpture_animations.cpp * */ #include "skulpture_p.h" #include #include /*-----------------------------------------------------------------------*/ void SkulptureStyle::Private::setAnimated(QWidget *widget, bool animated) { if (!widget) { return; } animations.removeAll(widget); if (animated && animateProgressBars) { animations.prepend(widget); if (!timer) { timer = startTimer(60); } } else { if (animations.isEmpty()) { if (timer) { killTimer(timer); timer = 0; } } } } bool SkulptureStyle::Private::isAnimated(QWidget *widget) { if (!widget || !timer) { return false; } return animations.contains(widget); } void SkulptureStyle::Private::timerEvent(QTimerEvent *event) { if (event->timerId() == timer) { Q_FOREACH (QWidget *widget, animations) { // FIXME: move this logic to progressbar QProgressBar *bar = qobject_cast(widget); if (bar) { if (bar->minimum() >= bar->maximum() || bar->value() < bar->maximum()) { bar->update(); } } else { widget->update(); } } } event->ignore(); } /* * skulpture_arrows.cpp * */ #include "skulpture_p.h" #include "sk_factory.h" #include /*-----------------------------------------------------------------------*/ #define awf 0.8 /* width of inner arrow 0 ... 1 */ #define ahf 0.2 /* position of inner arrow, -1 ... 1 */ #define spf 0.2 /* position of spin plus/minus edges */ #define swf 0.8 /* width of spin plus/minus sign */ #define shf 1.0 /* height of spin plus/minus sign */ static const ShapeFactory::Code arrowShapeDescription[] = { Pmove(-1, 1), Pline(-awf, 1), Pline(0, ahf), Pline(awf, 1), Pline(1, 1), Pline(0, -1), Pend }; static const ShapeFactory::Code spinPlusDescription[] = { Pmove(-swf, spf), Pline(-spf, spf), Pline(-spf, shf), Pline(spf, shf), Pline(spf, spf), Pline(swf, spf), Pline(swf, -spf), Pline(spf, -spf), Pline(spf, -shf), Pline(-spf, -shf), Pline(-spf, -spf), Pline(-swf, -spf), Pend }; static const ShapeFactory::Code spinMinusDescription[] = { Pmove(-swf, spf), Pline(swf, spf), Pline(swf, -spf), Pline(-swf, -spf), Pend }; static const ShapeFactory::Code sortIndicatorShapeDescription[] = { Pmove(-1, 1), Pline(1, 1), Pline(0, -1), Pend }; /*-----------------------------------------------------------------------*/ static inline QPainterPath arrowPath(const QStyleOption *option, Qt::ArrowType arrow, bool spin) { qreal var[ShapeFactory::MaxVar + 1]; var[1] = 0.01 * arrow; var[2] = spin ? 1.0 : 0.0; var[3] = option->fontMetrics.height(); var[4] = 0.0; QPainterPath shape = ShapeFactory::createShape( spin && arrow == Qt::LeftArrow ? spinMinusDescription : spin && arrow == Qt::RightArrow ? spinPlusDescription : arrowShapeDescription, var); if (var[4] != 0.0) { shape.setFillRule(Qt::WindingFill); } qreal h = 2.0 + var[3] * (spin ? 2.0 : 3.0) / 9.0; qreal w = 2.0 + var[3] / 3.0; h /= 2; w /= 2; if (arrow == Qt::DownArrow || arrow == Qt::RightArrow) { h = -h; } bool horiz = !spin && (arrow == Qt::LeftArrow || arrow == Qt::RightArrow); QTransform arrowMatrix(horiz ? 0 : w, horiz ? w : 0, horiz ? h : 0 , horiz ? 0 : h, 0, 0); return arrowMatrix.map(shape); } void paintScrollArrow(QPainter *painter, const QStyleOption *option, Qt::ArrowType arrow, bool spin) { painter->save(); // FIXME: combine translations with path matrix painter->translate(option->rect.center()); #if 1 painter->setRenderHint(QPainter::Antialiasing, true); #else painter->setRenderHint(QPainter::Antialiasing, false); #endif if (painter->renderHints() & QPainter::Antialiasing) { painter->translate(0.5, 0.5); } #if 1 switch (arrow) { case Qt::UpArrow: painter->translate(0, -0.5); break; case Qt::DownArrow: painter->translate(0, 0.5); break; case Qt::LeftArrow: if (!spin) { painter->translate(-0.5, 0); } break; case Qt::RightArrow: if (!spin) { painter->translate(0.5, 0); } break; case Qt::NoArrow: break; } #endif painter->setPen(Qt::NoPen); QColor color = option->palette.color(spin ? (option->state & QStyle::State_Enabled ? QPalette::WindowText : QPalette::Text) : QPalette::ButtonText); if ((option->state & QStyle::State_MouseOver) && option->state & QStyle::State_Enabled /* && !(option->state & QStyle::State_Sunken)*/) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) color = option->palette.color(QPalette::Highlight).darker(200); #else color = option->palette.color(QPalette::Highlight).dark(200); #endif // painter->setPen(QPen(Qt::white, 1.0)); } else { // painter->setPen(QPen(Qt::white, 0.5)); } color.setAlpha((179 * color.alpha()) >> 8); painter->setBrush(color); painter->drawPath(arrowPath(option, arrow, spin)); painter->restore(); } void paintIndicatorArrowDown(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::DownArrow, false); } void paintIndicatorArrowLeft(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::LeftArrow, false); } void paintIndicatorArrowRight(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::RightArrow, false); } void paintIndicatorArrowUp(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::UpArrow, false); } /* * skulpture_buttons.cpp * */ #include "skulpture_p.h" #include #include static QPainterPath button_path(const QRectF &rect, qreal k) { k *= 0.1; const qreal tlh_edge = 6.0 * k; const qreal tlv_edge = 6.0 * k; const qreal tlh_control = 4.0 * k; const qreal tlv_control = 4.0 * k; const qreal blh_edge = 6.0 * k; const qreal blv_edge = 6.0 * k; const qreal blh_control = 4.0 * k; const qreal blv_control = 4.0 * k; const qreal trh_edge = 6.0 * k; const qreal trv_edge = 6.0 * k; const qreal trh_control = 4.0 * k; const qreal trv_control = 4.0 * k; const qreal brh_edge = 6.0 * k; const qreal brv_edge = 6.0 * k; const qreal brh_control = 4.0 * k; const qreal brv_control = 4.0 * k; QPainterPath path; path.moveTo(rect.left() + tlh_edge, rect.top()); path.lineTo(rect.right() - trh_edge, rect.top()); path.cubicTo(rect.right() - trh_edge + trh_control, rect.top(), rect.right(), rect.top() + trv_edge - trv_control, rect.right(), rect.top() + trv_edge); path.lineTo(rect.right(), rect.bottom() - brv_edge); path.cubicTo(rect.right(), rect.bottom() - brv_edge + brv_control, rect.right() - brh_edge + brh_control, rect.bottom(), rect.right() - brh_edge, rect.bottom()); path.lineTo(rect.left() + blh_edge, rect.bottom()); path.cubicTo(rect.left() + blh_edge - blh_control, rect.bottom(), rect.left(), rect.bottom() - blv_edge + blv_control, rect.left(), rect.bottom() - blv_edge); path.lineTo(rect.left(), rect.top() + tlv_edge); path.cubicTo(rect.left(), rect.top() + tlv_edge - tlv_control, rect.left() + tlh_edge - tlh_control, rect.top(), rect.left() + tlh_edge, rect.top()); return path; } static QBrush button_gradient(const QRectF &rect, const QColor &color, const QStyleOptionButton *option) { Q_UNUSED(option); qreal ch = color.hueF(); qreal cs = color.saturationF() * 1.0; qreal cv = color.valueF() * 1.0; int ca = color.alpha(); QColor col; if (rect.height() > 64) { return QColor(color); } QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); col.setHsvF(ch, cs, qMax(0.0, cv - 0.02)); col.setAlpha(ca); gradient.setColorAt(0.0, col); col.setHsvF(ch, cs, qMin(1.0, cv + 0.03)); col.setAlpha(ca); gradient.setColorAt(1.0, col); return gradient; } void paintButtonPanel(QPainter *painter, const QStyleOptionButton *option, QPalette::ColorRole bgrole) { const QRectF &c_rect = option->rect; const qreal t = 1.0; QRectF rect = c_rect; bool frame = true; if (option->features & QStyleOptionButton::Flat && !(option->state & QStyle::State_Sunken)) { frame = false; } painter->setPen(Qt::NoPen); if ((option->features & QStyleOptionButton::DefaultButton) && (option->state & QStyle::State_Enabled)) { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 1.3), blend_color(QColor(0, 0, 0, 10), option->palette.color(QPalette::Highlight).lighter(110), 0.2), blend_color(QColor(0, 0, 0, 15), option->palette.color(QPalette::Highlight).lighter(110), 0.2))); } else { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 1.3), shaded_color(option->palette.color(QPalette::Window), -10), shaded_color(option->palette.color(QPalette::Window), -15))); } painter->drawPath(button_path(rect, 1.5)); rect.adjust(t, t, -t, -t); QBrush bgbrush = option->palette.brush(option->state & QStyle::State_Enabled ? (bgrole == QPalette::NoRole ? QPalette::Button : bgrole) : QPalette::Button); if (bgbrush.style() == Qt::SolidPattern && bgbrush.color().alpha() == 0) { QColor color = option->palette.color(QPalette::Window); color.setAlpha(0); bgbrush = color; } if (frame) { if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On) { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 1.1), shaded_color(option->palette.color(QPalette::Window), -35), shaded_color(option->palette.color(QPalette::Window), -75))); } else { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 1.1), shaded_color(option->palette.color(QPalette::Window), -75), shaded_color(option->palette.color(QPalette::Window), -45))); } } else { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 1.1), shaded_color(option->palette.color(QPalette::Window), -35), shaded_color(option->palette.color(QPalette::Window), -35))); } painter->drawPath(button_path(rect, 1.3)); rect.adjust(t, t, -t, -t); if (bgbrush.style() == Qt::SolidPattern) { QColor bgcolor = bgbrush.color(); if (option->state & QStyle::State_On) { bgcolor = blend_color(bgcolor, option->palette.color(QPalette::Highlight), 0.2); bgbrush = button_gradient(rect, bgcolor, option); } if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Sunken) { bgcolor = bgcolor.lighter(102); } else if (option->state & QStyle::State_MouseOver) { bgcolor = bgcolor.lighter(104); } bgbrush = button_gradient(rect, bgcolor, option); } painter->setBrush(bgbrush); // painter->setBrush(option->palette.color(QPalette::Button)); painter->drawPath(button_path(rect, 1.1)); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On) { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 0.9), shaded_color(bgcolor, -10), shaded_color(bgcolor, -20))); } else { painter->setBrush(path_edge_gradient(rect, option, button_path(rect, 0.9), shaded_color(bgcolor, -20), shaded_color(bgcolor, 160))); } painter->drawPath(button_path(rect, 1.1)); } } painter->setBrush(bgbrush); } else { QColor bgcolor = option->palette.color(QPalette::Window); if (option->state & QStyle::State_MouseOver) { bgcolor = bgcolor.lighter(104); } if (option->state & QStyle::State_On) { bgcolor = blend_color(bgcolor, option->palette.color(QPalette::Highlight), 0.2); } painter->setBrush(bgcolor); } rect.adjust(t, t, -t, -t); painter->save(); // make transparent buttons appear transparent painter->setCompositionMode(QPainter::CompositionMode_DestinationOut); painter->setBrush(Qt::black); painter->drawPath(button_path(rect, 0.9)); painter->restore(); painter->drawPath(button_path(rect, 0.9)); } void paintPushButtonBevel(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style) { QStyleOptionButton opt = *option; opt.features &= ~(QStyleOptionButton::HasMenu); ((QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_PushButtonBevel, &opt, painter, widget); if (option->features & QStyleOptionButton::Flat) { if (!(option->state & (QStyle::State_Sunken | QStyle::State_On))) { if (option->state & QStyle::State_MouseOver) { painter->fillRect(option->rect.adjusted(2, 2, -2, -2), QColor(255, 255, 255, 60)); } } } if (option->features & QStyleOptionButton::HasMenu) { int size = style->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, widget); opt.palette.setColor(QPalette::WindowText, opt.palette.color(widget ? widget->foregroundRole() : QPalette::ButtonText)); opt.state &= ~(QStyle::State_MouseOver); if (option->direction == Qt::LeftToRight) { opt.rect = QRect(option->rect.right() - size - 2, option->rect.top(), size, option->rect.height()); } else { opt.rect = QRect(option->rect.left() + 4, option->rect.top(), size, option->rect.height()); } if (option->state & (QStyle::State_Sunken | QStyle::State_On)) { opt.rect.translate(style->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &opt, widget), style->pixelMetric(QStyle::PM_ButtonShiftVertical, &opt, widget)); } style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, painter, widget); } } /* * skulpture_cache.cpp * */ #include "skulpture_p.h" #include #include #include #include #include "sk_factory.h" #include // FIXME #if (QT_VERSION < QT_VERSION_CHECK(4, 3, 0)) #define cacheKey serialNumber #endif /*-----------------------------------------------------------------------*/ static const bool UsePixmapCache = true; /*-----------------------------------------------------------------------*/ /* * paint a pushbutton to painter * */ extern void paintButtonPanel(QPainter *painter, const QStyleOptionButton *option, QPalette::ColorRole bgrole); static const int button_edge_size = 16; static const int button_inner_width = 32; void paintCommandButtonPanel(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle */*style*/) { Q_UNUSED(widget); QPalette::ColorRole bgrole = /*widget ? widget->backgroundRole() : */QPalette::Button; bool useCache = UsePixmapCache; QString pixmapName; QPixmap pixmap; QRect r = option->rect; r.setWidth(button_inner_width + 2 * button_edge_size); if (/*option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ r.height() > 64) { useCache = false; } if (useCache) { uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus); uint features = uint(option->features) & (QStyleOptionButton::Flat | QStyleOptionButton::DefaultButton); if (!(state & QStyle::State_Enabled)) { state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus); } #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) pixmapName.sprintf("scp-cbp-%x-%x-%x-%x-%llx-%x", features, uint(bgrole), state, option->direction, option->palette.cacheKey(), r.height()); #else pixmapName = QString::asprintf("scp-cbp-%x-%x-%x-%x-%llx-%x", features, uint(bgrole), state, option->direction, option->palette.cacheKey(), r.height()); #endif } if (!useCache || !QPixmapCache::find(pixmapName, &pixmap)) { pixmap = QPixmap(r.size()); pixmap.fill(Qt::transparent); // pixmap.fill(Qt::red); QPainter p(&pixmap); QStyleOptionButton but = *option; but.rect = QRect(QPoint(0, 0), r.size()); // ### neither Clear nor Source works? // p.setCompositionMode(QPainter::CompositionMode_Clear); // p.setCompositionMode(QPainter::CompositionMode_Source); // p.fillRect(but.rect, Qt::transparent); // p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setFont(painter->font()); p.setRenderHint(QPainter::Antialiasing, true); paintButtonPanel(&p, &but, bgrole); p.end(); if (useCache) { QPixmapCache::insert(pixmapName, pixmap); // qDebug() << "inserted into cache:" << pixmapName; } } int rem; if (option->rect.width() == r.width()) { rem = r.width(); } else { int side = qMin(option->rect.width() / 2, button_inner_width + button_edge_size); painter->drawPixmap(r.topLeft(), pixmap, QRect(0, 0, side, r.height())); int midw = option->rect.width() - 2 * side; rem = option->rect.width() - side; r.translate(side, 0); while (midw > 0) { int w = qMin(button_inner_width, midw); rem -= w; painter->drawPixmap(r.topLeft(), pixmap, QRect(button_edge_size, 0, w, r.height())); r.translate(w, 0); midw -= button_inner_width; } } painter->drawPixmap(r.topLeft(), pixmap, QRect(r.width() - rem, 0, rem, r.height())); } /*-----------------------------------------------------------------------*/ void paintPanelButtonTool(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style) { Q_UNUSED(style); QStyleOptionButton button; if (widget && !qstrcmp(widget->metaObject()->className(), "QDockWidgetTitleButton")) { if (!(option->state & QStyle::State_MouseOver) && !(option->state & QStyle::State_On)) return; } button.QStyleOption::operator=(*option); button.features = QStyleOptionButton::None; if (!(button.state & QStyle::State_Enabled) && (option->state & QStyle::State_AutoRaise)) { return; } // ### don't know if tool buttons should have that big frame... button.rect.adjust(-1, -1, 1, 1); // FIXME bgrole? paintCommandButtonPanel(painter, &button, 0, 0); } /*-----------------------------------------------------------------------*/ static void paintIndicatorCached(QPainter *painter, const QStyleOption *option, void (*paintIndicator)(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style), bool useCache, const QString &pixmapName) { QPixmap pixmap; if (!useCache || !QPixmapCache::find(pixmapName, &pixmap)) { pixmap = QPixmap(option->rect.size()); #if 1 pixmap.fill(Qt::transparent); // pixmap.fill(Qt::red); #else pixmap.fill(option->palette.color(QPalette::Window)); #endif QPainter p(&pixmap); QStyleOption opt = *option; opt.rect = QRect(QPoint(0, 0), option->rect.size()); // p.setCompositionMode(QPainter::CompositionMode_Clear); // p.setCompositionMode(QPainter::CompositionMode_Source); // p.fillRect(opt.rect, Qt::transparent); // p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setFont(painter->font()); p.setRenderHint(QPainter::Antialiasing, true); paintIndicator(&p, &opt, 0, 0); p.end(); if (useCache) { QPixmapCache::insert(pixmapName, pixmap); // qDebug() << "inserted into cache:" << pixmapName; } } painter->drawPixmap(option->rect, pixmap); } static void paintIndicatorShape(QPainter *painter, const QStyleOption *option, qreal scale, const QPainterPath &shapePath) { // configuration const QPalette::ColorRole indicatorRole = QPalette::Text; if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On || option->state & QStyle::State_MouseOver) { painter->save(); painter->setPen(Qt::NoPen); painter->translate(QRectF(option->rect).center()); painter->setRenderHint(QPainter::Antialiasing, true); QColor color; if ((option->state & QStyle::State_MouseOver || option->state & QStyle::State_Sunken) && option->state & QStyle::State_Enabled) { color = option->palette.color(QPalette::Highlight); if (!(option->state & QStyle::State_Sunken) && !(option->state & QStyle::State_On)) { color.setAlpha(80); } } else if (!(option->state & QStyle::State_Sunken) && option->state & QStyle::State_On) { color = option->palette.color(indicatorRole); color.setAlpha(80); } if (color.isValid()) { painter->setBrush(color); QTransform matrix(scale, 0, 0, scale, 0, 0); painter->drawPath(matrix.map(shapePath)); } if (!(option->state & QStyle::State_Sunken) && option->state & QStyle::State_On) { painter->setBrush(option->palette.brush(indicatorRole)); QTransform matrix(scale - 1, 0, 0, scale - 1, 0, 0); painter->drawPath(matrix.map(shapePath)); } painter->restore(); } } /*-----------------------------------------------------------------------*/ #define csx 0.35 #define csc 0.2 // cross static const ShapeFactory::Code checkShapeDescription1[] = { Pmove(-1 + csc, -1), Pline(0, -csx), Pline(1 - csc, -1), Pline(1, -1 + csc), Pline(csx, 0), Pline(1, 1 - csc), Pline(1 - csc, 1), Pline(0, csx), Pline(-1 + csc, 1), Pline(-1, 1 - csc), Pline(-csx, 0), Pline(-1, -1 + csc), Pend }; // checkmark static const ShapeFactory::Code checkShapeDescription2[] = { Pmove(1 - csc, -1), Pline(1, -1 + csc), Pline(csx, 1), Pline(-csx, 1), Pline(-1, csc), Pline(-1 + csc, 0), Pline(0, 1 - 2 * csx), Pend }; static void paintCheckBox(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { if (option->state & QStyle::State_NoChange) { paintThinFrame(painter, option->rect, option->palette, 30, -10); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -50, -60); paintThinFrame(painter, option->rect.adjusted(2, 2, -2, -2), option->palette, 0, 60); QColor color = option->palette.color(QPalette::Window); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Sunken) { color = color.darker(110); } else if (option->state & QStyle::State_MouseOver) { color = color.lighter(106); } } else { color = color.darker(106); } painter->fillRect(option->rect.adjusted(3, 3, -3, -3), color); } else { QColor color = option->palette.color(QPalette::Base); if (!(option->state & QStyle::State_On) && !(option->state & QStyle::State_Enabled)) { color = option->palette.color(QPalette::Window); } else if (option->state & QStyle::State_MouseOver) { color = color.lighter(105); } painter->fillRect(option->rect.adjusted(2, 2, -2, -2), color); paintRecessedFrame(painter, option->rect, option->palette, RF_Small); if (!(option->state & QStyle::State_Sunken)) { if (option->state & QStyle::State_Enabled) { paintThinFrame(painter, option->rect.adjusted(2, 2, -2, -2), option->palette, 140, 200); } else { paintThinFrame(painter, option->rect.adjusted(2, 2, -2, -2), option->palette, 180, 180); } } const ShapeFactory::Description description = checkShapeDescription1; const qreal scale = (option->rect.width() - 4) * 0.35; paintIndicatorShape(painter, option, scale, ShapeFactory::createShape(description)); } } void paintIndicatorCheckBox(QPainter *painter, const QStyleOptionButton *option, const QWidget */*widget*/, const QStyle */*style*/) { bool useCache = UsePixmapCache; QString pixmapName; if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) { useCache = false; } if (useCache) { uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_NoChange | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus); if (!(state & QStyle::State_Enabled)) { state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus); } state &= ~(QStyle::State_HasFocus); #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) pixmapName.sprintf("scp-icb-%x-%x-%llx-%x-%x", state, option->direction, option->palette.cacheKey(), option->rect.width(), option->rect.height()); #else pixmapName = QString::asprintf("scp-icb-%x-%x-%llx-%x-%x", state, option->direction, option->palette.cacheKey(), option->rect.width(), option->rect.height()); #endif } paintIndicatorCached(painter, option, paintCheckBox, useCache, pixmapName); } /*-----------------------------------------------------------------------*/ static void paintThinBevel(QPainter *painter, const QPainterPath &path, const QColor &dark, const QColor &light, qreal lightAngle = M_PI / 4) { QTransform scaleUp; scaleUp.scale(10, 10); QList bevel = path.toSubpathPolygons(scaleUp); Q_FOREACH (QPolygonF polygon, bevel) { for (int i = 0; i < polygon.size() - 1; ++i) { QLineF line(polygon.at(i) / 10, polygon.at(i + 1) / 10); line.setLength(line.length() + 0.20); painter->setPen(QPen(blend_color(light, dark, sin(atan2(polygon.at(i + 1).y() - polygon.at(i).y(), polygon.at(i + 1).x() - polygon.at(i).x()) - lightAngle) / 2 + 0.5), 1.0, Qt::SolidLine, Qt::FlatCap)); painter->drawLine(line); } } } static void paintThinBevel(QPainter *painter, const QPainterPath &path, const QPalette &palette, int dark, int light, qreal lightAngle = M_PI / 4) { paintThinBevel(painter, path, shaded_color(palette.color(QPalette::Window), dark), shaded_color(palette.color(QPalette::Window), light), lightAngle); } static inline QPainterPath radioShape(const QRectF rect) { QPainterPath path; path.addEllipse(rect); return path; } static void paintRadioButton(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { const qreal lightAngle = option->direction == Qt::LeftToRight ? M_PI / 4 : 3 * M_PI / 4; QColor color = option->palette.color(QPalette::Base); if (!(option->state & QStyle::State_On) && !(option->state & QStyle::State_Enabled)) { color = option->palette.color(QPalette::Window); } else if (option->state & QStyle::State_MouseOver) { color = color.lighter(105); } painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); painter->setBrush(color); painter->drawPath(radioShape(QRectF(option->rect).adjusted(2, 2, -2, -2))); paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(0.5, 0.5, -0.5, -0.5)), option->palette, 39, -26, lightAngle); paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(1.5, 1.5, -1.5, -1.5)), option->palette, -26, -91, lightAngle); paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(2.5, 2.5, -2.5, -2.5)), QColor(0, 0, 0, 15), QColor(0, 0, 0, 30), lightAngle); paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(3.5, 3.5, -3.5, -3.5)), QColor(0, 0, 0, 8), QColor(0, 0, 0, 15), lightAngle); paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(4.5, 4.5, -4.5, -4.5)), QColor(0, 0, 0, 4), QColor(0, 0, 0, 8), lightAngle); if (!(option->state & QStyle::State_Sunken)) { if (option->state & QStyle::State_Enabled) { paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(2.5, 2.5, -2.5, -2.5)), option->palette, 140, 300, lightAngle); } else { paintThinBevel(painter, radioShape(QRectF(option->rect).adjusted(2.5, 2.5, -2.5, -2.5)), option->palette, 180, 180, lightAngle); } } painter->restore(); const qreal scale = (option->rect.width() - 4) * 0.35; QPainterPath circlePath; const qreal radius = 0.7; circlePath.addEllipse(QRectF(-radius, -radius, 2 * radius, 2 * radius)); paintIndicatorShape(painter, option, scale, circlePath); } void paintIndicatorRadioButton(QPainter *painter, const QStyleOptionButton *option, const QWidget */*widget*/, const QStyle */*style*/) { bool useCache = UsePixmapCache; QString pixmapName; if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) { useCache = false; } if (useCache) { uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus); if (!(state & QStyle::State_Enabled)) { state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus); } state &= ~(QStyle::State_HasFocus); #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) pixmapName.sprintf("scp-irb-%x-%x-%llx-%x-%x", state, option->direction, option->palette.cacheKey(), option->rect.width(), option->rect.height()); #else pixmapName = QString::asprintf("scp-irb-%x-%x-%llx-%x-%x", state, option->direction, option->palette.cacheKey(), option->rect.width(), option->rect.height()); #endif } paintIndicatorCached(painter, option, paintRadioButton, useCache, pixmapName); } /*-----------------------------------------------------------------------*/ void paintIndicatorMenuCheckMark(QPainter *painter, const QStyleOptionMenuItem *option, const QWidget *widget, const QStyle *style) { QStyleOptionButton buttonOption; buttonOption.QStyleOption::operator=(*option); // buttonOption.rect.adjust(-2, -2, 2, 2); // qDebug("here!"); // printf("state 0x%08x\n", uint(buttonOption.state)); if (option->state & QStyle::State_Enabled) { if (buttonOption.state & QStyle::State_On) { buttonOption.state |= QStyle::State_Sunken; } } else { buttonOption.state &= ~QStyle::State_Sunken; } if (option->state & QStyle::State_Selected) { buttonOption.state |= QStyle::State_MouseOver; } else { buttonOption.state &= ~QStyle::State_MouseOver; } if (option->checked) { buttonOption.state |= QStyle::State_On; } else { buttonOption.state &= ~QStyle::State_On; } if (widget) { buttonOption.palette = widget->palette(); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Active) { buttonOption.palette.setCurrentColorGroup(QPalette::Active); } else { buttonOption.palette.setCurrentColorGroup(QPalette::Inactive); } } else { buttonOption.palette.setCurrentColorGroup(QPalette::Disabled); } } if (option->checkType == QStyleOptionMenuItem::Exclusive) { QSize size(style->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, option, widget), style->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight, option, widget)); buttonOption.rect = QRect(option->rect.x() + ((option->rect.width() - size.width()) >> 1), option->rect.y() + ((option->rect.height() - size.height()) >> 1), size.width(), size.height()); paintIndicatorRadioButton(painter, &buttonOption, 0, 0); } else { QSize size(style->pixelMetric(QStyle::PM_IndicatorWidth, option, widget), style->pixelMetric(QStyle::PM_IndicatorHeight, option, widget)); buttonOption.rect = QRect(option->rect.x() + ((option->rect.width() - size.width()) >> 1), option->rect.y() + ((option->rect.height() - size.height()) >> 1), size.width(), size.height()); paintIndicatorCheckBox(painter, &buttonOption, 0, 0); } } #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) void paintQ3CheckListIndicator(QPainter *painter, const QStyleOptionQ3ListView *option, const QWidget *widget, const QStyle *style) { if (!option->items.isEmpty()) { QStyleOptionButton buttonOption; buttonOption.QStyleOption::operator=(*option); QSize size(style->pixelMetric(QStyle::PM_IndicatorWidth, option, widget), style->pixelMetric(QStyle::PM_IndicatorHeight, option, widget)); buttonOption.rect = QRect(option->rect.center() - QPoint(size.width() / 2, size.height() / 2), size); // buttonOption.rect.adjust(0, -1, 0, -1); paintIndicatorCheckBox(painter, &buttonOption, 0, 0); } } void paintQ3CheckListExclusiveIndicator(QPainter *painter, const QStyleOptionQ3ListView *option, const QWidget *widget, const QStyle *style) { if (!option->items.isEmpty()) { QStyleOptionButton buttonOption; buttonOption.QStyleOption::operator=(*option); QSize size(style->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, option, widget), style->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight, option, widget)); buttonOption.rect = QRect(option->rect.center() - QPoint(size.width() / 2, size.height() / 2), size); // buttonOption.rect.adjust(0, -1, 0, -1); paintIndicatorRadioButton(painter, &buttonOption, 0, 0); } } #endif void paintIndicatorItemViewItemCheck(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { QStyleOptionButton buttonOption; buttonOption.QStyleOption::operator=(*option); buttonOption.state &= ~QStyle::State_MouseOver; paintIndicatorCheckBox(painter, &buttonOption, 0, 0); } /*-----------------------------------------------------------------------*/ static void paintGrip(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { // painter->fillRect(option->rect, Qt::red); int d = qMin(option->rect.width(), option->rect.height()); // good values are 3 (very small), 4 (small), 5 (good), 7 (large), 9 (huge) // int d = 5; QRectF rect(QRectF(option->rect).center() - QPointF(d / 2.0, d / 2.0), QSizeF(d, d)); const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0; // const qreal angle = 90; QColor color; qreal opacity = 0.9; painter->save(); painter->setPen(Qt::NoPen); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Sunken) { color = option->palette.color(QPalette::Highlight).darker(110); } else { color = option->palette.color(QPalette::Button); } } else { color = option->palette.color(QPalette::Button); opacity = 0.5; } QConicalGradient gradient1(rect.center(), angle); gradient1.setColorAt(0.0, shaded_color(color, -110)); gradient1.setColorAt(0.25, shaded_color(color, -30)); gradient1.setColorAt(0.5, shaded_color(color, 180)); gradient1.setColorAt(0.75, shaded_color(color, -30)); gradient1.setColorAt(1.0, shaded_color(color, -110)); painter->setBrush(color); painter->drawEllipse(rect); painter->setBrush(gradient1); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) // ### merge opacity into color painter->setOpacity(opacity); #endif painter->drawEllipse(rect); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) painter->setOpacity(1.0); if (d > 2) { QConicalGradient gradient2(rect.center(), angle); gradient2.setColorAt(0.0, shaded_color(color, -40)); gradient2.setColorAt(0.25, shaded_color(color, 0)); gradient2.setColorAt(0.5, shaded_color(color, 210)); gradient2.setColorAt(0.75, shaded_color(color, 0)); gradient2.setColorAt(1.0, shaded_color(color, -40)); rect.adjust(1, 1, -1, -1); painter->setBrush(color); painter->drawEllipse(rect); painter->setBrush(gradient2); painter->setOpacity(opacity); painter->drawEllipse(rect); painter->setOpacity(1.0); if (d > 8) { QConicalGradient gradient3(rect.center(), angle); gradient3.setColorAt(0.0, shaded_color(color, -10)); gradient3.setColorAt(0.25, shaded_color(color, 0)); gradient3.setColorAt(0.5, shaded_color(color, 180)); gradient3.setColorAt(0.75, shaded_color(color, 0)); gradient3.setColorAt(1.0, shaded_color(color, -10)); rect.adjust(2, 2, -2, -2); painter->setBrush(color); painter->drawEllipse(rect); painter->setBrush(gradient3); painter->setOpacity(opacity); painter->drawEllipse(rect); painter->setOpacity(1.0); } } #endif painter->restore(); } void paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole /*bgrole*/) { bool useCache = UsePixmapCache; QString pixmapName; if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) { useCache = false; } if (useCache) { uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus); if (!(state & QStyle::State_Enabled)) { state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus); } state &= ~(QStyle::State_HasFocus); QByteArray colorName = option->palette.color(QPalette::Button).name().toLatin1(); #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) pixmapName.sprintf("scp-isg-%x-%x-%s-%x-%x", state, option->direction, colorName.constData(), option->rect.width(), option->rect.height()); #else pixmapName= QString::asprintf("scp-isg-%x-%x-%s-%x-%x", state, option->direction, colorName.constData(), option->rect.width(), option->rect.height()); #endif } paintIndicatorCached(painter, option, paintGrip, useCache, pixmapName); } /*-----------------------------------------------------------------------*/ void paintDialBase(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { // painter->fillRect(option->rect, Qt::red); // painter->save(); // painter->setRenderHint(QPainter::Antialiasing, true); int d = qMin(option->rect.width(), option->rect.height()); /* if (d > 20 && option->notchTarget > 0) { d += -1; } */ QRectF r((option->rect.width() - d) / 2.0, (option->rect.height() - d) / 2.0, d, d); const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0; // const qreal angle = 90; painter->setPen(Qt::NoPen); QColor border_color = option->palette.color(QPalette::Window); #if 0 { QRadialGradient depth_gradient(r.center(), d / 2); // depth_gradient.setColorAt(0.0, QColor(0, 0, 0, 255)); depth_gradient.setColorAt(0.5, QColor(0, 0, 0, 255)); depth_gradient.setColorAt(1.0, QColor(0, 0, 0, 0)); painter->setBrush(depth_gradient); painter->drawEllipse(r); } #endif #if 1 if (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange) { painter->setBrush(option->palette.color(QPalette::Highlight).darker(180)); r.adjust(1, 1, -1, -1); painter->drawEllipse(r); painter->setBrush(border_color); r.adjust(1, 1, -1, -1); painter->drawEllipse(r); r.adjust(1, 1, -1, -1); } else { painter->setBrush(border_color); r.adjust(1, 1, -1, -1); painter->drawEllipse(r); r.adjust(1, 1, -1, -1); QConicalGradient border_gradient(r.center(), angle); if (!(option->state & QStyle::State_Enabled)) { border_color = border_color.lighter(120); } border_gradient.setColorAt(0.0, border_color.darker(180)); border_gradient.setColorAt(0.3, border_color.darker(130)); border_gradient.setColorAt(0.5, border_color.darker(170)); border_gradient.setColorAt(0.7, border_color.darker(130)); border_gradient.setColorAt(1.0, border_color.darker(180)); painter->setBrush(border_gradient); // painter->setBrush(Qt::blue); painter->drawEllipse(r); r.adjust(1, 1, -1, -1); } d -= 6; QColor dial_color; if (option->state & QStyle::State_Enabled) { dial_color = option->palette.color(QPalette::Button).lighter(101); if (option->state & QStyle::State_MouseOver) { dial_color = dial_color.lighter(103); } } else { dial_color = option->palette.color(QPalette::Window); } qreal t = option->state & QStyle::State_Enabled ? 2.0 : 1.5; if (1) { // ###: work around Qt 4.3.0 bug? (this works for 4.3.1) QConicalGradient border_gradient(r.center(), angle); border_gradient.setColorAt(0.0, dial_color.lighter(120)); border_gradient.setColorAt(0.2, dial_color); border_gradient.setColorAt(0.5, dial_color.darker(130)); border_gradient.setColorAt(0.8, dial_color); border_gradient.setColorAt(1.0, dial_color.lighter(120)); painter->setPen(QPen(border_gradient, t)); } else { painter->setPen(QPen(Qt::red, t)); } #if 0 QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft()); dial_gradient.setColorAt(0.0, dial_color.darker(105)); dial_gradient.setColorAt(0.5, dial_color.lighter(102)); dial_gradient.setColorAt(1.0, dial_color.lighter(105)); #elif 1 QLinearGradient dial_gradient(option->direction == Qt::LeftToRight ? r.topLeft() : r.topRight(), option->direction == Qt::LeftToRight ? r.bottomRight() : r.bottomLeft()); // QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft()); if (true || option->state & QStyle::State_Enabled) { #if 1 dial_gradient.setColorAt(0.0, dial_color.darker(106)); dial_gradient.setColorAt(1.0, dial_color.lighter(104)); #else dial_gradient.setColorAt(0.0, dial_color.lighter(101)); dial_gradient.setColorAt(0.5, dial_color.darker(103)); dial_gradient.setColorAt(1.0, dial_color.lighter(104)); #endif } else { dial_gradient.setColorAt(0.0, dial_color); dial_gradient.setColorAt(1.0, dial_color); } #elif 0 QConicalGradient dial_gradient(r.center(), angle); dial_gradient.setColorAt(0.0, dial_color.lighter(102)); dial_gradient.setColorAt(0.5, dial_color.darker(103)); dial_gradient.setColorAt(1.0, dial_color.lighter(102)); #else QBrush dial_gradient(dial_color); #endif painter->setBrush(dial_gradient); t = t / 2; painter->drawEllipse(r.adjusted(t, t, -t, -t)); // painter->setPen(Qt::NoPen); // painter->setBrush(dial_color); // painter->drawEllipse(r.adjusted(d / 4, d / 4, - d / 4, - d / 4)); #if 0 QLinearGradient border2_gradient(r.topLeft(), r.bottomRight()); border2_gradient.setColorAt(1.0, dial_color.darker(425)); border2_gradient.setColorAt(0.9, dial_color); border2_gradient.setColorAt(0.0, dial_color.darker(400)); painter->setPen(QPen(border2_gradient, 1.3)); painter->setBrush(Qt::NoBrush); painter->drawEllipse(r.adjusted(0.3, 0.3, -0.3, -0.3)); #endif // painter->restore(); #endif } void paintCachedDialBase(QPainter *painter, const QStyleOptionSlider *option) { bool useCache = UsePixmapCache; QString pixmapName; QRect r = option->rect; int d = qMin(r.width(), r.height()); if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 128) { useCache = false; } if (useCache) { uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_KeyboardFocusChange | QStyle::State_HasFocus); if (!(state & QStyle::State_Enabled)) { state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange); } // state &= ~(QStyle::State_HasFocus); #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) pixmapName.sprintf("scp-qdb-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d); #else pixmapName = QString::asprintf("scp-qdb-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d); #endif } paintIndicatorCached(painter, option, paintDialBase, useCache, pixmapName); } void paintIndicatorDial(QPainter *painter, const QStyleOptionSlider *option) { int d = qMin(option->rect.width(), option->rect.height()); QRect rect(option->rect.center() - QPoint((d - 1) / 2, (d - 1) / 2), QSize(d, d)); QStyleOptionSlider opt; opt.QStyleOption::operator=(*option); opt.rect = rect; paintCachedDialBase(painter, &opt); } /*-----------------------------------------------------------------------*/ void paintBranchChildren(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { painter->setBrush(option->palette.color(QPalette::Text)); painter->setPen(Qt::NoPen); const qreal r = qMin(option->rect.width() * 0.5, option->fontMetrics.height() * 0.15); const QPointF center = QRectF(option->rect).center(); painter->drawEllipse(QRectF(center.x() - r, center.y() - r, 2 * r, 2 * r)); } void paintCachedIndicatorBranchChildren(QPainter *painter, const QStyleOption *option) { bool useCache = UsePixmapCache; QString pixmapName; QRect r = option->rect; int d = qMin(r.width(), r.height()); if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 64) { useCache = false; } if (useCache) { uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_Open); // if (!(state & QStyle::State_Enabled)) { // state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange); // } // state &= ~(QStyle::State_HasFocus); #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) pixmapName.sprintf("scp-qibc-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d); #else pixmapName = QString::asprintf("scp-qibc-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d); #endif } paintIndicatorCached(painter, option, paintBranchChildren, useCache, pixmapName); } /* * skulpture_color.cpp * */ #include "skulpture_p.h" #include /*-----------------------------------------------------------------------*/ QColor shaded_color(const QColor &color, int shade) { #if 1 const qreal contrast = 1.0; int r, g, b; color.getRgb(&r, &g, &b); int gray = qGray(r, g, b); gray = qMax(r, qMax(g, b)); gray = (r + b + g + 3 * gray) / 6; if (color.alpha() == 0) { gray = 200; } if (shade < 0) { qreal k = 220.0 / 255.0 * shade; k *= contrast; int a = 255; if (gray > 0) { a = int(k * 255 / (0 - gray)); if (a < 0) a = 0; if (a > 255) a = 255; } return QColor(0, 0, 0, a); } else { qreal k = (255 - 220.0) / (255.0) * shade; k *= contrast; int a = 255; if (gray < 255) { a = int(k * 255 / (255 - gray)); if (a < 0) a = 0; if (a > 255) a = 255; } return QColor(255, 255, 255, a); } #else if (shade < 0) { return QColor(0, 0, 0, -shade); } else { return QColor(255, 255, 255, shade); } #endif } QColor blend_color(const QColor &c0, const QColor &c1, qreal blend) { #if 0 // more exact, but probably slower QColor c; blend = qMin(1.0, qMax(0.0, blend)); c.setRgbF( c0.redF() * (1.0 - blend) + c1.redF() * blend, c0.greenF() * (1.0 - blend) + c1.greenF() * blend, c0.blueF() * (1.0 - blend) + c1.blueF() * blend, c0.alphaF() * (1.0 - blend) + c1.alphaF() * blend ); return c; #else int b = int(0.5 + 256.0 * blend); b = qMin(256, qMax(0, b)); QRgb rgba0 = c0.rgba(); QRgb rgba1 = c1.rgba(); return QColor( qRed(rgba0) + (((qRed(rgba1) - qRed(rgba0)) * b) >> 8), qGreen(rgba0) + (((qGreen(rgba1) - qGreen(rgba0)) * b) >> 8), qBlue(rgba0) + (((qBlue(rgba1) - qBlue(rgba0)) * b) >> 8), qAlpha(rgba0) + (((qAlpha(rgba1) - qAlpha(rgba0)) * b) >> 8) ); #endif } /*-----------------------------------------------------------------------*/ enum ColorScheme { NormalColorScheme, // allow 3D effects DarkColorScheme, // too dark, no 3D effects BrightColorScheme // too bright, no 3D effects }; ColorScheme guessColorScheme(const QPalette &palette, QPalette::ColorGroup colorGroup = QPalette::Active, QPalette::ColorRole colorRole = QPalette::Window) { const QColor windowColor = palette.color(colorGroup, colorRole); int r, g, b; windowColor.getRgb(&r, &g, &b); int brightness = qGray(r, g, b); if (brightness > 230) { return BrightColorScheme; } else if (brightness < 40) { return DarkColorScheme; } return NormalColorScheme; } static void computeAlternateBase(QPalette &palette, QPalette::ColorGroup colorGroup) { switch (guessColorScheme(palette, colorGroup, QPalette::Base)) { case DarkColorScheme: palette.setColor(colorGroup, QPalette::AlternateBase, palette.color(colorGroup, QPalette::Base).lighter(103)); break; case BrightColorScheme: case NormalColorScheme: palette.setColor(colorGroup, QPalette::AlternateBase, palette.color(colorGroup, QPalette::Base).darker(103)); break; } } static void copyColorGroup(QPalette &palette, QPalette::ColorGroup fromColorGroup, QPalette::ColorGroup toColorGroup) { for (int role = int(QPalette::WindowText); role <= int(QPalette::LinkVisited); ++role) { QPalette::ColorRole colorRole = QPalette::ColorRole(role); palette.setColor(toColorGroup, colorRole, palette.color(fromColorGroup, colorRole)); } } static void computeColorGroups(QPalette &palette, bool kdeMode = false, bool makeDisabledWidgetsTransparent = true) { // ### Is this used by pre-Qt 4.5 for HLine / VLine ? palette.setColor(QPalette::Disabled, QPalette::Dark, shaded_color(palette.color(QPalette::Active, QPalette::Window), -20)); palette.setColor(QPalette::Disabled, QPalette::Light, shaded_color(palette.color(QPalette::Active, QPalette::Window), 60)); if (!kdeMode) { // compute remaining colors in Active group computeAlternateBase(palette, QPalette::Active); // copy Active group to Inactive group copyColorGroup(palette, QPalette::Active, QPalette::Inactive); // compute remaining colors in Inactive group computeAlternateBase(palette, QPalette::Inactive); } if (!kdeMode || makeDisabledWidgetsTransparent) { // create Disabled group QColor disabledBackgroundColor = palette.color(QPalette::Active, QPalette::Window); QColor disabledForegroundColor; switch (guessColorScheme(palette, QPalette::Active, QPalette::Window)) { case DarkColorScheme: disabledForegroundColor = palette.color(QPalette::Active, QPalette::Window).lighter(125); break; case BrightColorScheme: case NormalColorScheme: disabledForegroundColor = palette.color(QPalette::Active, QPalette::Window).darker(125); break; } palette.setColor(QPalette::Disabled, QPalette::Window, disabledBackgroundColor); palette.setColor(QPalette::Disabled, QPalette::WindowText, disabledForegroundColor); palette.setColor(QPalette::Disabled, QPalette::Base, disabledBackgroundColor); palette.setColor(QPalette::Disabled, QPalette::Text, disabledForegroundColor); palette.setColor(QPalette::Disabled, QPalette::Link, disabledForegroundColor); palette.setColor(QPalette::Disabled, QPalette::LinkVisited, disabledForegroundColor); palette.setColor(QPalette::Disabled, QPalette::Button, disabledBackgroundColor); palette.setColor(QPalette::Disabled, QPalette::ButtonText, disabledForegroundColor); palette.setColor(QPalette::Disabled, QPalette::Highlight, disabledForegroundColor); palette.setColor(QPalette::Disabled, QPalette::HighlightedText, disabledBackgroundColor); computeAlternateBase(palette, QPalette::Disabled); } } QPalette SkulptureStyle::standardPalette() const { QPalette palette(QColor(205, 205, 205)); palette.setColor(QPalette::Active, QPalette::Base, QColor(229, 229, 229)); palette.setColor(QPalette::Active, QPalette::Text, QColor(0, 0, 0)); palette.setColor(QPalette::Active, QPalette::Link, QColor(80, 40, 120)); palette.setColor(QPalette::Active, QPalette::LinkVisited, QColor(80, 50, 80)); palette.setColor(QPalette::Active, QPalette::Highlight, QColor(114, 174, 211)); palette.setColor(QPalette::Active, QPalette::HighlightedText, QColor(0, 0, 0)); palette.setColor(QPalette::Active, QPalette::Window, QColor(200, 200, 200)); palette.setColor(QPalette::Active, QPalette::WindowText, QColor(0, 0, 0)); // palette.setColor(QPalette::Active, QPalette::Button, QColor(205, 205, 205)); palette.setColor(QPalette::Active, QPalette::ButtonText, QColor(0, 0, 0)); palette.setColor(QPalette::Active, QPalette::Shadow, QColor(0, 0, 0)); palette.setColor(QPalette::Active, QPalette::BrightText, QColor(240, 240, 240)); #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) palette.setColor(QPalette::Inactive, QPalette::ToolTipBase, QColor(240, 230, 190)); palette.setColor(QPalette::Inactive, QPalette::ToolTipText, QColor(0, 0, 0)); #endif computeColorGroups(palette); return palette; } void SkulptureStyle::polish(QPalette &palette) { ParentStyle::polish(palette); computeColorGroups(palette, qApp->inherits("KApplication"), d->makeDisabledWidgetsTransparent); } /* * skulpture_combobox.cpp * */ #include "skulpture_p.h" #include #include /*-----------------------------------------------------------------------*/ extern void paintComplexControlArea(QPainter *painter, const QStyleOption *option); void paintComboBox(QPainter *painter, const QStyleOptionComboBox *option, const QWidget *widget, const QStyle *style) { QStyleOptionComboBox opt = *option; const bool buttonMode = false; //!option->editable; QRect rect = style->subControlRect(QStyle::CC_ComboBox, option, QStyle::SC_ComboBoxArrow, widget); if (option->subControls & (QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField)) { if (buttonMode) { QStyleOptionButton buttonOption; buttonOption.QStyleOption::operator=(opt); if (buttonOption.state & QStyle::State_On) { buttonOption.state |= QStyle::State_Sunken; } else { buttonOption.state &= ~QStyle::State_Sunken; } buttonOption.state &= ~QStyle::State_On; // separator position opt.rect = rect; if (option->direction == Qt::LeftToRight) { opt.rect.setWidth(1); } else { opt.rect.setLeft(rect.left() + rect.width() - 1); } if (option->frame) { style->drawPrimitive(QStyle::PE_PanelButtonCommand, &buttonOption, painter, widget); QColor color = option->palette.color(QPalette::Button); if (!(opt.state & QStyle::State_On)) { opt.rect.translate(option->direction == Qt::LeftToRight ? -1 : 1, 0); } painter->fillRect(opt.rect, shaded_color(color, option->state & QStyle::State_Enabled ? -30 : -15)); if (option->state & QStyle::State_Enabled) { opt.rect.translate(option->direction == Qt::LeftToRight ? 1 : -1, 0); painter->fillRect(opt.rect, shaded_color(color, 80)); } } else { QColor bg = option->palette.color(QPalette::Button); painter->fillRect(option->rect, bg); painter->fillRect(opt.rect, shaded_color(bg, -15)); } } else { int fw = option->frame ? style->pixelMetric(QStyle::PM_ComboBoxFrameWidth, option, widget) : 0; QColor color = option->palette.color(QPalette::Base); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_HasFocus && option->editable) { color = blend_color(color, option->palette.color(QPalette::Highlight), 0.15); } else if (option->state & QStyle::State_MouseOver /*&& !option->editable*/) { color = color.lighter(103); } } QRect edit = style->subControlRect(QStyle::CC_ComboBox, option, QStyle::SC_ComboBoxFrame, widget).adjusted(fw, fw, -fw, -fw); painter->fillRect(edit, color); if (false && option->state & QStyle::State_Enabled && option->rect.height() <= 64) { QLinearGradient panelGradient(option->rect.topLeft(), option->rect.bottomLeft()); if (color.valueF() > 0.9) { panelGradient.setColorAt(0.0, shaded_color(color, -20)); } panelGradient.setColorAt(0.6, shaded_color(color, 0)); panelGradient.setColorAt(1.0, shaded_color(color, 10)); painter->fillRect(edit, panelGradient); } opt.rect = rect; if (!(option->activeSubControls & QStyle::SC_ComboBoxArrow)) { opt.state &= ~QStyle::State_MouseOver; } paintComplexControlArea(painter, &opt); if (option->subControls & QStyle::SC_ComboBoxFrame && option->frame) { QStyleOptionFrame frameOpt; frameOpt.QStyleOption::operator=(*option); frameOpt.rect = style->subControlRect(QStyle::CC_ComboBox, option, QStyle::SC_ComboBoxFrame, widget); frameOpt.state |= QStyle::State_Sunken; frameOpt.lineWidth = fw; frameOpt.midLineWidth = 0; style->drawPrimitive(QStyle::PE_FrameLineEdit, &frameOpt, painter, widget); } } } // arrow if (option->subControls & (QStyle::SC_ComboBoxArrow)) { opt.rect = rect; opt.state &= /*QStyle::State_MouseOver |*/ QStyle::State_Enabled; if (buttonMode) { opt.state &= ~QStyle::State_MouseOver; if (option->state & QStyle::State_On) { int sx = style->pixelMetric(QStyle::PM_ButtonShiftHorizontal, option, widget); int sy = style->pixelMetric(QStyle::PM_ButtonShiftVertical, option, widget); opt.rect.adjust(sx, sy, sx, sy); } } else { opt.palette.setColor(QPalette::ButtonText, opt.palette.color(option->state & QStyle::State_Enabled ? QPalette::WindowText : QPalette::Text)); } style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, painter, widget); } // focus frame if ((option->state & QStyle::State_HasFocus) && !option->editable) { QStyleOptionFocusRect focus; focus.QStyleOption::operator=(*option); focus.rect = style->subElementRect(QStyle::SE_ComboBoxFocusRect, option, widget); focus.state |= QStyle::State_FocusAtBorder; focus.backgroundColor = option->palette.color(buttonMode ? QPalette::Button : QPalette::Base); style->drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget); } } void paintComboBoxLabel(QPainter *painter, const QStyleOptionComboBox *option, const QWidget *widget, const QStyle *style) { QStyleOptionComboBox opt = *option; const bool buttonMode = false; //!option->editable; if (!buttonMode) { opt.palette.setColor(QPalette::Base, QColor(0, 0, 0, 0)); } else { painter->save(); painter->setPen(opt.palette.color(QPalette::ButtonText)); if (opt.state & QStyle::State_On) { int sx = style->pixelMetric(QStyle::PM_ButtonShiftHorizontal, option, widget); int sy = style->pixelMetric(QStyle::PM_ButtonShiftVertical, option, widget); opt.rect.adjust(sx, sy, sx, sy); } } ((const QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_ComboBoxLabel, &opt, painter, widget); if (buttonMode) { painter->restore(); } } /*-----------------------------------------------------------------------*/ QRect subControlRectComboBox(const QStyleOptionComboBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { int fw = option->frame ? style->pixelMetric(QStyle::PM_ComboBoxFrameWidth, option, widget) : 0; int bw = style->pixelMetric(QStyle::PM_ScrollBarExtent, option, widget); if (option->editable) bw = qMax(bw, 0); QRect rect; switch (subControl) { case QStyle::SC_ComboBoxArrow: rect = QRect(option->rect.right() - bw - fw + 1, option->rect.top() + fw, bw, option->rect.height() - 2 * fw); break; case QStyle::SC_ComboBoxEditField: { if (option->editable) { rect = option->rect.adjusted(fw, fw, -fw - bw, -fw); } else { rect = option->rect.adjusted(fw + 4, fw, -fw - bw - 4, -fw); } break; } case QStyle::SC_ComboBoxFrame: default: // avoid warning rect = option->rect; break; } return style->visualRect(option->direction, option->rect, rect); } QRect subElementRectComboBoxFocusRect(const QStyleOptionComboBox *option, const QWidget *widget, const QStyle *style) { int fw = option->frame ? (option->editable ? style->pixelMetric(QStyle::PM_ComboBoxFrameWidth, option, widget) : 4) : 2; int bw = true || option->editable ? qMax(style->pixelMetric(QStyle::PM_ScrollBarExtent, option, widget), 0) : 0; return style->visualRect(option->direction, option->rect, option->rect.adjusted(fw, fw, -fw - bw, -fw)); } /* * skulpture_complex.cpp * */ #include "skulpture_p.h" /*-----------------------------------------------------------------------*/ extern QRect subControlRectSpinBox(const QStyleOptionSpinBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style); extern QRect subControlRectScrollBar(const QStyleOptionSlider *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style, ArrowPlacementMode horizontalArrowMode, ArrowPlacementMode verticalArrowMode); extern QRect subControlRectSlider(const QStyleOptionSlider *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style); extern QRect subControlRectToolButton(const QStyleOptionToolButton *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style); extern QRect subControlRectComboBox(const QStyleOptionComboBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style); extern QRect subControlRectGroupBox(const QStyleOptionGroupBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style); extern QRect subControlRectTitleBar(const QStyleOptionTitleBar *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style); /*-----------------------------------------------------------------------*/ #define SC_CASE(cc, so) \ case CC_## cc: \ if (option->type == QStyleOption::SO_## so) { \ return subControlRect ## cc((const QStyleOption ## so *) option, subControl, widget, this); \ } \ break QRect SkulptureStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const { switch (control) { SC_CASE(SpinBox, SpinBox); SC_CASE(ComboBox, ComboBox); case CC_ScrollBar: if (option && option && option->type == QStyleOption::SO_Slider) { return subControlRectScrollBar((const QStyleOptionSlider *) option, subControl, widget, this, d->horizontalArrowMode, d->verticalArrowMode); } break; SC_CASE(Slider, Slider); SC_CASE(TitleBar, TitleBar); #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) case CC_Q3ListView: break; #endif SC_CASE(ToolButton, ToolButton); case CC_Dial: break; //#if (QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)) SC_CASE(GroupBox, GroupBox); //#endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) case CC_MdiControls: break; #endif case CC_CustomBase: // avoid warning break; } return ParentStyle::subControlRect(control, option, subControl, widget); } /*-----------------------------------------------------------------------*/ extern QStyle::SubControl hitTestComplexControlScrollBar(const QStyleOptionSlider *option, const QPoint &position, const QWidget *widget, const QStyle *style, ArrowPlacementMode horizontalArrowMode, ArrowPlacementMode verticalArrowMode); /*-----------------------------------------------------------------------*/ #define HIT_CASE(cc, so) \ case CC_## cc: \ if (option->type == QStyleOption::SO_## so) { \ return hitTestComplexControl ## cc((const QStyleOption ## so *) option, position, widget, this); \ } \ break QStyle::SubControl SkulptureStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget) const { switch (control) { case CC_ScrollBar: if (option->type == QStyleOption::SO_Slider) { return hitTestComplexControlScrollBar((const QStyleOptionSlider *) option, position, widget, this, d->horizontalArrowMode, d->verticalArrowMode); } break; default: break; } return ParentStyle::hitTestComplexControl(control, option, position, widget); } /*-----------------------------------------------------------------------*/ extern void paintSpinBox(QPainter *painter, const QStyleOptionSpinBox *option, const QWidget *widget, const QStyle *style); extern void paintComboBox(QPainter *painter, const QStyleOptionComboBox *option, const QWidget *widget, const QStyle *style); extern void paintScrollBar(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style, ArrowPlacementMode horizontalArrowMode, ArrowPlacementMode verticalArrowMode); extern void paintSlider(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); extern void paintToolButton(QPainter *painter, const QStyleOptionToolButton *option, const QWidget *widget, const QStyle *style); extern void paintTitleBar(QPainter *painter, const QStyleOptionTitleBar *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) extern void paintQ3ListView(QPainter *painter, const QStyleOptionQ3ListView *option, const QWidget *widget, const QStyle *style); #endif extern void paintDial(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); //extern void paintGroupBox(QPainter *painter, const QStyleOptionGroupBox *option, const QWidget *widget, const QStyle *style); //extern void paintMdiControls(QPainter *painter, const QStyleOptionComplex *option, const QWidget *widget, const QStyle *style); /*-----------------------------------------------------------------------*/ #define CC_CASE(cc, so) \ case CC_## cc: \ if (option->type == QStyleOption::SO_## so) { \ paint ## cc(painter, (const QStyleOption ## so *) option, widget, this); \ return; \ } \ break void SkulptureStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { switch (control) { CC_CASE(SpinBox, SpinBox); CC_CASE(ComboBox, ComboBox); case CC_ScrollBar: if (option->type == QStyleOption::SO_Slider) { paintScrollBar(painter, (const QStyleOptionSlider *) option, widget, this, d->horizontalArrowMode, d->verticalArrowMode); return; } break; CC_CASE(Slider, Slider); CC_CASE(ToolButton, ToolButton); CC_CASE(TitleBar, TitleBar); #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) CC_CASE(Q3ListView, Q3ListView); #endif CC_CASE(Dial, Slider); //#if (QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)) case CC_GroupBox: break; //#endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) case CC_MdiControls: break; #endif case CC_CustomBase: // avoid warning break; } ParentStyle::drawComplexControl(control, option, painter, widget); } /* * skulpture_dial.cpp * */ #include "skulpture_p.h" #include #include #include /*-----------------------------------------------------------------------*/ extern void paintIndicatorDial(QPainter *painter, const QStyleOptionSlider *option); extern void paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole bgrole); void paintDial(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style) { int d = qMin(option->rect.width() & ~1, option->rect.height() & ~1); QStyleOptionSlider opt = *option; const QAbstractSlider *slider; // always highlight knob if pressed (even if mouse is not over knob) if ((option->state & QStyle::State_HasFocus) && (slider = qobject_cast(widget))) { if (slider->isSliderDown()) { opt.state |= QStyle::State_MouseOver; } } // tickmarks opt.palette.setColor(QPalette::Inactive, QPalette::WindowText, QColor(120, 120, 120, 255)); opt.palette.setColor(QPalette::Active, QPalette::WindowText, QColor(120, 120, 120, 255)); opt.state &= ~QStyle::State_HasFocus; opt.rect.setWidth(opt.rect.width() & ~1); opt.rect.setHeight(opt.rect.height() & ~1); ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_Dial, &opt, painter, widget); #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)) opt.rect.setWidth((opt.rect.width() & ~1) - 1); opt.rect.setHeight((opt.rect.height() & ~1) - 1); opt.rect.translate(1, 1); #else if (runtimeQtVersion() >= QT_VERSION_CHECK(4, 6, 0)) { opt.rect.setWidth((opt.rect.width() & ~1) - 1); opt.rect.setHeight((opt.rect.height() & ~1) - 1); opt.rect.translate(1, 1); } #endif // focus rectangle if (option->state & QStyle::State_HasFocus) { QStyleOptionFocusRect focus; opt.state |= QStyle::State_HasFocus; focus.QStyleOption::operator=(opt); focus.rect.adjust(-1, -1, 1, 1); style->drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget); } opt.palette = option->palette; // dial base if (d <= 256) { paintIndicatorDial(painter, &opt); } else { // large dials are slow to render, do not render them } // dial knob d -= 6; int gripSize = (option->fontMetrics.height() / 4) * 2 - 1; opt.rect.setSize(QSize(gripSize, gripSize)); opt.rect.moveCenter(option->rect.center()); // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA. qreal angle; int sliderPosition = option->upsideDown ? option->sliderPosition : (option->maximum - option->sliderPosition); int range = option->maximum - option->minimum; if (!range) { angle = M_PI / 2; } else if (option->dialWrapping) { angle = M_PI * 1.5 - (sliderPosition - option->minimum) * 2 * M_PI / range; } else { angle = (M_PI * 8 - (sliderPosition - option->minimum) * 10 * M_PI / range) / 6; } qreal rr = d / 2.0 - gripSize - 2; opt.rect.translate(int(0.5 + rr * cos(angle)), int(0.5 - rr * sin(angle))); paintCachedGrip(painter, &opt, option->state & QStyle::State_Enabled ? QPalette::Button : QPalette::Window); } /* * skulpture_dock.cpp * */ #include "skulpture_p.h" #include #include /*-----------------------------------------------------------------------*/ void paintFrameDockWidget(QPainter *painter, const QStyleOptionFrame *option, const QWidget */*widget*/, const QStyle */*style*/) { paintThinFrame(painter, option->rect, option->palette, -60, 160); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -20, 60); } void paintDockWidgetTitle(QPainter *painter, const QStyleOptionDockWidget *option, const QWidget *widget, const QStyle *style) { const QDockWidget *dock = qobject_cast(widget); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) const bool vertical = dock && (dock->features() & QDockWidget::DockWidgetVerticalTitleBar); #else const bool vertical = false; #endif const bool floating = dock && dock->isFloating(); QRect r = option->rect; if (floating) { if (vertical) { r.adjust(-3, 3, 0, -3); } else { r.adjust(3, -3, -3, 0); } // painter->fillRect(r.adjusted(1, 1, -1, -1), QColor(30, 40, 80)); } QColor color = option->palette.color(QPalette::Window); paintThinFrame(painter, r, option->palette, 40, -20); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -20, 80); QLinearGradient gradient(r.topLeft(), vertical ? r.topRight() : r.bottomLeft()); gradient.setColorAt(0.0, shaded_color(color, 50)); gradient.setColorAt(0.2, shaded_color(color, 30)); gradient.setColorAt(0.5, shaded_color(color, 0)); gradient.setColorAt(0.51, shaded_color(color, -10)); gradient.setColorAt(1.0, shaded_color(color, -20)); painter->fillRect(r.adjusted(1, 1, -1, -1), gradient); #if 0 QRadialGradient dialogGradient2(r.left() + r.width() / 2, r.top(), r.height()); dialogGradient2.setColorAt(0.0, QColor(255, 255, 255, 50)); dialogGradient2.setColorAt(1.0, QColor(0, 0, 0, 0)); painter->save(); painter->translate(r.center()); painter->scale(r.width() / 2.0 / r.height(), 1); painter->translate(-r.center()); painter->fillRect(r.adjusted(1, 1, -1, -1), dialogGradient2); painter->restore(); #endif QFont font = painter->font(); font.setBold(true); font.setPointSizeF(font.pointSizeF() / 1.19); painter->save(); painter->setFont(font); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) r = style->subElementRect(QStyle::SE_DockWidgetTitleBarText, option, widget); #else // FIXME r = option->rect; #endif // ### fix for Plastique centering if (vertical && option->rect.height() & 1) { if (!floating) { r.adjust(0, 1, 0, 1); } else { r.adjust(0, -1, 0, -1); } } if (floating) { if (vertical) { r.adjust(-1, 12, 3, -10); } else { r.adjust(2, 3, -3, -7); } } else { if (vertical) { r.adjust(0, 8, 4, -8); } else { r.adjust(0, 5, 0, -7); } } if (vertical) { QTransform mat; QPointF c = r.center(); mat.translate(c.x(), c.y()); mat.rotate(-90); mat.translate(-c.x(), -c.y()); r = mat.mapRect(r); painter->setTransform(mat, true); } // painter->fillRect(r, Qt::red); painter->setClipRect(r); style->drawItemText(painter, r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic, option->palette, true, option->title, QPalette::WindowText); painter->restore(); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) QRect subElementRectDockWidget(QStyle::SubElement element, const QStyleOptionDockWidget *option, const QWidget *widget, const QStyle *style) { switch (element) { case QStyle::SE_DockWidgetCloseButton: case QStyle::SE_DockWidgetFloatButton: { const QDockWidget *dock = qobject_cast(widget); bool floating = option->floatable && dock && dock->isFloating(); bool vertical = dock && (dock->features() & QDockWidget::DockWidgetVerticalTitleBar); QRect r = ((QCommonStyle *) style)->QCommonStyle::subElementRect(element, option, widget); if (!vertical) { if (floating) { if (option->direction == Qt::LeftToRight) { return r.adjusted(-6, 0, -6, 0); } else { return r.adjusted(6, 0, 6, 0); } } else { if (option->direction == Qt::LeftToRight) { return r.adjusted(-3, 1, -3, 1); } else { return r.adjusted(3, 1, 3, 1); } } } else { if (floating) { return r.adjusted(0, 6, 0, 6); } else { return r.adjusted(1, 3, 1, 3); } } } case QStyle::SE_DockWidgetTitleBarText: return ((QCommonStyle *) style)->QCommonStyle::subElementRect(element, option, widget).adjusted(4, -3, -4, 5); case QStyle::SE_DockWidgetIcon: return ((QCommonStyle *) style)->QCommonStyle::subElementRect(element, option, widget).adjusted(4, -3, 4, 5); default: // avoid warning return option->rect; } } #endif /* * skulpture_factory.cpp * */ #include "skulpture_p.h" #include "sk_factory.h" /*-----------------------------------------------------------------------*/ bool AbstractFactory::evalCondition() { Code code = *p++; if (code < Or) { qreal v1 = evalValue(); qreal v2 = evalValue(); switch (code) { case EQ: return qAbs(v1 - v2) < 1.0e-9; case NE: return qAbs(v1 - v2) >= 1.0e-9; case LT: return v1 < v2; case GE: return v1 >= v2; case GT: return v1 > v2; case LE: return v1 <= v2; default: break; } } else { switch (code) { case OptionState: return opt && (opt->state & (1 << *p++)); case OptionRTL: return opt && (opt->direction != Qt::LeftToRight); case OptionVersion: return opt && (opt->version >= *p++); case OptionType: return opt && (!*p || opt->type == *p++); case OptionComplex: return opt && ((!*p && opt->type >= QStyleOption::SO_Complex) || (opt->type == QStyleOption::SO_Complex + *p++)); case FactoryVersion: return version() >= *p++; case Not: return !evalCondition(); case Or: if (evalCondition()) { skipCondition(); return true; } else { return evalCondition(); } case And: if (!evalCondition()) { skipCondition(); return false; } else { return evalCondition(); } default: break; } } return false; } void AbstractFactory::skipCondition() { Code code = *p++; if (code < Or) { skipValue(); skipValue(); } else { skipCondition(); skipCondition(); } } /*-----------------------------------------------------------------------*/ qreal AbstractFactory::evalValue() { Code code = *p++; if (code >= MinVal && code <= MaxVal) { return code * 0.01; } else if (code >= GetVar + MinVar && code <= GetVar + MaxVar) { return var[code - GetVar]; } else if (code >= Add && code <= Max) { qreal v1 = evalValue(); qreal v2 = evalValue(); switch (code) { case Add: return v1 + v2; case Sub: return v1 - v2; case Mul: return v1 * v2; case Div: return v2 != 0 ? v1 / v2 : 0; case Min: return qMin(v1, v2); case Max: return qMax(v1, v2); } } else if (code == Mix) { qreal v = evalValue(); return v * evalValue() + (1 - v) * evalValue(); } else if (code == Cond) { if (evalCondition()) { qreal v = evalValue(); skipValue(); return v; } else { skipValue(); return evalValue(); } } return 0; } void AbstractFactory::skipValue() { Code code = *p++; if (code >= MinVal && code <= MaxVal) { return; } else if (code >= GetVar + MinVar && code <= GetVar + MaxVar) { return; } else if (code >= Add && code <= Max) { skipValue(); skipValue(); return; } else if (code == Mix) { skipValue(); skipValue(); skipValue(); return; } else if (code == Cond) { skipCondition(); skipValue(); skipValue(); return; } } /*-----------------------------------------------------------------------*/ QColor AbstractFactory::evalColor() { Code code = *p++; switch (code) { case RGB: { const quint8 *c = (const quint8 *) p; p += 3; return QColor(c[0], c[1], c[2]); } case RGBA: { const quint8 *c = (const quint8 *) p; p += 4; return QColor(c[0], c[1], c[2], c[3]); } case RGBAf: { qreal v[4]; for (int n = 0; n < 4; ++n) { v[n] = qMin(qMax(qreal(0), evalValue()), qreal(1)); } return QColor::fromRgbF(v[0], v[1], v[2], v[3]); } case Blend: { QColor color0 = evalColor(); QColor color1 = evalColor(); return blend_color(color0, color1, evalValue()); } case Palette: { if (opt) { return opt->palette.color(QPalette::ColorRole(*p++)); } break; } case Shade: { QColor color = evalColor(); return shaded_color(color, int(evalValue() * 200)); } case Darker: { QColor color = evalColor(); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) return color.darker(*p++); #else return color.dark(*p++); #endif } case Lighter: { QColor color = evalColor(); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) return color.lighter(*p++); #else return color.light(*p++); #endif } default: break; } return QColor(); } void AbstractFactory::skipColor() { Code code = *p++; switch (code) { case RGB: { p += 3; return; } case RGBA: { p += 4; return; } case RGBAf: { for (int n = 0; n < 4; ++n) { skipValue(); } return; } case Blend: { skipColor(); skipColor(); skipValue(); return; } case Palette: { ++p; return; } case Shade: { skipColor(); skipValue(); return; } case Darker: case Lighter: { skipColor(); p++; return; } default: break; } } /*-----------------------------------------------------------------------*/ void AbstractFactory::executeCode(Code code) { if (code >= SetVar + MinVar && code <= SetVar + MaxVar) { var[code - SetVar] = evalValue(); } else switch (code) { case Begin: { while (*p != End) { Code code = *p++; executeCode(code); } ++p; return; } case While: { const Code *loop_p = p; int counter = 100; // prevent infinite loop while (evalCondition() && --counter >= 0) { Code code = *p++; executeCode(code); p = loop_p; } Code code = *p++; skipCode(code); return; } case If: { if (evalCondition()) { Code code = *p++; executeCode(code); if (*p == Else) { ++p; Code code = *p++; skipCode(code); } } else { Code code = *p++; skipCode(code); if (*p == Else) { ++p; Code code = *p++; executeCode(code); } } return; } } } void AbstractFactory::skipCode(Code code) { if (code >= SetVar + MinVar && code <= SetVar + MaxVar) { skipValue(); } else switch (code) { case Begin: { while (*p != End) { Code code = *p++; skipCode(code); } ++p; return; } case While: { skipCondition(); Code code = *p++; skipCode(code); return; } case If: { skipCondition(); Code code = *p++; skipCode(code); if (*p == Else) { ++p; Code code = *p++; skipCode(code); } return; } } } /*-----------------------------------------------------------------------*/ void AbstractFactory::create() { if (p != 0) { while (*p != End) { Code code = *p++; executeCode(code); } } } /* * skulpture_frames.cpp * */ #include "skulpture_p.h" #include #include #include #include #include #include #include #include #include #include #include /*-----------------------------------------------------------------------*/ static void paintThinFrame(QPainter *painter, const QRect &rect, const QBrush &brush1, const QBrush &brush2) { painter->fillRect(QRect(rect.left() + 1, rect.top(), rect.width() - 1, 1), brush2); painter->fillRect(QRect(rect.left(), rect.top(), 1, rect.height()), brush2); painter->fillRect(QRect(rect.left(), rect.bottom(), rect.width() - 1, 1), brush1); painter->fillRect(QRect(rect.right(), rect.top(), 1, rect.height()), brush1); } static const QBrush shaded_brush(const QPalette &palette, int shade, QPalette::ColorRole bgrole) { return (shaded_color(palette.color(bgrole), shade)); } /*-----------------------------------------------------------------------*/ /** * paintThinFrame - paint a single pixel wide frame * * Paints a frame _inside_ the specified rectangle, using * a single pixel wide pen. The frame is rendered by darkening * or brightening the pixels in that area; no specific color * can be selected. * * dark and light specify how dark or bright the frame should * be rendered. They are either negative (meaning darkening), * or positive (meaning brigthening). * * TODO: * dark and light are arbitrary values; they need adjustment. * */ void paintThinFrame(QPainter *painter, const QRect &rect, const QPalette &palette, int dark, int light, QPalette::ColorRole bgrole) { paintThinFrame(painter, rect, shaded_brush(palette, dark, bgrole), shaded_brush(palette, light, bgrole)); } void paintRecessedFrame(QPainter *painter, const QRect &rect, const QPalette &palette, enum RecessedFrame rf, QPalette::ColorRole bgrole) { paintThinFrame(painter, rect, palette, 30, -20, bgrole); paintThinFrame(painter, rect.adjusted(1, 1, -1, -1), palette, -20, -70, bgrole); paintRecessedFrameShadow(painter, rect.adjusted(2, 2, -2, -2), rf); } /*-----------------------------------------------------------------------*/ void paintFrameGroupBox(QPainter *painter, const QStyleOptionFrame *option, const QWidget */*widget*/, const QStyle */*style*/) { QRect r = option->rect; r.setHeight(/*r.height() +*/ 2); paintThinFrame(painter, r, option->palette, 60, -20); // paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -20, 60); } static inline bool is_popup_menu(const QWidget *widget) { if (widget) { Qt::WindowFlags flags = widget->windowFlags(); Qt::WindowType type = Qt::WindowType(int(flags & Qt::WindowType_Mask)); if ((type & Qt::Window) && (flags & Qt::FramelessWindowHint || type == Qt::Popup)) { return true; } } return false; } void paintStyledFrame(QPainter *painter, const QStyleOptionFrame *option, const QWidget *widget, const QStyle */*style*/) { QPalette::ColorRole bgrole = widget ? widget->backgroundRole() : QPalette::Window; if (option->state & QStyle::State_Sunken) { if (qobject_cast(widget) && widget->parentWidget() && widget->parentWidget()->inherits("KFontRequester")) { paintThinFrame(painter, option->rect, option->palette, 60, -20); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -20, 60); QLinearGradient panelGradient(option->rect.topLeft(), option->rect.bottomLeft()); panelGradient.setColorAt(0.6, QColor(255, 255, 255, 0)); panelGradient.setColorAt(1.0, shaded_color(option->palette.color(QPalette::Window), 70)); painter->fillRect(option->rect.adjusted(2, 2, -2, -2), panelGradient); } else { /* if (option->palette.color(QPalette::Base) == QColor(220, 230, 210)) { painter->fillRect(option->rect.adjusted(2, 2, -2, -2), option->palette.color(QPalette::Base)); paintRecessedFrame(painter, option->rect, option->palette, RF_Small); } else*/ { RecessedFrame rf = RF_Large; if (!(option->state & QStyle::State_Enabled) || (widget && (!widget->isEnabled() || qobject_cast(widget)))) { rf = RF_Small; } if (qobject_cast(widget) || (widget && widget->inherits("Q3ScrollView"))) { const QList children = widget->children(); Q_FOREACH (QObject *child, children) { if (qobject_cast(child)) { rf = RF_None; break; } } } paintRecessedFrame(painter, option->rect, option->palette, rf); } } } else if (option->state & QStyle::State_Raised) { QRect r = option->rect; if (option->lineWidth == 0) { paintThinFrame(painter, r, option->palette, -20, 60); } else { paintThinFrame(painter, r, option->palette, -10, -20); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -40, 80, bgrole); // painter->fillRect(option->rect, Qt::red); } } else { // Plain if (qobject_cast(widget) && widget->parentWidget() && widget->parentWidget()->inherits("KTitleWidget")) { QRect r = option->rect; bgrole = QPalette::Window; // bgrole = QPalette::Base; #if 1 QColor bgcolor = option->palette.color(bgrole); #else QColor bgcolor = QColor(230, 230, 230); #endif // painter->fillRect(r.adjusted(1, 1, -1, -1), bgcolor); paintThinFrame(painter, r, option->palette, -10, -20); // painter->fillRect(r.adjusted(1, 1, -1, -1), QColor(200, 190, 160)); // painter->fillRect(r.adjusted(1, 1, -1, -1), QColor(240, 240, 240)); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -30, 80, bgrole); QLinearGradient gradient(r.topLeft(), r.bottomLeft()); gradient.setColorAt(0.0, shaded_color(bgcolor, 90)); gradient.setColorAt(0.2, shaded_color(bgcolor, 60)); gradient.setColorAt(0.5, shaded_color(bgcolor, 0)); gradient.setColorAt(0.51, shaded_color(bgcolor, -10)); gradient.setColorAt(1.0, shaded_color(bgcolor, -20)); painter->fillRect(r.adjusted(1, 1, -1, -1), gradient); #if 0 QRadialGradient dialogGradient2(r.left() + r.width() / 2, r.top(), r.height()); dialogGradient2.setColorAt(0.0, QColor(255, 255, 255, 50)); dialogGradient2.setColorAt(1.0, QColor(0, 0, 0, 0)); painter->save(); painter->translate(r.center()); painter->scale(r.width() / 2.0 / r.height(), 1); painter->translate(-r.center()); painter->fillRect(r.adjusted(1, 1, -1, -1), dialogGradient2); painter->restore(); #endif } else if (is_popup_menu(widget)) { QRect r = option->rect; paintThinFrame(painter, r, option->palette, -60, 160); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -20, 60, bgrole); } else { QRect r = option->rect; paintThinFrame(painter, r, option->palette, 60, -20); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -20, 60, bgrole); } } } void paintFrameLineEdit(QPainter *painter, const QStyleOptionFrame *option, const QWidget */*widget*/, const QStyle */*style*/) { paintRecessedFrame(painter, option->rect, option->palette, RF_Small); } class LineEditHack : public QLineEdit { public: QRect cursorRectHack() const { #if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) return cursorRect(); #else return inputMethodQuery(Qt::ImMicroFocus).toRect(); #endif } }; static QRect getCursorRect(const QWidget *widget) { if (const QLineEdit *lineEdit = qobject_cast(widget)) { const LineEditHack *lineEditHack = reinterpret_cast(lineEdit); /*if (lineEdit->cursorPosition() != lineEdit->text().length())*/ { return lineEditHack->cursorRectHack(); } } return QRect(); } void lineEditMouseMoved(QLineEdit *lineEdit, QMouseEvent *event) { if (!lineEdit->hasFocus()) { QAbstractSpinBox *spinBox = qobject_cast(lineEdit->parentWidget()); int oldCursorPosition = lineEdit->cursorPosition(); int newCursorPosition = lineEdit->cursorPositionAt(event->pos()); if (spinBox && lineEdit->text() == spinBox->specialValueText()) { // newCursorPosition = lineEdit->text().length(); } else { if (QSpinBox *spinBox = qobject_cast(lineEdit->parentWidget())) { newCursorPosition = qBound(spinBox->prefix().length(), newCursorPosition, lineEdit->text().length() - spinBox->suffix().length()); } else if (QDoubleSpinBox *spinBox = qobject_cast(lineEdit->parentWidget())) { newCursorPosition = qBound(spinBox->prefix().length(), newCursorPosition, lineEdit->text().length() - spinBox->suffix().length()); } } if (oldCursorPosition != newCursorPosition) { lineEdit->update(getCursorRect(lineEdit).adjusted(-4, -16, 4, 16)); lineEdit->setCursorPosition(newCursorPosition); lineEdit->update(getCursorRect(lineEdit).adjusted(-4, -16, 4, 16)); } } } void paintPanelLineEdit(QPainter *painter, const QStyleOptionFrame *option, const QWidget *widget, const QStyle *style) { QPalette::ColorRole bgrole = widget ? widget->backgroundRole() : QPalette::Window; bool focus = (option->state & QStyle::State_HasFocus) && !(option->state & QStyle::State_ReadOnly); int fw = option->lineWidth; if (option->palette.brush(bgrole).style() == Qt::SolidPattern) { QRect cursorRect; QColor color = option->palette.color(bgrole); // printf("style=%d, bgrole=%d, panel color: r=%d, g=%d, b=%d, a=%d\n", option->palette.brush(bgrole).style(), bgrole, color.red(), color.green(), color.blue(), color.alpha()); if (focus && color.alpha() > 0) { color = blend_color(color, option->palette.color(QPalette::Highlight), 0.15); } else { focus = false; #if 1 if (option->state & QStyle::State_MouseOver && option->state & QStyle::State_Enabled && !(option->state & QStyle::State_ReadOnly)) { color = color.lighter(103); cursorRect = getCursorRect(widget); } else if (widget) { QWidget *box = widget->parentWidget(); if (qobject_cast(box) || qobject_cast(box)) { if (box->underMouse() && option->state & QStyle::State_Enabled) { QAbstractSpinBox *spinBox = qobject_cast(box); if (!spinBox || !spinBox->isReadOnly()) { color = color.lighter(103); } } } } #endif } painter->fillRect(option->rect.adjusted(fw, fw, -fw, -fw), color); if (false && option->state & QStyle::State_Enabled && option->rect.height() <= 64) { QLinearGradient panelGradient(option->rect.topLeft(), option->rect.bottomLeft()); if (color.valueF() > 0.9) { panelGradient.setColorAt(0.0, shaded_color(color, -20)); } panelGradient.setColorAt(0.6, shaded_color(color, 0)); panelGradient.setColorAt(1.0, shaded_color(color, 10)); painter->fillRect(option->rect.adjusted(fw, fw, -fw, -fw), panelGradient); } if (!cursorRect.isEmpty()) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) QRect cursor = style->subElementRect(QStyle::SE_LineEditContents, option, widget).adjusted(0, 2, 0, -3); #else QRect cursor = option->rect.adjusted(0, fw + 2, 0, -fw - 3); #endif if (cursor.height() != option->fontMetrics.height() - 1) { cursor.adjust(0, 1, 0, 0); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) int cursorWidth = style->pixelMetric(QStyle::PM_TextCursorWidth, option, widget); #else int cursorWidth = style->pixelMetric((QStyle::PixelMetric)((int) QStyle::PM_CustomBase + 1), option, widget); #endif cursor.setLeft(cursorRect.center().x() + 1 - (cursorWidth >> 1)); cursor.setWidth(cursorWidth); cursor.setTop(cursor.top() + ((cursor.height() - option->fontMetrics.height() + 2) >> 1)); cursor.setHeight(cursorRect.height() - 2); QColor color = option->palette.color(QPalette::Text); color.setAlpha(60); painter->fillRect(cursor, color); painter->fillRect(QRect(cursor.left() - cursorWidth, cursor.top() - 1, cursorWidth, 1), color); painter->fillRect(QRect(cursor.left() + cursorWidth, cursor.top() - 1, cursorWidth, 1), color); painter->fillRect(QRect(cursor.left() - cursorWidth, cursor.bottom() + 1, cursorWidth, 1), color); painter->fillRect(QRect(cursor.left() + cursorWidth, cursor.bottom() + 1, cursorWidth, 1), color); } } if (focus && option->state & QStyle::State_KeyboardFocusChange) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) QColor color = option->palette.color(QPalette::Highlight).darker(120); #else QColor color = option->palette.color(QPalette::Highlight).dark(120); #endif color.setAlpha(120); QRect r = option->rect.adjusted(fw + 2, fw + 2, -fw - 2, -fw - 2); r.setTop(r.top() + r.height() - 1); painter->fillRect(r, color); } if (fw) { if (option->state & QStyle::State_ReadOnly && !(option->state & QStyle::State_Enabled)) { paintThinFrame(painter, option->rect, option->palette, 60, -20); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -20, 60); } else { paintRecessedFrame(painter, option->rect, option->palette, option->rect.height() <= 64 ? RF_Small : RF_Small); } } else if (widget && widget->parent() && (qobject_cast(widget->parent()) || qobject_cast(widget->parent()))) { if (option->palette.brush(bgrole).style() != Qt::SolidPattern) { /* Fix Qt stylesheet demo */ return; } // we need to adjust shadows to the real frame, not that of the line edit int left = widget->geometry().left(), right = widget->geometry().right(); QComboBox *combo = qobject_cast(widget->parent()); int parentFrameWidth; if (combo) { if (!combo->hasFrame()) { return; } parentFrameWidth = style->pixelMetric(QStyle::PM_ComboBoxFrameWidth, option, widget); } else { QAbstractSpinBox *spin = qobject_cast(widget->parent()); if (spin && !spin->hasFrame()) { return; } parentFrameWidth = style->pixelMetric(QStyle::PM_SpinBoxFrameWidth, option, widget); } paintRecessedFrameShadow(painter, option->rect.adjusted(parentFrameWidth - left, 0, widget->parentWidget()->geometry().width() - right - parentFrameWidth - 1, 0), option->rect.height() <= 64 ? RF_Small : RF_Small); } } void paintFrameFocusRect(QPainter *painter, const QStyleOptionFocusRect *option, const QWidget *widget, const QStyle */*style*/) { if (!(option->state & QStyle::State_KeyboardFocusChange)) { return; } if (option->state & QStyle::State_Item) { if (widget && widget->window() && !widget->window()->testAttribute(Qt::WA_KeyboardFocusChange)) { return; } } QColor color = option->palette.color(QPalette::Highlight); color.setAlpha(20); painter->fillRect(option->rect, color); // painter->fillRect(option->rect.adjusted(1, 1, -1, -1), color); painter->fillRect(option->rect.adjusted(2, 2, -2, -2), color); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) color = color.darker(120); #else color = color.dark(120); #endif color.setAlpha(230); painter->fillRect(option->rect.adjusted(0, option->rect.height() - 1, 0, 0), color); } //#if (QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)) QRect subControlRectGroupBox(const QStyleOptionGroupBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { switch (subControl) { case QStyle::SC_GroupBoxContents: return option->rect.adjusted(0, option->fontMetrics.height(), 0, 0); case QStyle::SC_GroupBoxCheckBox: case QStyle::SC_GroupBoxLabel: { int x = option->direction == Qt::LeftToRight ? -8 : 8; int y = (subControl == QStyle::SC_GroupBoxCheckBox) ? 0 : 1; return ((const QCommonStyle *) style)->QCommonStyle::subControlRect(QStyle::CC_GroupBox, option, subControl, widget).adjusted(x, y, x, y); break; } default: break; } return ((const QCommonStyle *) style)->QCommonStyle::subControlRect(QStyle::CC_GroupBox, option, subControl, widget); } //#endif /*-----------------------------------------------------------------------*/ QGradient path_edge_gradient(const QRectF &rect, const QStyleOption *option, const QPainterPath &path, const QColor &color2, const QColor &color1) { QPointF c = rect.center(); QColor color[8]; if (/*true ||*/ option->direction == Qt::LeftToRight) { color[0] = blend_color(QColor(255, 255, 255, 255), color1, 0.5); color[1] = color1; color[2] = blend_color(color1, color2, 0.5); color[3] = color2; // color[3] = color1; color[4] = blend_color(QColor(0, 0, 0, 255), color2, 0.5); color[5] = color2; color[6] = blend_color(color2, color1, 0.5); color[7] = color1; // color[7] = color2; } else { color[2] = blend_color(QColor(255, 255, 255, 255), color1, 0.5); color[1] = color1; color[0] = blend_color(color1, color2, 0.5); color[7] = color2; // color[7] = color1; color[6] = blend_color(QColor(0, 0, 0, 255), color2, 0.5); color[5] = color2; color[4] = blend_color(color2, color1, 0.5); color[3] = color1; // color[3] = color2; } QConicalGradient gradient(c, 0); Q_UNUSED(path); qreal angle; qreal d = 1; QRectF r = rect.adjusted(1, 1, -1, -1); { QRectF rect = r; gradient.setColorAt(0.0, color[3]); angle = atan2(rect.top() + d - c.y(), rect.right() - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[3]); angle = atan2(rect.top() - c.y(), rect.right() - d - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[5]); angle = atan2(rect.top() - c.y(), rect.left() + d - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[5]); angle = atan2(rect.top() + d - c.y(), rect.left() - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[7]); angle = atan2(rect.bottom() - d - c.y(), rect.left() - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[7]); angle = atan2(rect.bottom() - c.y(), rect.left() + d - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[1]); angle = atan2(rect.bottom() - c.y(), rect.right() - d - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[1]); angle = atan2(rect.bottom() - d - c.y(), rect.right() - c.x()); if (angle < 0) angle += M_PI * 2.0; gradient.setColorAt(angle / 2.0 / M_PI, color[3]); gradient.setColorAt(1.0, color[3]); } return gradient; } /* * skulpture_gradients.cpp * */ #include "skulpture_p.h" #include "sk_factory.h" /*-----------------------------------------------------------------------*/ /** * GradientFactory - create a QGradient from a description * * The gradient description is a bytecode stream that allows simple arithmetic, * conditionals, and looping. * */ /*-----------------------------------------------------------------------*/ void GradientFactory::executeCode(Code code) { qreal v; switch (code) { case ColorAt: v = evalValue(); gradient.setColorAt(v, evalColor()); break; default: AbstractFactory::executeCode(code); break; } } void GradientFactory::skipCode(Code code) { switch (code) { case ColorAt: skipValue(); skipColor(); break; default: AbstractFactory::skipCode(code); break; } } /*-----------------------------------------------------------------------*/ QGradient GradientFactory::createGradient(GradientFactory::Description description, qreal var[]) { GradientFactory factory; factory.setDescription(description); for (int n = MinVar; n <= MaxVar; ++n) { factory.setVar(n, var[n]); } factory.create(); for (int n = MinVar; n <= MaxVar; ++n) { var[n] = factory.getVar(n); } return factory.getGradient(); } QGradient GradientFactory::createGradient(GradientFactory::Description description) { GradientFactory factory; factory.setDescription(description); factory.create(); return factory.getGradient(); } /* * skulpture_header.cpp * */ #include "skulpture_p.h" #include "sk_factory.h" #include #include /*-----------------------------------------------------------------------*/ void paintHeaderEmptyArea(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { if (option->state & QStyle::State_Enabled) { painter->fillRect(option->rect, option->palette.color(QPalette::Window).lighter(107)); } else { painter->fillRect(option->rect, option->palette.color(QPalette::Window).darker(104)); } if (option->state & QStyle::State_Horizontal) { paintThinFrame(painter, option->rect.adjusted(0, -2, 32000, -1), option->palette, -20, 60); // painter->fillRect(option->rect.adjusted(0, option->rect.height() - 1, 0, 0), QColor(255, 255, 255, 160)); } else { paintThinFrame(painter, option->rect.adjusted(-2, 0, -1, 32000), option->palette, -20, 60); // painter->fillRect(option->rect.adjusted(option->rect.width() - 1, 0, 0, 0), QColor(255, 255, 255, 160)); } } static bool isHeaderEnabled(const QStyleOptionHeader *option, const QWidget *widget) { bool enabled = true; if (!(option->state & QStyle::State_Enabled)) { enabled = false; if (widget && widget->inherits("Q3Header")) { enabled = widget->isEnabled(); } } return enabled; } void paintHeaderSection(QPainter *painter, const QStyleOptionHeader *option, const QWidget *widget, const QStyle *style) { Q_UNUSED(style); if (!(option->state & (QStyle::State_Raised | QStyle::State_Sunken))) { painter->fillRect(option->rect, option->palette.color(QPalette::Window).darker(104)); paintRecessedFrame(painter, option->rect.adjusted(-9, -9, 3, 3), option->palette, RF_Small); painter->fillRect(QRect(option->rect.right(), option->rect.bottom(), 1, 1), option->palette.color(QPalette::Window)); } else { if (isHeaderEnabled(option, widget)) { bool hover = false; #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) const QHeaderView *view = qobject_cast(widget); if (view && (view->isClickable() || view->isMovable())) { hover = option->state & QStyle::State_MouseOver; } #endif painter->fillRect(option->rect, option->palette.color(QPalette::Base).darker(hover ? 104 : (option->state & QStyle::State_On ? 120 : 106))); } else { painter->fillRect(option->rect, option->palette.color(QPalette::Window).darker(104)); } if (true || !(option->state & QStyle::State_On)) { if (option->orientation == Qt::Horizontal) { const QHeaderView *view = qobject_cast(widget); if (view && view->rect().right() == option->rect.right()) { paintThinFrame(painter, option->rect.adjusted(0, -2, 1, -1), option->palette, -20, 60); } else { paintThinFrame(painter, option->rect.adjusted(0, -2, 0, -1), option->palette, -20, 60); } } else { if (option->direction == Qt::LeftToRight) { paintThinFrame(painter, option->rect.adjusted(-2, 0, -1, 0), option->palette, -20, 60); } else { paintThinFrame(painter, option->rect.adjusted(1, 0, 2, 0), option->palette, -20, 60); } } } #if 0 if (option->orientation == Qt::Horizontal) { painter->fillRect(option->rect.adjusted(0, option->rect.height() - 1, 0, 0), QColor(255, 255, 255, 160)); } else { painter->fillRect(option->rect.adjusted(option->rect.width() - 1, 0, 0, 0), QColor(255, 255, 255, 160)); } #endif } } void paintHeaderLabel(QPainter *painter, const QStyleOptionHeader *option, const QWidget *widget, const QStyle *style) { QStyleOptionHeader opt = *option; if (isHeaderEnabled(option, widget)) { opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::Text)); } else { opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::WindowText)); } painter->save(); if (widget) { painter->setFont(widget->font()); } ((QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_HeaderLabel, &opt, painter, widget); painter->restore(); } static const ShapeFactory::Code headerSortIndicatorShapeDescription[] = { Pmove(-1, 1), Pline(1, 1), Pline(0, -1), Pend }; void paintHeaderSortIndicator(QPainter *painter, const QStyleOptionHeader *option, const QWidget */*widget*/, const QStyle */*style*/) { int h = option->fontMetrics.height() / 2 + 2; int w = option->fontMetrics.height() / 4 + 2; QPainterPath path; h /= 2; w /= 2; if (option->sortIndicator == QStyleOptionHeader::SortDown) { h = -h; } painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->translate(option->rect.center()); painter->translate(0.5, 1.5); painter->setPen(Qt::NoPen); QColor color = option->palette.color(option->state & QStyle::State_Enabled ? QPalette::Text : QPalette::WindowText); color.setAlphaF(0.6 * color.alphaF()); painter->setBrush(color); QTransform matrix(w, 0, 0, h, 0, 0); painter->drawPath(matrix.map(ShapeFactory::createShape(headerSortIndicatorShapeDescription))); painter->restore(); } /* * skulpture_icons.cpp * */ #include "skulpture_p.h" #include "sk_factory.h" #include #include #include #include #include #include /*-----------------------------------------------------------------------*/ QPixmap SkulptureStyle::standardPixmap(QStyle::StandardPixmap standardPixmap, const QStyleOption *option, const QWidget *widget) const { return ParentStyle::standardPixmap(standardPixmap, option, widget); } /*-----------------------------------------------------------------------*/ /** * decorationShape - get shape for window decoration button * * The coordinate system is -1 ... 1 for each dimension, with * (0, 0) being at the center, and positive coordinates pointing * down and to the right. * */ static const ShapeFactory::Code titleBarMenuButtonDescription[] = { Pmove(0, 0.6), Pline(0.6, 0), Pline(0, -0.6), Pline(-0.6, 0), Pend }; static const ShapeFactory::Code titleBarCloseButtonDescription[] = { #define kx3 0.3 Pmove(-1, -1), Pline(0, -kx3), Pline(1, -1), Pline(kx3, 0), Pline(1, 1), Pline(0, kx3), Pline(-1, 1), Pline(-kx3, 0), Pend }; static const ShapeFactory::Code titleBarShadeButtonDescription[] = { Pmove(-1, -0.4), Pline(0, -0.6), Pline(1, -0.4), Pline(0, -1), Pend }; static const ShapeFactory::Code titleBarUnshadeButtonDescription[] = { Pmove(-1, -1), Pline(0, -0.8), Pline(1, -1), Pline(0, -0.4), Pend }; static const ShapeFactory::Code titleBarMinButtonDescription[] = { Pmove(-1, 0.4), Pline(0, 0.6), Pline(1, 0.4), Pline(0, 1), Pend }; static const ShapeFactory::Code titleBarMaxButtonDescription[] = { #define kx1 0.8 #define kx2 0.55 Pmove(0, -1), Pline(1, 0), Pline(0, 1), Pline(-1, 0), Pclose, Pmove(0, -kx2), Pline(-kx1, 0), Pline(0, kx2), Pline(kx1, 0), Pend, }; static const ShapeFactory::Code titleBarNormalButtonDescription[] = { Pmove(0, -1), Pline(1, 0), Pline(0, 1), Pline(-1, 0), Pclose, Pmove(0, -kx1), Pline(-kx2, 0), Pline(0, kx1), Pline(kx2, 0), Pend, }; static const ShapeFactory::Code titleBarHelpButtonDescription[] = { Pmove(0.0305, 0.513), Pline(-0.0539, 0.513), Pline(0.0117, 0.227), Pline(0.22, -0.0859), Pline(0.38, -0.323), Pline(0.417, -0.491), Pline(0.279, -0.767), Pline(-0.0609, -0.87), Pline(-0.342, -0.814), Pline(-0.445, -0.692), Pline(-0.383, -0.568), Pline(-0.321, -0.456), Pline(-0.368, -0.373), Pline(-0.483, -0.339), Pline(-0.64, -0.396), Pline(-0.71, -0.555), Pline(-0.512, -0.827), Pline(0.0281, -0.947), Pline(0.649, -0.783), Pline(0.797, -0.516), Pline(0.73, -0.31), Pline(0.476, -0.0625), Pline(0.111, 0.255), Pclose, Pmove(0.00234, 0.681), Pline(0.165, 0.726), Pline(0.232, 0.834), Pline(0.164, 0.943), Pline(0.00234, 0.988), Pline(-0.158, 0.943), Pline(-0.225, 0.834), Pline(-0.158, 0.726), Pend }; static const ShapeFactory::Code titleBarStickyButtonDescription[] = { Pmove(0, -1), Pline(0.2, -0.2), Pline(1, 0), Pline(0.2, 0.2), Pline(0, 1), Pline(-0.2, 0.2), Pline(-1, 0), Pline(-0.2, -0.2), Pend }; static const ShapeFactory::Code titleBarUnstickyButtonDescription[] = { Pmove(0, -0.2), Pline(1, 0), Pline(0, 0.2), Pline(-1, 0), Pend }; static const ShapeFactory::Code titleBarAboveButtonDescription[] = { Pmove(0, -0.2), Pline(1, 0), Pline(0, 0.2), Pline(-1, 0), Pclose, Pmove(-1, -0.4), Pline(0, -0.6), Pline(1, -0.4), Pline(0, -1), Pend }; static const ShapeFactory::Code titleBarBelowButtonDescription[] = { Pmove(0, -0.2), Pline(1, 0), Pline(0, 0.2), Pline(-1, 0), Pclose, Pmove(-1, 0.4), Pline(0, 0.6), Pline(1, 0.4), Pline(0, 1), Pend }; static const ShapeFactory::Code titleBarUnaboveButtonDescription[] = { Pmove(0, -0.2), Pline(1, 0), Pline(0, 0.2), Pline(-1, 0), Pclose, Pmove(-1, -1), Pline(0, -0.8), Pline(1, -1), Pline(0, -0.4), Pend }; static const ShapeFactory::Code titleBarUnbelowButtonDescription[] = { Pmove(0, -0.2), Pline(1, 0), Pline(0, 0.2), Pline(-1, 0), Pclose, Pmove(-1, 1), Pline(0, 0.8), Pline(1, 1), Pline(0, 0.4), Pend }; static const ShapeFactory::Code toolBarHorizontalExtensionButtonDescription[] = { Pmove(-1, -1), Pline(0, 0), Pline(-1, 1), Pline(-0.5, 0), Pclose, Pmove(0, -1), Pline(1, 0), Pline(0, 1), Pline(0.5, 0), Pend }; static const ShapeFactory::Code toolBarVerticalExtensionButtonDescription[] = { Pmove(-1, -1), Pline(0, -0.5), Pline(1, -1), Pline(0, 0), Pclose, Pmove(-1, 0), Pline(0, 0.5), Pline(1, 0), Pline(0, 1), Pend }; static const ShapeFactory::Code * const titleBarButtonDescriptions[] = { titleBarMenuButtonDescription, titleBarMinButtonDescription, titleBarMaxButtonDescription, titleBarCloseButtonDescription, titleBarNormalButtonDescription, titleBarShadeButtonDescription, titleBarUnshadeButtonDescription, titleBarHelpButtonDescription }; static const ShapeFactory::Code * const titleBarCustomDescriptions[] = { 0, // CustomBase intentionally left blank titleBarStickyButtonDescription, titleBarUnstickyButtonDescription, 0, // this used to be titleBarIconDescription titleBarAboveButtonDescription, titleBarBelowButtonDescription, titleBarUnaboveButtonDescription, titleBarUnbelowButtonDescription }; #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) QIcon SkulptureStyle::standardIconImplementation(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { const ShapeFactory::Code *code = 0; int numStates = 1; int size = 10; if (standardIcon > QStyle::SP_CustomBase) { if (standardIcon - QStyle::SP_CustomBase < sizeof(titleBarCustomDescriptions) / sizeof(titleBarCustomDescriptions[0])) { code = titleBarCustomDescriptions[standardIcon - QStyle::SP_CustomBase]; numStates = 3; } } else if (/*standardIcon >= QStyle::SP_TitleBarMenuButton && */standardIcon <= QStyle::SP_TitleBarContextHelpButton) { code = titleBarButtonDescriptions[standardIcon - QStyle::SP_TitleBarMenuButton]; numStates = 3; } else { switch (standardIcon) { case QStyle::SP_ToolBarHorizontalExtensionButton: code = toolBarHorizontalExtensionButtonDescription; numStates = 2; size = 8; break; case QStyle::SP_ToolBarVerticalExtensionButton: code = toolBarVerticalExtensionButtonDescription; numStates = 2; size = 8; break; default: break; } } if (code) { QIcon icon; bool dock = qobject_cast(widget) != 0; if (dock) { size = 14; numStates = 2; } qreal s = size / 2.0; if (numStates == 3) { if (widget && !qstrcmp(widget->metaObject()->className(), "KLineEditButton")) { s = qMin(22, widget->fontMetrics().height()) * 0.25; size += 2; } else if (widget && !qstrcmp(widget->metaObject()->className(), "CloseButton")) { s = qMin(20, widget->fontMetrics().height()) * 0.25; } else { size += 4; if (option) { s = qMin(22, option->fontMetrics.height()) * 0.3; } } } for (int state = 0; state < numStates; ++state) { QImage image(size, size, QImage::Format_ARGB32); image.fill(0); QPainter painter(&image); painter.setRenderHint(QPainter::Antialiasing, true); painter.translate(size / 2.0, size / 2.0); if (dock) { painter.scale(s - 2, s - 2); } else { painter.scale(s, s); } painter.setPen(Qt::NoPen); QPalette palette; if (option) { palette = option->palette; } QPalette::ColorRole role = QPalette::Text; QColor shapeColor; if (numStates == 2) { if (state == 0) { role = QPalette::WindowText; } else { role = QPalette::ButtonText; } shapeColor = palette.color(role); } else if (numStates == 3) { if (state == 1) { QColor glowColor = palette.color(role); if (standardIcon == QStyle::SP_TitleBarCloseButton) { glowColor = QColor(255, 0, 0, 100); } else { glowColor.setAlpha(50); } painter.fillRect(QRectF(-1.5, -1.5, 3, 3), glowColor); QPainterPath path = ShapeFactory::createShape(code); shapeColor = palette.color(role); // painter.setPen(QPen(shapeColor, 0.3)); painter.drawRect(QRectF(-1.5, -1.5, 3, 3)); painter.setPen(Qt::NoPen); painter.setBrush(shapeColor); painter.drawPath(path); } else { shapeColor = palette.color(role); } } QColor shadowColor = option ? option->palette.color(QPalette::Shadow) : Qt::black; shadowColor.setAlpha(25); painter.translate(1 / s, 1 / s); painter.setBrush(shadowColor); painter.drawPath(ShapeFactory::createShape(code)); painter.translate(-1 / s, -1 / s); painter.setBrush(shapeColor); painter.drawPath(ShapeFactory::createShape(code)); painter.end(); QIcon::Mode iconMode; switch (state) { case 1: iconMode = QIcon::Active; break; case 2: #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) iconMode = QIcon::Selected; #else iconMode = QIcon::Normal; #endif break; default: iconMode = QIcon::Normal; break; } icon.addPixmap(QPixmap::fromImage(image), iconMode); } return icon; } return ParentStyle::standardIconImplementation(standardIcon, option, widget); } #endif QPixmap SkulptureStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const { return ParentStyle::generatedIconPixmap(iconMode, pixmap, option); } QRect SkulptureStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap & pixmap) const { return ParentStyle::itemPixmapRect(rectangle, alignment, pixmap); } void SkulptureStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const { ParentStyle::drawItemPixmap(painter, rectangle, alignment, pixmap); } /* * skulpture_layout.cpp * */ #include "skulpture_p.h" #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) #include #include #include #endif /*-----------------------------------------------------------------------*/ int SkulptureStyle::Private::verticalTextShift(const QFontMetrics &fontMetrics) { if (fontMetrics.xHeight() == qApp->fontMetrics().xHeight() && fontMetrics.ascent() == qApp->fontMetrics().ascent() && fontMetrics.descent() == qApp->fontMetrics().descent() && fontMetrics.leading() == qApp->fontMetrics().leading()) { return textShift; } return 0; } static QFontMetrics styledFontMetrics(const QStyleOption *option, const QWidget *widget) { if (option) { return option->fontMetrics; } else if (widget) { return widget->fontMetrics(); } return qApp->fontMetrics(); } int SkulptureStyle::Private::textLineHeight(const QStyleOption *option, const QWidget *widget) { QFontMetrics fm = styledFontMetrics(option, widget); return fm.height() + (verticalTextShift(fm) & 1); } static int fontHeight(const QStyleOption *option, const QWidget *widget) { return styledFontMetrics(option, widget).height(); } /*-----------------------------------------------------------------------*/ int SkulptureStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { switch (metric) { /* entries are stricly sorted in Qt order for future lookup table */ case PM_ButtonMargin: return 2 * d->pushButtonSize; case PM_ButtonDefaultIndicator: return 0; case PM_MenuButtonIndicator: return fontHeight(option, widget); case PM_ButtonShiftHorizontal: { Qt::LayoutDirection direction; if (option) { direction = option->direction; } else if (widget) { direction = widget->layoutDirection(); } else { direction = QApplication::layoutDirection(); } return direction == Qt::LeftToRight ? 1 : -1; } case PM_ButtonShiftVertical: return 1; case PM_DefaultFrameWidth: return 2; // 3 for command buttons case PM_SpinBoxFrameWidth: return 2; case PM_ComboBoxFrameWidth: return 2; // 3 for non-editable combobox (in button mode) case PM_MaximumDragDistance: return -1; case PM_ScrollBarExtent: { if (d->scrollBarSize > 0) { return d->scrollBarSize; } // do not depend on widget font size int extent = ((fontHeight(0, 0) >> 1) & ~1) + 9; #if 0 if (option && (option->state & QStyle::State_Horizontal)) { return (qMax(extent, 0) & ~1) + 1; } else { return (qMax(extent, 0) & ~1) + 1; } #else return extent; #endif } case PM_ScrollBarSliderMin: { if (d->scrollBarLength > 0) { return d->scrollBarLength; } return fontHeight(0, 0) + 1; } case PM_SliderThickness: case PM_SliderControlThickness: { if (d->sliderSize > 0) { return d->sliderSize + 4; } int thickness = (fontHeight(option, widget) & ~1) + 5; if (option && !(option->state & QStyle::State_Horizontal)) { return (qMax(thickness, 0) & ~1) + 1; } else { return (qMax(thickness, 0) & ~1) + 1; } } case PM_SliderLength: { if (d->sliderLength > 0) { return d->sliderLength; } int length = (fontHeight(option, widget)) + 6; if (option && !(option->state & QStyle::State_Horizontal)) { return qMax(length, 0); } else { return qMax(length, 0); } } case PM_SliderTickmarkOffset: { if (const QStyleOptionSlider *sliderOption = qstyleoption_cast(option)) { if (sliderOption->tickPosition == QSlider::TicksAbove) { return 5; } else if (sliderOption->tickPosition == QSlider::TicksBothSides) { return 5; } else if (sliderOption->tickPosition == QSlider::TicksBelow) { return 0; } } return 0; } case PM_SliderSpaceAvailable: { return QCommonStyle::pixelMetric(metric, option, widget); } case PM_DockWidgetSeparatorExtent: return ((qMax(fontHeight(option, widget), 16) >> 1) & ~1) - 1; case PM_DockWidgetHandleExtent: return 8; case PM_DockWidgetFrameWidth: return 2; case PM_TabBarTabOverlap: return 2; case PM_TabBarTabHSpace: return 2 * d->tabBarSize + (fontHeight(option, widget) & ~1); case PM_TabBarTabVSpace: return 0; case PM_TabBarBaseHeight: return 2; case PM_TabBarBaseOverlap: return 2; case PM_ProgressBarChunkWidth: return fontHeight(option, widget) >> 1; case PM_SplitterWidth: return ((qMax(fontHeight(option, widget), 16) >> 1) & ~1) - 1; case PM_TitleBarHeight: return d->textLineHeight(option, widget) + 4; case PM_MenuScrollerHeight: return (fontHeight(option, widget) >> 1) + 2; #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) case PM_MenuHMargin: return 1; case PM_MenuVMargin: return 1; case PM_MenuPanelWidth: return 1; #else case PM_MenuHMargin: return runtimeQtVersion() < QT_VERSION_CHECK(4, 4, 0) ? 0 : 1; // ### anything other than 0 messes Qt's menu positioning code ... case PM_MenuVMargin: return runtimeQtVersion() < QT_VERSION_CHECK(4, 4, 0) ? 0 : 1; case PM_MenuPanelWidth: return runtimeQtVersion() < QT_VERSION_CHECK(4, 4, 0) ? 2 : 1; #endif case PM_MenuTearoffHeight: return (fontHeight(option, widget) >> 1) + 2; case PM_MenuDesktopFrameWidth: return 0; case PM_MenuBarPanelWidth: return 0; case PM_MenuBarItemSpacing: return 0; case PM_MenuBarVMargin: return 0; case PM_MenuBarHMargin: return 0; case PM_IndicatorWidth: case PM_IndicatorHeight: case PM_ExclusiveIndicatorWidth: case PM_ExclusiveIndicatorHeight: #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) case PM_CheckListButtonSize: case PM_CheckListControllerSize: #endif { // do not use strut width, because label is usually wide enough return qMax(d->textLineHeight(option, widget), 0); } case PM_DialogButtonsSeparator: return 6; case PM_DialogButtonsButtonWidth: return 64; case PM_DialogButtonsButtonHeight: return 16; #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) case PM_MdiSubWindowFrameWidth: return 3; case PM_MdiSubWindowMinimizedWidth: return fontHeight(option, widget) * 12; #else case PM_MDIFrameWidth: return 3; case PM_MDIMinimizedWidth: return fontHeight(option, widget) * 12; #endif case PM_HeaderMargin: return 3; case PM_HeaderMarkSize: return 5; case PM_HeaderGripMargin: return 4; case PM_TabBarTabShiftHorizontal: return 0; case PM_TabBarTabShiftVertical: return 0; case PM_TabBarScrollButtonWidth: return (fontHeight(option, widget) & ~1) + 1; case PM_ToolBarFrameWidth: return 1; case PM_ToolBarHandleExtent: return 9; case PM_ToolBarItemSpacing: return 2; case PM_ToolBarItemMargin: return 0; case PM_ToolBarSeparatorExtent: return 4; case PM_ToolBarExtensionExtent: return 12; case PM_SpinBoxSliderHeight: return 2; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) case PM_DefaultTopLevelMargin: { if (d->dialogMargins >= 0) { return d->dialogMargins; } return (fontHeight(option, widget) >> 1); } case PM_DefaultChildMargin: { if (d->widgetMargins >= 0) { return d->widgetMargins; } return (fontHeight(option, widget) >> 1); } case PM_DefaultLayoutSpacing: { if (d->verticalSpacing >= 0) { return d->verticalSpacing; } return ((fontHeight(option, widget) * 3) >> 3); } #endif case PM_ToolBarIconSize: if (runtimeQtVersion() >= QT_VERSION_CHECK(4, 6, 0)) { break; } return pixelMetric(PM_SmallIconSize, option, widget); case PM_ListViewIconSize: return pixelMetric(PM_SmallIconSize, option, widget); case PM_IconViewIconSize: return pixelMetric(PM_LargeIconSize, option, widget); case PM_SmallIconSize: { int iconSize = d->textLineHeight(option, widget); return iconSize; } case PM_LargeIconSize: { const bool hasSvgIcons = false; int iconSize = 2 * fontHeight(option, widget); if (!hasSvgIcons) { if (iconSize < 28) { return 22; } else if (iconSize < 40) { return 32; } else if (iconSize < 56) { return 48; } else if (iconSize < 96) { return 64; } } return iconSize; } case PM_FocusFrameVMargin: return 2; case PM_FocusFrameHMargin: return 2; case PM_ToolTipLabelFrameWidth: return 1; case PM_CheckBoxLabelSpacing: { if (d->labelSpacing >= 0) { return d->labelSpacing; } return (fontHeight(option, widget) >> 1) - 2; } case PM_TabBarIconSize: return pixelMetric(PM_SmallIconSize, option, widget); case PM_SizeGripSize: return 13; // ### make this variable case PM_DockWidgetTitleMargin: return 2; #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) case PM_MessageBoxIconSize: return pixelMetric(PM_LargeIconSize, option, widget); case PM_ButtonIconSize: return pixelMetric(PM_SmallIconSize, option, widget); #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) case PM_DockWidgetTitleBarButtonMargin: return 0; case PM_RadioButtonLabelSpacing: { if (d->labelSpacing >= 0) { return d->labelSpacing; } return (fontHeight(option, widget) >> 1) - 2; } #if 0//Qt6 case PM_LayoutLeftMargin: case PM_LayoutTopMargin: case PM_LayoutRightMargin: case PM_LayoutBottomMargin: { PixelMetric metric = QStyle::PM_DefaultChildMargin; if ((option && (option->state & QStyle::State_Window)) || (widget && widget->isWindow())) { metric = QStyle::PM_DefaultTopLevelMargin; } return pixelMetric(metric, option, widget); } #endif case PM_LayoutHorizontalSpacing: case PM_LayoutVerticalSpacing: { return -1; } #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) case PM_TabBar_ScrollButtonOverlap: return 0; case PM_TextCursorWidth: { if (d->textCursorWidth > 0) { return qMax(1, int(d->textCursorWidth + 0.5)); } return qMax(1, (fontHeight(option, widget) + 8) / 12); } #else // used for TextCursorWidth in Qt < 4.4 case PM_CustomBase + 1: { if (d->textCursorWidth > 0) { return qMax(1, int(d->textCursorWidth + 0.5)); } return qMax(1, (fontHeight(option, widget) + 8) / 12); } #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) case PM_TabCloseIndicatorWidth: case PM_TabCloseIndicatorHeight: { return (fontHeight(option, widget) & ~1); } case PM_ScrollView_ScrollBarSpacing: return 0; case PM_SubMenuOverlap: return -2; #endif case PM_CustomBase: // avoid warning break; default: break; } return ParentStyle::pixelMetric(metric, option, widget); } /*-----------------------------------------------------------------------*/ #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) int SkulptureStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const { Q_UNUSED(control2); if (orientation == Qt::Horizontal) { if (control1 == QSizePolicy::Label) { if (d->labelSpacing >= 0) { return d->labelSpacing + 2; } return fontHeight(option, widget) >> 1; } if (d->horizontalSpacing >= 0) { return d->horizontalSpacing; } return fontHeight(option, widget) >> 1; } if (control1 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton) && control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)) { if (d->verticalSpacing >= 0) { return qMax(0, d->verticalSpacing - 2); } return d->verticalSpacing; } if (d->verticalSpacing >= 0) { return d->verticalSpacing; } return d->verticalSpacing; } #endif /*-----------------------------------------------------------------------*/ extern QSize sizeFromContentsToolButton(const QStyleOptionToolButton *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int toolButtonSize); extern QSize sizeFromContentsMenuItem(const QStyleOptionMenuItem *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int menuItemSize, int textLineHeight); /*-----------------------------------------------------------------------*/ static inline QSize sizeFromContentsPushButton(const QStyleOptionButton *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int pushButtonSize, int textLineHeight) { Q_UNUSED(style); // width int w = contentsSize.width() + (fontHeight(option, widget) & ~1); if (!option->text.isEmpty()) { w += 6 + 2 * pushButtonSize; const int sizeBase = qMin(64, 4 * fontHeight(option, widget)); const int sizeIncrement = qMin(32, qMin(sizeBase, qMax(1, 2 * pushButtonSize))); if (w < sizeBase) { w = sizeBase; } else { w = ((w - sizeBase + sizeIncrement - 1) / sizeIncrement) * sizeIncrement + sizeBase; } } // height int h = qMax(contentsSize.height(), textLineHeight); h += 2 * pushButtonSize + 4; return QSize(w, h); } static inline QSize sizeFromContentsComboBox(const QStyleOptionComboBox *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int widgetSize, int textLineHeight) { // if (contentsSize.height() > 16) { // fh = contentsSize.height() - 2; // } return ((const QCommonStyle *) style)->QCommonStyle::sizeFromContents(QStyle::CT_ComboBox, option, QSize(contentsSize.width(), textLineHeight + 2 * widgetSize), widget); } static inline QSize sizeFromContentsLineEdit(const QStyleOptionFrame *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int widgetSize, int textLineHeight) { Q_UNUSED(widget); Q_UNUSED(style); int fw = option->lineWidth; int fh = textLineHeight; // if (contentsSize.height() > 14) { // fh = contentsSize.height() - 4; // } return QSize(contentsSize.width() + 6 + 2 * fw, fh + 2 * (widgetSize + fw)); } static inline QSize sizeFromContentsSpinBox(const QStyleOptionSpinBox *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style) { Q_UNUSED(option); Q_UNUSED(widget); Q_UNUSED(style); return contentsSize + QSize(4, 0); } static inline QSize sizeFromContentsGroupBox(const QStyleOptionGroupBox *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style) { Q_UNUSED(widget); Q_UNUSED(style); return contentsSize + QSize(fontHeight(option, widget) & ~1, 0); } static inline QSize sizeFromContentsTabBarTab(const QStyleOptionTab *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int tabBarSize, int textShift) { Q_UNUSED(widget); Q_UNUSED(style); if (int(option->shape) & 2) { return (contentsSize + QSize(4 + 2 * tabBarSize, 0)).expandedTo(QSize(0, 0)); } if (!option->icon.isNull()) { textShift = 0; } return (contentsSize + QSize(0, 2 + 2 * tabBarSize + (textShift & 1))).expandedTo(QSize(0, 0)); } static inline QSize sizeFromContentsProgressBar(const QStyleOptionProgressBar *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int widgetSize, int textShift) { Q_UNUSED(widget); Q_UNUSED(style); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) if (option->version >= 2 && ((const QStyleOptionProgressBarV2 *) option)->orientation == Qt::Vertical) { #else if (option->version >= 2 && option->orientation == Qt::Vertical) { #endif return contentsSize + QSize(2 * widgetSize, 6); } #else Q_UNUSED(option); #endif return contentsSize + QSize(6, (textShift & 1) + 2 * widgetSize - 6); } /*-----------------------------------------------------------------------*/ #define CT_CASE(ct, so) \ case CT_## ct: \ if (option && option->type == QStyleOption::SO_## so) { \ return sizeFromContents ## ct((const QStyleOption ## so *) option, contentsSize, widget, this); \ } \ break QSize SkulptureStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const { switch (type) { case CT_PushButton: if (option && option->type == QStyleOption::SO_Button) { return sizeFromContentsPushButton((const QStyleOptionButton *) option, contentsSize, widget, this, d->pushButtonSize, d->textLineHeight(option, widget)); } break; case CT_CheckBox: case CT_RadioButton: return ParentStyle::sizeFromContents(type, option, contentsSize, widget) + QSize(0, 2 * d->widgetSize - 4); break; case CT_ToolButton: if (option && option->type == QStyleOption::SO_ToolButton) { return sizeFromContentsToolButton((const QStyleOptionToolButton *) option, contentsSize, widget, this, d->toolButtonSize); } break; case CT_ComboBox: if (option && option->type == QStyleOption::SO_ComboBox) { return sizeFromContentsComboBox((const QStyleOptionComboBox *) option, contentsSize, widget, this, d->widgetSize, d->textLineHeight(option, widget)); } break; case CT_Splitter: #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) case CT_Q3DockWindow: #endif return contentsSize; case CT_ProgressBar: if (option && option->type == QStyleOption::SO_ProgressBar) { return sizeFromContentsProgressBar((const QStyleOptionProgressBar *) option, contentsSize, widget, this, d->widgetSize, d->verticalTextShift(styledFontMetrics(option, widget))); } break; case CT_MenuItem: if (option && option->type == QStyleOption::SO_MenuItem) { return sizeFromContentsMenuItem((const QStyleOptionMenuItem *) option, contentsSize, widget, this, 2 * d->menuItemSize, d->textLineHeight(option, widget)); } break; case CT_MenuBarItem: { int h = 2 * (d->menuBarSize >= 0 ? d->menuBarSize : 3) + d->textLineHeight(option, widget); return QSize(contentsSize.width() + 2 + (((fontHeight(option, widget) * 7) >> 3) & ~1), h).expandedTo(QSize(0, 0)); } case CT_MenuBar: return contentsSize; case CT_Menu: return contentsSize; case CT_TabBarTab: if (option && option->type == QStyleOption::SO_Tab) { return sizeFromContentsTabBarTab((const QStyleOptionTab *) option, contentsSize, widget, this, d->tabBarSize, d->verticalTextShift(styledFontMetrics(option, widget))); } break; case CT_Slider: case CT_ScrollBar: #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) case CT_Q3Header: #endif return contentsSize; case CT_LineEdit: if (option && option->type == QStyleOption::SO_Frame) { return sizeFromContentsLineEdit((const QStyleOptionFrame *) option, contentsSize, widget, this, d->widgetSize, d->textLineHeight(option, widget)); } break; CT_CASE(SpinBox, SpinBox); case CT_SizeGrip: return contentsSize; case CT_TabWidget: return contentsSize + QSize(4, 4); case CT_DialogButtons: return contentsSize; case CT_HeaderSection: break; //#if (QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)) CT_CASE(GroupBox, GroupBox); //#endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) case CT_MdiControls: break; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) case CT_ItemViewItem: break; #endif case CT_CustomBase: // avoid warning break; } return ParentStyle::sizeFromContents(type, option, contentsSize, widget); } /*-----------------------------------------------------------------------*/ extern QRect subElementRectDockWidget(QStyle::SubElement element, const QStyleOptionDockWidget *option, const QWidget *widget, const QStyle *style); extern QRect subElementRectComboBoxFocusRect(const QStyleOptionComboBox *option, const QWidget *widget, const QStyle *style); /*-----------------------------------------------------------------------*/ #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) static inline QRect subElementRectFrameContents(const QStyleOption *option, const QWidget *widget, const QStyle *style) { Q_UNUSED(style); if (widget && widget->inherits("KHTMLView")) { QWidget *window; // case 1: the parent widget is a QFrame, and already has a sunken frame // do not show any frame (KMail mail view, Kopete chat view) if (QFrame *frame = qobject_cast(widget->parentWidget())) { if (frame->frameShape() == QFrame::StyledPanel) { // ### fix Kopete frame // frame->setFrameShadow(QFrame::Sunken); return option->rect; } } else if ((window = widget->window()) && window->inherits("KonqMainWindow")) { // case 2: the html view covers the full width of window: // do not show side frames (Konqueror) return option->rect.adjusted(0, 2, 0, -2); } else { // case 3: detect KMail 4.2 while ((widget = widget->parentWidget())) { if (widget->inherits("KMReaderWin")) { return option->rect; } } } } return option->rect.adjusted(2, 2, -2, -2); } static inline QRect subElementRectLineEditContents(const QStyleOptionFrame *option, const QWidget *widget, const QStyle *style, int textShift) { Q_UNUSED(widget); Q_UNUSED(style); int fw = option->lineWidth; int adjust = 0; /// TODO replace with runtime version check #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 1)) if (textShift & 1) { adjust = -1; textShift &= ~1; } #else // ### can the 4.6.1 code be used on < 4.6.1 ??? if (textShift & 1 && !(option->rect.height() & 1)) { textShift += 1; } #endif return option->rect.adjusted(fw + 2, fw + ((-textShift) >> 1), -fw - 2, -fw + ((-textShift) >> 1) + adjust); } #endif /*-----------------------------------------------------------------------*/ QRect SkulptureStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const { switch (element) { case SE_PushButtonContents: case SE_PushButtonFocusRect: case SE_CheckBoxIndicator: case SE_CheckBoxContents: case SE_CheckBoxFocusRect: case SE_CheckBoxClickRect: case SE_RadioButtonIndicator: case SE_RadioButtonContents: case SE_RadioButtonFocusRect: case SE_RadioButtonClickRect: break; case SE_ComboBoxFocusRect: if (option->type == QStyleOption::SO_ComboBox) { return subElementRectComboBoxFocusRect((const QStyleOptionComboBox *) option, widget, this); } break; case SE_SliderFocusRect: #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) case SE_Q3DockWindowHandleRect: #endif break; case SE_ProgressBarGroove: case SE_ProgressBarContents: case SE_ProgressBarLabel: return option->rect; #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) case SE_DialogButtonAccept: case SE_DialogButtonReject: case SE_DialogButtonApply: case SE_DialogButtonHelp: case SE_DialogButtonAll: case SE_DialogButtonAbort: case SE_DialogButtonIgnore: case SE_DialogButtonRetry: case SE_DialogButtonCustom: break; #endif case SE_ToolBoxTabContents: return option->rect.adjusted(11, 0, -6, 0); case SE_HeaderLabel: case SE_HeaderArrow: break; case SE_TabWidgetTabBar: case SE_TabWidgetTabPane: case SE_TabWidgetTabContents: break; case SE_TabWidgetLeftCorner: case SE_TabWidgetRightCorner: if (option->type == QStyleOption::SO_TabWidgetFrame) { if (((const QStyleOptionTabWidgetFrame *) option)->lineWidth == 0) { break; } if ((((const QStyleOptionTabWidgetFrame *) option)->shape & 3) == 1) { return QCommonStyle::subElementRect(element, option, widget).adjusted(1, -1, -1, -1); } } return QCommonStyle::subElementRect(element, option, widget).adjusted(1, 1, -1, 1); #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) case SE_ItemViewItemCheckIndicator: #else case SE_ViewItemCheckIndicator: #endif break; case SE_TabBarTearIndicator: case SE_TreeViewDisclosureItem: break; #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) case SE_LineEditContents: if (option->type == QStyleOption::SO_Frame) { return subElementRectLineEditContents((const QStyleOptionFrame *) option, widget, this, d->textShift); } break; case SE_FrameContents: return subElementRectFrameContents(option, widget, this); #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) case SE_DockWidgetCloseButton: case SE_DockWidgetFloatButton: case SE_DockWidgetTitleBarText: case SE_DockWidgetIcon: if (option->type == QStyleOption::SO_DockWidget) { return subElementRectDockWidget(element, (const QStyleOptionDockWidget *) option, widget, this); } break; case SE_CheckBoxLayoutItem: case SE_ComboBoxLayoutItem: case SE_DateTimeEditLayoutItem: break; case SE_LabelLayoutItem: case SE_ProgressBarLayoutItem: case SE_PushButtonLayoutItem: case SE_RadioButtonLayoutItem: case SE_SliderLayoutItem: case SE_SpinBoxLayoutItem: case SE_ToolButtonLayoutItem: break; case SE_FrameLayoutItem: case SE_GroupBoxLayoutItem: case SE_TabWidgetLayoutItem: break; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) case SE_ItemViewItemDecoration: case SE_ItemViewItemText: case SE_ItemViewItemFocusRect: break; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) case SE_TabBarTabLeftButton: case SE_TabBarTabRightButton: case SE_TabBarTabText: break; case SE_ShapedFrameContents: break; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)) case SE_ToolBarHandle: break; #endif case SE_CustomBase: // avoid warning default: break; } return ParentStyle::subElementRect(element, option, widget); } /*-----------------------------------------------------------------------*/ #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) void SkulptureStyle::Private::polishFormLayout(QFormLayout *layout) { if (layout->labelAlignment() & Qt::AlignVCenter) { return; } int addedHeight = -1; for (int row = 0; row < layout->rowCount(); ++row) { QLayoutItem *labelItem = layout->itemAt(row, QFormLayout::LabelRole); if (!labelItem) { continue; } QLayoutItem *fieldItem = layout->itemAt(row, QFormLayout::FieldRole); if (!fieldItem) { continue; } QWidget *label = labelItem->widget(); if (!label) { continue; } int labelHeight; if (addedHeight < 0) { #if 0 // fixed value in Qt static const int verticalMargin = 1; QStyleOptionFrame option; option.initFrom(label); option.lineWidth = label->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, label); option.midLineWidth = 0; option.rect = QRect(0, 0, 10, fontHeight(option, label) + 2 * verticalMargin); // label should be aligned centered to LineEdit, so use its size addedHeight = label->style()->sizeFromContents(QStyle::CT_LineEdit, &option, option.rect.size(), label).height() - fontHeight(option, height); #else addedHeight = 4 + 2 * widgetSize; #endif } if (qobject_cast(label)) { labelHeight = label->sizeHint().height() + addedHeight; } else if (qobject_cast(label)) { labelHeight = label->sizeHint().height(); } else { continue; } int fieldHeight = fieldItem->sizeHint().height(); if (runtimeQtVersion() < QT_VERSION_CHECK(4, 6, 0)) { // work around KIntNumInput::sizeHint() bug if (fieldItem->widget() && fieldItem->widget()->inherits("KIntNumInput")) { fieldHeight -= 2; fieldItem->widget()->setMaximumHeight(fieldHeight); } } /* for large fields, we don't center */ if (fieldHeight <= 2 * fontHeight(0, label) + addedHeight) { if (fieldHeight > labelHeight) { labelHeight = fieldHeight; } } else { if (verticalTextShift(label->fontMetrics()) & 1) { labelHeight += 1; } } if (qobject_cast(label)) { label->setMinimumHeight(labelHeight); } else { #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 2)) if (runtimeQtVersion() >= QT_VERSION_CHECK(4, 6, 2)) { label->setMinimumHeight((labelHeight * 4 + 6) / 7); } else { // QFormLayout determines label size as height * 5 / 4, so revert that label->setMinimumHeight((labelHeight * 4 + 4) / 5); } #else label->setMinimumHeight((labelHeight * 4 + 6) / 7); #endif } } } #endif void SkulptureStyle::Private::polishLayout(QLayout *layout) { if (forceSpacingAndMargins) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) if (QFormLayout *formLayout = qobject_cast(layout)) { if (formLayout->spacing() >= 2) { formLayout->setSpacing(-1); } } else #endif if (QGridLayout *gridLayout = qobject_cast(layout)) { if (gridLayout->spacing() >= 2) { gridLayout->setSpacing(-1); } } else if (QBoxLayout *boxLayout = qobject_cast(layout)) { if (boxLayout->spacing() >= 2) { boxLayout->setSpacing(-1); } } else { if (layout->spacing() >= 2) { layout->setSpacing(-1); } } #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (layout->margin() >= 4) { layout->setMargin(-1); } #endif } #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) if (QFormLayout *formLayout = qobject_cast(layout)) { polishFormLayout(formLayout); } #endif // recurse into layouts for (int i = 0; i < layout->count(); ++i) { QLayoutItem *item = layout->itemAt(i); if (QLayout *layout = item->layout()) { polishLayout(layout); } } } /* * skulpture_mdi.cpp * */ #include "skulpture_p.h" #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) #include #endif #include #include /*-----------------------------------------------------------------------*/ QRect subControlRectTitleBar(const QStyleOptionTitleBar *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { QRect r = ((const QCommonStyle *) style)->QCommonStyle::subControlRect(QStyle::CC_TitleBar, option, subControl, widget); if (subControl != QStyle::SC_TitleBarSysMenu) { return r.adjusted(option->direction == Qt::LeftToRight ? -2 : 2, -2, option->direction == Qt::LeftToRight ? -3 : 3, -3); } else { return r.adjusted(0, -1, 0, -1); } } /*-----------------------------------------------------------------------*/ void paintFrameWindow(QPainter *painter, const QStyleOptionFrame *option, const QWidget */*widget*/, const QStyle */*style*/) { // painter->fillRect(option->rect, option->palette.color(QPalette::Window)); #if 0 paintThinFrame(painter, option->rect.adjusted(0, 0, 0, 0), option->palette, -60, 160); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -20, 60); #else paintThinFrame(painter, option->rect.adjusted(0, 0, 0, 0), option->palette, -90, 355); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -40, 100); #endif // paintThinFrame(painter, option->rect.adjusted(4, 7 + option->fontMetrics.height(), -4, -4), option->palette, 60, -20); #if 0 painter->setPen(Qt::red); painter->setBrush(Qt::NoBrush); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); #endif } static void getTitleBarPalette(QPalette &palette) { QSettings settings(QLatin1String("Trolltech")); settings.beginGroup(QLatin1String("Qt")); if (settings.contains(QLatin1String("KWinPalette/activeBackground"))) { palette.setColor(QPalette::Window, QColor(settings.value(QLatin1String("KWinPalette/inactiveBackground")).toString())); palette.setColor(QPalette::WindowText, QColor(settings.value(QLatin1String("KWinPalette/inactiveForeground")).toString())); palette.setColor(QPalette::Highlight, QColor(settings.value(QLatin1String("KWinPalette/activeBackground")).toString())); palette.setColor(QPalette::HighlightedText, QColor(settings.value(QLatin1String("KWinPalette/activeForeground")).toString())); } else { palette.setColor(QPalette::Window, QColor(0, 0, 0, 20)); palette.setColor(QPalette::WindowText, QColor(0, 0, 0, 255)); QColor barColor = palette.color(QPalette::Highlight); barColor.setHsvF(barColor.hueF(), barColor.saturationF() * 0.9, 0.25); palette.setColor(QPalette::Highlight, barColor); palette.setColor(QPalette::HighlightedText, QColor(255, 255, 255, 240)); } } void paintTitleBar(QPainter *painter, const QStyleOptionTitleBar *option, const QWidget *widget, const QStyle *style) { QColor barColor; QColor textColor; painter->save(); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) qreal opacity = painter->opacity(); #endif QPalette palette = option->palette; #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (qobject_cast(widget)) { if (widget->objectName() != QLatin1String("SkulpturePreviewWindow")) { getTitleBarPalette(palette); } } #endif if (option->state & QStyle::State_Active) { barColor = palette.color(QPalette::Highlight); textColor = palette.color(QPalette::HighlightedText); } else { barColor = palette.color(QPalette::Window); textColor = palette.color(QPalette::WindowText); } QLinearGradient barGradient(option->rect.topLeft() + QPoint(-1, -1), option->rect.bottomLeft() + QPoint(-1, -2)); // barGradient.setColorAt(0.0, option->palette.color(QPalette::Window)); // barGradient.setColorAt(0.3, barColor); // barGradient.setColorAt(0.7, barColor); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) barGradient.setColorAt(0.0, barColor.darker(105)); barGradient.setColorAt(1.0, barColor.lighter(120)); #else barGradient.setColorAt(0.0, barColor.dark(105)); barGradient.setColorAt(1.0, barColor.light(120)); #endif // barGradient.setColorAt(1.0, option->palette.color(QPalette::Window)); // painter->fillRect(option->rect.adjusted(-1, -1, 1, -2), barGradient); // painter->fillRect(option->rect.adjusted(-1, -1, 1, -2), barColor); #if 1 { QRect r = option->rect.adjusted(-4, -7, 4, 0); QRect lr = r.adjusted(6, 2, -6/* - 55*/, -1); // QRect lr = r.adjusted(6, 2, -70, -1); if (true || option->state & QStyle::State_Active) { painter->fillRect(lr, barColor); } QStyleOptionTitleBar buttons = *option; // buttons.subControls &= ~QStyle::SC_TitleBarLabel; buttons.subControls = QStyle::SC_TitleBarSysMenu; buttons.rect.adjust(3, -2, -4, -1); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) painter->setOpacity(option->state & QStyle::State_Active ? opacity : 0.7 * opacity); #endif ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_TitleBar, &buttons, painter, widget); buttons = *option; #if 0 buttons.subControls &= ~(QStyle::SC_TitleBarLabel | QStyle::SC_TitleBarSysMenu); ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_TitleBar, &buttons, painter, widget); #else QStyleOption opt = *option; QIcon icon; for (int i = 1; i <= 7; ++i) { QStyle::SubControl sc = (QStyle::SubControl) (1 << i); if (option->subControls & sc & ~(QStyle::SC_TitleBarContextHelpButton)) { QRect rect = style->subControlRect(QStyle::CC_TitleBar, option, sc, widget); QIcon::Mode iconMode = QIcon::Normal; if (option->activeSubControls & sc) { iconMode = QIcon::Active; } opt.palette.setColor(QPalette::Text, textColor); icon = style->standardIcon((QStyle::StandardPixmap)(QStyle::SP_TitleBarMenuButton + i), &opt, widget); icon.paint(painter, rect, Qt::AlignCenter, iconMode); } } #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) painter->setOpacity(opacity); #endif #if 0 QRect buttonRect = option->rect.adjusted(300, 1, -90, -6); paintThinFrame(painter, buttonRect, option->palette, -180, 40); paintThinFrame(painter, buttonRect.adjusted(-1, -1, 1, 1), option->palette, 40, -180); #endif { QLinearGradient labelGradient(lr.topLeft(), lr.bottomLeft()); #if 0 labelGradient.setColorAt(0.0, QColor(0, 0, 0, 50)); labelGradient.setColorAt(0.5, QColor(0, 0, 0, 0)); labelGradient.setColorAt(0.55, QColor(0, 0, 0, 20)); labelGradient.setColorAt(1.0, QColor(0, 0, 0, 0)); #elif 1 labelGradient.setColorAt(0.0, QColor(255, 255, 255, 10)); labelGradient.setColorAt(0.5, QColor(255, 255, 255, 40)); labelGradient.setColorAt(0.55, QColor(255, 255, 255, 0)); labelGradient.setColorAt(1.0, QColor(255, 255, 255, 20)); #else labelGradient.setColorAt(0.0, QColor(0, 0, 0, 30)); labelGradient.setColorAt(1.0, QColor(255, 255, 255, 60)); #endif painter->fillRect(lr, labelGradient); } QLinearGradient barGradient(r.topLeft(), r.bottomLeft()); barGradient.setColorAt(0.0, QColor(255, 255, 255, 200)); barGradient.setColorAt(0.2, QColor(255, 255, 255, 80)); barGradient.setColorAt(0.5, QColor(255, 255, 255, 30)); barGradient.setColorAt(1.0, QColor(255, 255, 255, 0)); painter->fillRect(r, barGradient); #if 0 QRadialGradient dialogGradient2(r.left() + r.width() / 2, r.top(), r.height()); dialogGradient2.setColorAt(0.0, QColor(255, 255, 225, 70)); dialogGradient2.setColorAt(1.0, QColor(0, 0, 0, 0)); painter->save(); painter->translate(r.center()); painter->scale(r.width() / 2.0 / r.height(), 1); painter->translate(-r.center()); painter->fillRect(r.adjusted(1, 1, -1, -1), dialogGradient2); painter->restore(); #endif paintThinFrame(painter, lr, option->palette, -30, 90); paintThinFrame(painter, lr.adjusted(-1, -1, 1, 1), option->palette, 90, -30); } #endif #if 0 // paintThinFrame(painter, option->rect.adjusted(0, 0, 0, -1), option->palette, -30, 80); paintThinFrame(painter, option->rect.adjusted(-1, -1, 1, 0), option->palette, 80, -30); painter->fillRect(option->rect.adjusted(0, 0, 0, -1), barColor); // FIXME: adjust rect for new shadow // paintRecessedFrameShadow(painter, option->rect.adjusted(-1, -1, 1, 0), RF_Large); { QRect labelRect = option->rect.adjusted(20, 0, -250, 0); painter->fillRect(labelRect, option->palette.color(QPalette::Window)); paintThinFrame(painter, labelRect.adjusted(0, 0, 0, 1), option->palette, -30, 80); } #endif if (option->subControls & QStyle::SC_TitleBarLabel) { QRect labelRect; #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (qobject_cast(widget)) { QFont font = painter->font(); font.setBold(true); if (option->direction == Qt::LeftToRight) { labelRect = option->rect.adjusted(option->fontMetrics.height() + 10, -1, -2, -3); } else { labelRect = option->rect.adjusted(1, -1, -option->fontMetrics.height() - 11, -3); } // font.setPointSizeF(10); painter->setFont(font); } else #endif { labelRect = style->subControlRect(QStyle::CC_TitleBar, option, QStyle::SC_TitleBarLabel, widget); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) painter->setOpacity(opacity); #endif painter->setPen(QColor(0, 0, 0, 25)); style->drawItemText(painter, labelRect.adjusted(1, 1, 1, 1), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, option->palette, true, option->text, QPalette::NoRole); //painter->drawText(labelRect.adjusted(1, 1, 1, 1), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, option->text); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) painter->setOpacity(option->state & QStyle::State_Active ? opacity : 0.7 * opacity); #endif painter->setPen(textColor); style->drawItemText(painter, labelRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, option->palette, true, option->text, QPalette::NoRole); //painter->drawText(labelRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, option->text); } /* if (!option->icon.isNull()) { labelRect.setWidth(16); labelRect.setHeight(16); painter->drawPixmap(labelRect.adjusted(0, -1, 0, -1), option->icon.pixmap(QSize(16, 16))); } */ painter->restore(); } int getWindowFrameMask(QStyleHintReturnMask *mask, const QStyleOptionTitleBar *option, const QWidget *widget) { Q_UNUSED(widget); mask->region = option->rect; // TODO get total dimensions of workspace and don't use masks on corners /*if (option->rect.topLeft() != QPoint(0, 0))*/ { // mask->region -= QRect(option->rect.topLeft(), QSize(1, 1)); } // mask->region -= QRect(option->rect.topRight(), QSize(1, 1)); // mask->region -= QRect(option->rect.bottomLeft(), QSize(1, 1)); // mask->region -= QRect(option->rect.bottomRight(), QSize(1, 1)); // try new style // mask->region -= QRect(option->rect.topLeft(), QSize(6, 1)); // mask->region -= QRect(option->rect.topRight() - QPoint(5, 0), QSize(6, 1)); return 1; } /* * skulpture_menu.cpp * */ #include "skulpture_p.h" #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) #include #endif /*-----------------------------------------------------------------------*/ void paintFrameMenu(QPainter *painter, const QStyleOptionFrame *option, const QWidget */*widget*/, const QStyle */*style*/) { paintThinFrame(painter, option->rect, option->palette, -60, 160); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -20, 60); } void paintPanelMenuBar(QPainter *painter, const QStyleOptionFrame *option, const QWidget */*widget*/, const QStyle */*style*/) { Q_UNUSED(painter); Q_UNUSED(option); // paintThinFrame(painter, option->rect, option->palette, -20, 60); // painter->fillRect(option->rect.adjusted(1, 1, -1, -1), option->palette.color(QPalette::Window)); } void paintMenuBarEmptyArea(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { Q_UNUSED(painter); Q_UNUSED(option); // painter->fillRect(option->rect, option->palette.color(QPalette::Window)); } /*-----------------------------------------------------------------------*/ extern void paintCommandButtonPanel(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style); void paintMenuBarItem(QPainter *painter, const QStyleOptionMenuItem *option, const QWidget *widget, const QStyle *style) { QStyleOptionMenuItem opt = *option; if (option->state & QStyle::State_Selected || option->state & QStyle::State_MouseOver) { QStyleOptionButton button; button.QStyleOption::operator=(*option); button.features = QStyleOptionButton::None; button.state |= QStyle::State_MouseOver; painter->save(); painter->setClipRect(button.rect.adjusted(1, 1, -1, -1)); // call without widget to get QPalette::Button background paintCommandButtonPanel(painter, &button, 0, 0); painter->restore(); } else { opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::WindowText)); } opt.state &= ~QStyle::State_Sunken; ((QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_MenuBarItem, &opt, painter, widget); } /*-----------------------------------------------------------------------*/ enum MenuMode { ButtonMenu, ItemViewMenu, }; enum CheckColumnMode { UseIconColumn, ShowCheckColumn, NoCheckColumn }; enum IconColumnMode { ForceIconColumn, ShowIconColumn, HideIconColumn }; enum SeparatorMode { TextSeparator, IconSeparator, ItemSeparator }; enum SelectionMode { TextSelection, IconSelection, ItemSelection }; /*-----------------------------------------------------------------------*/ QSize sizeFromContentsMenuItem(const QStyleOptionMenuItem *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int menuItemSize, int textLineHeight) { if (option->menuItemType == QStyleOptionMenuItem::Separator) { if (option->text.isEmpty()) { return QSize(4, 4); } // ### width? return QSize(4, QFontMetrics(option->font).height() + 8); } int w = contentsSize.width(), h = contentsSize.height(); // always make room for icon column const int iconMargin = 4; int iconWidth; if (option->maxIconWidth) { iconWidth = option->maxIconWidth - 4 + 2 * iconMargin; } else { iconWidth = style->pixelMetric(QStyle::PM_SmallIconSize, option, widget) + 2 * iconMargin; } w += iconWidth; // add size for check column const int checkMargin = 4; if (option->checkType != QStyleOptionMenuItem::NotCheckable) { w += style->pixelMetric(QStyle::PM_IndicatorWidth, option, widget) + checkMargin; } // submenu arrow and spacing w += option->fontMetrics.height() + 4; if (option->menuItemType == QStyleOptionMenuItem::SubMenu || option->text.indexOf(QChar('\t', 0)) >= 0) { w += option->fontMetrics.height(); } if (h < textLineHeight) { h = textLineHeight; } h += menuItemSize; return QSize(w, qMax(h, 0)); } /*-----------------------------------------------------------------------*/ inline QRect remainingHorizontalVisualRect(const QRect &rect, const QStyleOption *option, int width) { return rect.adjusted(option->direction == Qt::LeftToRight ? width : 0, 0, option->direction != Qt::LeftToRight ? -width : 0, 0); } inline QRect horizontalVisualRect(const QRect &rect, const QStyleOption *option, int width) { QRect res = rect; if (option->direction != Qt::LeftToRight) { res.setLeft(rect.left() + rect.width() - width); } else { res.setWidth(width); } return res; } inline QRect rightHorizontalVisualRect(const QRect &rect, const QStyleOption *option, int width) { QRect res = rect; if (option->direction != Qt::LeftToRight) { res.setWidth(width); } else { res.setLeft(rect.left() + rect.width() - width); } return res; } /*-----------------------------------------------------------------------*/ void paintMenuItem(QPainter *painter, const QStyleOptionMenuItem *option, const QWidget *widget, const QStyle *style) { // configuration const MenuMode menuMode = ButtonMenu; const CheckColumnMode checkColumnMode = option->maxIconWidth ? (/*option->menuHasCheckableItems ? UseIconColumn :*/ NoCheckColumn) : NoCheckColumn; const bool showUncheckedIndicator = true; const bool showShortcut = true; const IconColumnMode iconColumnMode = checkColumnMode == UseIconColumn && option->menuHasCheckableItems ? ForceIconColumn : option->maxIconWidth ? ShowIconColumn : ShowIconColumn; const SeparatorMode separatorMode = TextSeparator; const SelectionMode selectionMode = ItemSelection; // layout // ### make margins configurable const int checkMargin = 4; const int iconMargin = 4; const int checkSize = option->menuHasCheckableItems ? qMax(style->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, option, widget), style->pixelMetric(QStyle::PM_IndicatorWidth, option, widget)) : 0; const int iconSize = style->pixelMetric(QStyle::PM_SmallIconSize, option, widget); const int checkColumnWidth = checkSize + 2 * checkMargin; // FIXME qMax(checkSize, iconSize) for useIconColum const int iconColumnWidth = iconColumnMode == HideIconColumn ? 0 : option->maxIconWidth ? option->maxIconWidth - 4 + 2 * iconMargin : iconSize + 2 * iconMargin; #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) // Qt 4.x has a bug where the option->rect is one pixel too wide const QRect itemRect = runtimeQtVersion() < QT_VERSION_CHECK(4, 6, 0) ? option->rect.adjusted(0, 0, -1, 0) : option->rect; #else const QRect itemRect = option->rect; #endif QRect iconRect = horizontalVisualRect(itemRect, option, iconColumnWidth); QRect textRect = remainingHorizontalVisualRect(itemRect, option, iconColumnWidth); // background color QPalette::ColorRole menuBackgroundRole; QPalette::ColorRole menuForegroundRole; QBrush menuBackground; QBrush iconBackground; switch (menuMode) { case ButtonMenu: menuBackgroundRole = QPalette::Window; menuForegroundRole = QPalette::WindowText; iconBackground = QColor(0, 0, 0, 10); break; case ItemViewMenu: menuBackgroundRole = QPalette::Base; menuForegroundRole = QPalette::Text; iconBackground = option->palette.brush(QPalette::Active, QPalette::Window); break; } // background menuBackground = option->palette.brush(QPalette::Active, menuBackgroundRole); painter->fillRect(textRect, menuBackground); if (!iconRect.isEmpty()) { if (!iconBackground.isOpaque()) { painter->fillRect(iconRect, menuBackground); } } painter->fillRect(iconRect, iconBackground); // painter->fillRect(iconRect.adjusted(2, 2, -2, -2), QColor(0, 255, 0, 120)); // separator if (option->menuItemType == QStyleOptionMenuItem::Separator) { QRect separatorRect; switch (separatorMode) { case IconSeparator: separatorRect = iconRect; break; case TextSeparator: separatorRect = textRect; break; case ItemSeparator: separatorRect = itemRect; break; } // ### make separator margins configurable separatorRect.adjust(0, 1, 0, -1); if (option->text.isEmpty()) { paintThinFrame(painter, separatorRect, option->palette, 60, -20); } else { const int textFlags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip | Qt::TextSingleLine; QColor bgcolor = menuBackground.color(); paintThinFrame(painter, separatorRect, option->palette, -10, -20); paintThinFrame(painter, separatorRect.adjusted(1, 1, -1, -1), option->palette, -30, 80, menuBackgroundRole); QLinearGradient gradient(separatorRect.topLeft(), separatorRect.bottomLeft()); gradient.setColorAt(0.0, shaded_color(bgcolor, 90)); gradient.setColorAt(0.2, shaded_color(bgcolor, 60)); gradient.setColorAt(0.5, shaded_color(bgcolor, 0)); gradient.setColorAt(0.51, shaded_color(bgcolor, -10)); gradient.setColorAt(1.0, shaded_color(bgcolor, -20)); painter->fillRect(separatorRect.adjusted(1, 1, -1, -1), gradient); // ### margins separatorRect = remainingHorizontalVisualRect(separatorRect, option, 8); style->drawItemText(painter, separatorRect, textFlags, option->palette, true, option->text, menuForegroundRole); } return; } // selection background painter->save(); if (option->state & QStyle::State_Selected) { QRect selectionRect; switch (selectionMode) { case IconSelection: selectionRect = iconRect; break; case TextSelection: selectionRect = textRect; break; case ItemSelection: selectionRect = itemRect; break; } switch (menuMode) { case ButtonMenu: { QStyleOptionButton button; button.QStyleOption::operator=(*option); button.features = QStyleOptionButton::None; button.state |= QStyle::State_MouseOver; button.rect = selectionRect.adjusted(-1, -1, 1, 1); paintCommandButtonPanel(painter, &button, 0, 0); menuForegroundRole = QPalette::ButtonText; break; } case ItemViewMenu: { QColor color = option->palette.color(QPalette::Active, QPalette::Highlight); color.setAlpha(option->state & QStyle::State_Enabled ? 180 : 40); painter->fillRect(selectionRect, color); if (option->state & QStyle::State_Enabled) { paintThinFrame(painter, selectionRect, option->palette, -20, -20); } menuForegroundRole = QPalette::HighlightedText; break; } } painter->setPen(option->palette.color(QPalette::Active, menuForegroundRole)); } // arrow if (option->menuItemType == QStyleOptionMenuItem::SubMenu) { const int arrowWidth = option->fontMetrics.height(); const QRect arrowRect = rightHorizontalVisualRect(textRect, option, arrowWidth); QStyleOptionMenuItem opt = *option; opt.rect = arrowRect; QFont font = painter->font(); font.setPointSizeF(font.pointSizeF() / 1.19); opt.fontMetrics = QFontMetrics(font); opt.state &= QStyle::State_Enabled; opt.palette.setColor(QPalette::ButtonText, option->palette.color(option->state & QStyle::State_Enabled ? QPalette::Active : QPalette::Disabled, menuForegroundRole)); style->drawPrimitive((option->direction == Qt::RightToLeft) ? QStyle::PE_IndicatorArrowLeft : QStyle::PE_IndicatorArrowRight, &opt, painter, widget); } // check if (option->checkType != QStyleOptionMenuItem::NotCheckable) { QRect checkRect; switch (checkColumnMode) { case UseIconColumn: checkRect = iconRect; if (option->checked) { // when using the icon colum, we do not show an icon for checked items iconRect = QRect(); } break; case NoCheckColumn: case ShowCheckColumn: checkRect = horizontalVisualRect(textRect, option, checkColumnWidth); textRect = remainingHorizontalVisualRect(textRect, option, checkColumnWidth - checkMargin); break; } // painter->fillRect(checkRect.adjusted(2, 2, -2, -2), QColor(0, 0, 255, 120)); if (option->checked || option->state & QStyle::State_Selected || (showUncheckedIndicator && option->checkType == QStyleOptionMenuItem::NonExclusive)) { QStyleOptionMenuItem opt = *option; opt.rect = checkRect; style->drawPrimitive(QStyle::PE_IndicatorMenuCheckMark, &opt, painter, widget); } } else if (checkColumnMode == ShowCheckColumn) { textRect = remainingHorizontalVisualRect(textRect, option, checkColumnWidth - checkMargin); } // painter->fillRect(textRect.adjusted(2, 2, -2, -2), QColor(255, 0, 0, 120)); // text if (!option->text.isEmpty()) { const int shortcutPos = option->text.indexOf(QChar('\t', 0)); int textFlags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!style->styleHint(QStyle::SH_UnderlineShortcut, option, widget)) { textFlags |= Qt::TextHideMnemonic; } if (showShortcut && shortcutPos >= 0) { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) const int shortcutWidth = option->tabWidth + option->fontMetrics.height() - 2; #else const int shortcutWidth = option->fontMetrics.averageCharWidth() * (option->text.length() - shortcutPos); #endif const QRect shortcutRect = rightHorizontalVisualRect(textRect, option, shortcutWidth); // painter->fillRect(shortcutRect, QColor(255, 220, 0, 120)); style->drawItemText(painter, shortcutRect, textFlags, option->palette, option->state & QStyle::State_Enabled, option->text.mid(shortcutPos + 1), menuForegroundRole); } QFont font = option->font; if (option->menuItemType == QStyleOptionMenuItem::DefaultItem) { font.setBold(true); } painter->setFont(font); // ### textMargin textRect = remainingHorizontalVisualRect(textRect, option, 4); style->drawItemText(painter, textRect, textFlags, option->palette, option->state & QStyle::State_Enabled, option->text.left(shortcutPos), menuForegroundRole); } // icon if (iconColumnMode != HideIconColumn && !option->icon.isNull() && !iconRect.isEmpty()) { QIcon::Mode mode; if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Selected) { mode = QIcon::Active; } else { mode = QIcon::Normal; } } else { mode = QIcon::Disabled; } iconRect = QRect((iconRect.left() + iconRect.right() + 2 - iconSize) >> 1, (iconRect.top() + iconRect.bottom() + 2 - iconSize) >> 1, iconSize, iconSize); option->icon.paint(painter, iconRect, Qt::AlignCenter, mode, QIcon::Off); } painter->restore(); } /*-----------------------------------------------------------------------*/ void paintMenuTitle(QPainter *painter, const QStyleOptionToolButton *option, const QWidget *widget, const QStyle *style) { const QPalette::ColorRole bgrole = QPalette::Window; QColor bgcolor = option->palette.color(bgrole); QStyleOptionToolButton opt = *option; opt.state &= ~(QStyle::State_Sunken | QStyle::State_On | QStyle::State_Selected | QStyle::State_HasFocus); #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) if (runtimeQtVersion() < QT_VERSION_CHECK(4, 6, 0)) { // Qt 4.x has a bug where the option->rect is one pixel too wide opt.rect.adjust(0, 0, -1, 0); } #endif opt.palette.setColor(QPalette::ButtonText, option->palette.color(QPalette::WindowText)); paintThinFrame(painter, opt.rect, option->palette, -10, -20); paintThinFrame(painter, opt.rect.adjusted(1, 1, -1, -1), opt.palette, -30, 80, bgrole); QLinearGradient gradient(opt.rect.topLeft(), opt.rect.bottomLeft()); gradient.setColorAt(0.0, shaded_color(bgcolor, 90)); gradient.setColorAt(0.2, shaded_color(bgcolor, 60)); gradient.setColorAt(0.5, shaded_color(bgcolor, 0)); gradient.setColorAt(0.51, shaded_color(bgcolor, -10)); gradient.setColorAt(1.0, shaded_color(bgcolor, -20)); painter->fillRect(opt.rect.adjusted(1, 1, -1, -1), gradient); ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_ToolButton, &opt, painter, widget); } /*-----------------------------------------------------------------------*/ #if (QT_VERSION < QT_VERSION_CHECK(4, 6, 0)) bool SkulptureStyle::Private::menuEventFilter(QMenu *menu, QEvent *event) { QHash::iterator i = menuHash.begin(); while (i != menuHash.end()) { if (!i->menu) { i = menuHash.erase(i); } else { ++i; } } i = menuHash.find(menu); MenuInfo *menuInfo = i != menuHash.end() ? &(*i) : 0; if (event->type() == QEvent::Hide || event->type() == QEvent::Destroy) { if (menuInfo) { menuHash.erase(i); } menuInfo = 0; } else { QPoint eventPos; bool moveEvent = false; if (event->type() == QEvent::TabletMove) { QTabletEvent *tabletEvent = (QTabletEvent *) event; eventPos = tabletEvent->pos(); moveEvent = true; } else if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = (QMouseEvent *) event; eventPos = mouseEvent->pos(); moveEvent = true; } QAction *menuAction = 0; QAction *action = 0; if (moveEvent && menu->rect().contains(eventPos)) { action = menu->actionAt(eventPos); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) if (QWidgetAction * widgetAction = qobject_cast(action)) { if (!widgetAction->defaultWidget()) { if (action->menu()) { menuAction = action; } } } else #endif if (action && action->menu()) { menuAction = action; } } if (menuAction && !menuInfo) { MenuInfo info; info.menu = menu; info.delayTimer = 0; info.lastPos = eventPos; info.eventCount = 0; i = menuHash.insert(menu, info); menuInfo = &(*i); } if (menuInfo) { if (event->type() == QEvent::Enter) { menuInfo->lastSubMenuAction = 0; menuInfo->eventCount = 0; } else if (event->type() == QEvent::Leave) { menuInfo->lastSubMenuAction = 0; menuInfo->eventCount = 0; } else if (moveEvent) { if (action != menuAction) { menuInfo->lastSubMenuAction = 0; menuInfo->eventCount = 0; } if (menu->rect().contains(eventPos)) { if (menuAction) { QAction *last = menuInfo->lastSubMenuAction; menuInfo->lastSubMenuAction = menuAction; if (last && last == menuAction) { if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = (QMouseEvent *) event; ++menuInfo->eventCount; if (menuInfo->eventCount > 2 && mouseEvent->buttons() == Qt::NoButton) { event->accept(); return true; } } } else { menuInfo->eventCount = 0; } } } else { menuInfo->lastSubMenuAction = 0; menuInfo->eventCount = 0; } } } } return false; } #endif /* * skulpture_misc.cpp * */ #include "skulpture_p.h" #include #include /*-----------------------------------------------------------------------*/ extern void paintPanelButtonTool(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) #if 0 void paintPanelPlacesViewItem(QPainter *painter, const QStyleOptionViewItemV4 *option, const QWidget *widget, const QStyle *style) { QStyleOption opt = *option; if (opt.state & QStyle::State_Selected) { opt.state |= QStyle::State_On; } else if (!(opt.state & QStyle::State_MouseOver)) { // draw nothing return; } paintPanelButtonTool(painter, &opt, 0, style); } #endif #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintPanelItemViewItem(QPainter *painter, const QStyleOptionViewItemV4 *option, const QWidget *widget, const QStyle *style) #else void paintPanelItemViewItem(QPainter *painter, const QStyleOptionViewItem *option, const QWidget *widget, const QStyle *style) #endif { Q_UNUSED(style); #if 0 if (widget && widget->inherits("KFilePlacesView")) { paintPanelPlacesViewItem(painter, option, widget, style); return; } #endif QColor color = option->palette.color(QPalette::Highlight); const bool mouse = option->state & QStyle::State_MouseOver && option->state & QStyle::State_Enabled; const QTableView *table = qobject_cast(widget); const bool largePanel = option->rect.height() > 7 + option->fontMetrics.height() && !table; QRect panelRect; if (largePanel) { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (option->version >= 4) { switch (option->viewItemPosition) { case QStyleOptionViewItemV4::Beginning: panelRect = option->rect.adjusted(1, 1, 0, 0); break; case QStyleOptionViewItemV4::End: panelRect = option->rect.adjusted(0, 1, -1, 0); break; case QStyleOptionViewItemV4::Middle: panelRect = option->rect.adjusted(0, 1, 0, 0); break; case QStyleOptionViewItemV4::Invalid: case QStyleOptionViewItemV4::OnlyOne: panelRect = option->rect.adjusted(1, 1, -1, 0); break; } } else { panelRect = option->rect.adjusted(1, 1, -1, 0); } #else panelRect = option->rect.adjusted(1, 1, -1, 0); #endif } else { panelRect = option->rect; } #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (option->version >= 2 && option->features & QStyleOptionViewItemV2::Alternate) { painter->fillRect(panelRect, option->palette.color(QPalette::AlternateBase)); } else { painter->fillRect(panelRect, option->backgroundBrush); } #else painter->fillRect(panelRect, option->backgroundBrush); #endif if (option->state & QStyle::State_Selected) { if (mouse) { color = color.lighter(110); } } else if (mouse) { color.setAlpha(40); } else { return; } painter->save(); // ### work around KDE widgets that turn on antialiasing painter->setRenderHint(QPainter::Antialiasing, false); painter->setBrush(Qt::NoBrush); // QColor shine(255, 255, 255, panelRect.height() > 20 ? 25 : 10); QColor shadow(0, 0, 0, largePanel ? 50 : 20); painter->setPen(shadow); // painter->setPen(QPen(color.darker(panelRect.height() > 20 ? 150 : 120), 1)); painter->fillRect(panelRect, color); if (table && table->showGrid()) { painter->restore(); return; } #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (option->version >= 4) { switch (option->viewItemPosition) { case QStyleOptionViewItemV4::Beginning: painter->drawLine(panelRect.topLeft() + QPoint(0, 1), panelRect.bottomLeft() - QPoint(0, 1)); painter->drawLine(panelRect.topLeft(), panelRect.topRight()); painter->drawLine(panelRect.bottomLeft(), panelRect.bottomRight()); break; case QStyleOptionViewItemV4::End: painter->drawLine(panelRect.topRight() + QPoint(0, 1), panelRect.bottomRight() - QPoint(0, 1)); painter->drawLine(panelRect.topLeft(), panelRect.topRight()); painter->drawLine(panelRect.bottomLeft(), panelRect.bottomRight()); break; case QStyleOptionViewItemV4::Middle: painter->drawLine(panelRect.topLeft(), panelRect.topRight()); painter->drawLine(panelRect.bottomLeft(), panelRect.bottomRight()); break; case QStyleOptionViewItemV4::Invalid: case QStyleOptionViewItemV4::OnlyOne: painter->drawRect(panelRect.adjusted(0, 0, -1, -1)); break; } } else { painter->drawRect(panelRect.adjusted(0, 0, -1, -1)); } #else painter->drawRect(panelRect.adjusted(0, 0, -1, -1)); #endif painter->restore(); } #endif /*-----------------------------------------------------------------------*/ extern void paintCachedIndicatorBranchChildren(QPainter *painter, const QStyleOption *option); void paintIndicatorBranch(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { QPoint center = option->rect.center() + (option->direction == Qt::LeftToRight ? QPoint(2, 0) : QPoint(-1, 0)); if (option->state & (QStyle::State_Item | QStyle::State_Sibling)) { QColor lineColor = option->palette.color(QPalette::Text); lineColor.setAlpha(50); painter->fillRect(QRect(center.x(), option->rect.y(), 1, center.y() - option->rect.y()), lineColor); if (option->state & QStyle::State_Sibling) { painter->fillRect(QRect(center.x(), center.y(), 1, option->rect.bottom() - center.y() + 1), lineColor); } if (option->state & QStyle::State_Item) { if (option->direction == Qt::LeftToRight) { painter->fillRect(QRect(center.x() + 1, center.y(), option->rect.right() - center.x(), 1), lineColor); } else { painter->fillRect(QRect(option->rect.left(), center.y(), center.x() - option->rect.left(), 1), lineColor); } if (!(option->state & QStyle::State_Sibling)) { lineColor.setAlpha(25); painter->fillRect(QRect(center.x(), center.y(), 1, 1), lineColor); } } } if (option->state & QStyle::State_Children && !(option->state & QStyle::State_Open)) { QStyleOption opt = *option; static const int d = 9; opt.rect = QRect(center.x() - d / 2, center.y() - d / 2, d, d); paintCachedIndicatorBranchChildren(painter, &opt); } } /*-----------------------------------------------------------------------*/ #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) void paintQ3ListView(QPainter *painter, const QStyleOptionQ3ListView *option, const QWidget *widget, const QStyle *style) { Q_UNUSED(widget); Q_UNUSED(style); if (option->subControls & QStyle::SC_Q3ListView) { painter->fillRect(option->rect, option->viewportPalette.brush(option->viewportBGRole)); } if (option->subControls & QStyle::SC_Q3ListViewBranch) { QStyleOption opt = *((QStyleOption *) option); int y = option->rect.y(); for (int i = 1; i < option->items.size(); ++i) { QStyleOptionQ3ListViewItem item = option->items.at(i); if (y + item.totalHeight > 0 && y < option->rect.height()) { opt.state = QStyle::State_Item; if (i + 1 < option->items.size()) { opt.state |= QStyle::State_Sibling; } if (item.features & QStyleOptionQ3ListViewItem::Expandable || (item.childCount > 0 && item.height > 0)) { opt.state |= QStyle::State_Children | (item.state & QStyle::State_Open); } opt.rect = QRect(option->rect.left(), y, option->rect.width(), item.height); paintIndicatorBranch(painter, &opt, 0, 0); if (opt.state & QStyle::State_Sibling && item.height < item.totalHeight) { opt.state = QStyle::State_Sibling; opt.rect = QRect(option->rect.left(), y + item.height, option->rect.width(), item.totalHeight - item.height); paintIndicatorBranch(painter, &opt, 0, 0); } } y += item.totalHeight; } } } #endif /*-----------------------------------------------------------------------*/ void paintSizeGrip(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { Qt::Corner corner = Qt::BottomRightCorner; #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) if (option->type == QStyleOption::SO_SizeGrip) { const QStyleOptionSizeGrip *sizegrip = static_cast(option); corner = sizegrip->corner; } #endif QRect r; switch (corner) { case Qt::TopLeftCorner: r = option->rect.adjusted(0, 0, 2, 2); break; case Qt::TopRightCorner: r = option->rect.adjusted(-2, 0, 0, 2); break; case Qt::BottomLeftCorner: r = option->rect.adjusted(0, -2, 2, 0); break; case Qt::BottomRightCorner: r = option->rect.adjusted(-2, -2, 0, 0); break; } paintThinFrame(painter, r, option->palette, 60, -20); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -20, 60); switch (corner) { case Qt::TopRightCorner: // for Kickoff 4.1 painter->save(); painter->setPen(QPen(shaded_color(option->palette.color(QPalette::Window), 60), 1.0)); painter->drawLine(r.topLeft(), r.bottomRight()); painter->setPen(QPen(shaded_color(option->palette.color(QPalette::Window), -20), 1.0)); painter->drawLine(r.topLeft() + QPoint(1, -1), r.bottomRight() + QPoint(1, -1)); painter->restore(); break; case Qt::BottomRightCorner: painter->save(); painter->setPen(QPen(shaded_color(option->palette.color(QPalette::Window), -20), 1.0)); painter->drawLine(r.topRight(), r.bottomLeft()); painter->setPen(QPen(shaded_color(option->palette.color(QPalette::Window), 60), 1.0)); painter->drawLine(r.topRight() + QPoint(1, 1), r.bottomLeft() + QPoint(1, 1)); painter->restore(); break; case Qt::TopLeftCorner: // TODO break; case Qt::BottomLeftCorner: // TODO break; } } /*-----------------------------------------------------------------------*/ extern void paintCommandButtonPanel(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintToolBoxTabShape(QPainter *painter, const QStyleOptionToolBoxV2 *option, const QWidget */*widget*/, const QStyle */*style*/) #else void paintToolBoxTabShape(QPainter *painter, const QStyleOptionToolBox *option, const QWidget */*widget*/, const QStyle */*style*/) #endif { QRect r = option->rect; if (option->state & QStyle::State_Selected) { QColor color = option->palette.color(QPalette::Window); paintThinFrame(painter, r, option->palette, 40, -20); paintThinFrame(painter, r.adjusted(1, 1, -1, -1), option->palette, -20, 80); QLinearGradient gradient(r.topLeft(), r.bottomLeft()); gradient.setColorAt(0.0, shaded_color(color, 50)); gradient.setColorAt(0.2, shaded_color(color, 30)); gradient.setColorAt(0.5, shaded_color(color, 0)); gradient.setColorAt(0.51, shaded_color(color, -10)); gradient.setColorAt(1.0, shaded_color(color, -20)); painter->fillRect(r.adjusted(1, 1, -1, -1), gradient); } else if (option->state & (QStyle::State_Sunken | QStyle::State_MouseOver)) { QStyleOptionButton button; button.QStyleOption::operator=(*option); button.features = QStyleOptionButton::None; button.rect.adjust(-1, -1, 1, 1); // ### needs QPalette::Window ? paintCommandButtonPanel(painter, &button, 0, 0); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) } else if (option->version >= 2 && option->selectedPosition == QStyleOptionToolBoxV2::PreviousIsSelected) { r.setHeight(2); paintThinFrame(painter, r, option->palette, 60, -20); #endif } else { // r.setHeight(2); // painter->fillRect(r, option->palette.color(QPalette::Window)); } QStyleOption indicator; indicator = *option; indicator.rect.setSize(QSize(11, 11)); indicator.rect.translate(0, (option->rect.height() - 11) >> 1); indicator.state = QStyle::State_Children; if (option->state & QStyle::State_Selected) { indicator.state |= QStyle::State_Open; } paintIndicatorBranch(painter, &indicator, 0, 0); } void paintToolBoxTabLabel(QPainter *painter, const QStyleOptionToolBox *option, const QWidget *widget, const QStyle *style) { #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) QStyleOptionToolBoxV2 opt; #else QStyleOptionToolBox opt; #endif #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (option->version >= 2) opt = *((const QStyleOptionToolBoxV2 *) option); else #endif opt = *option; if ((option->state & QStyle::State_Selected) || !(option->state & (QStyle::State_Sunken | QStyle::State_MouseOver))) { opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::WindowText)); } ((QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_ToolBoxTabLabel, &opt, painter, widget); } /*-----------------------------------------------------------------------*/ extern void paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole bgrole); void paintSplitter(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { if (option->state & QStyle::State_Enabled && option->state & QStyle::State_MouseOver) { painter->fillRect(option->rect, QColor(255, 255, 255, 60)); } int d = 5; QRect rect(QRect(option->rect).center() - QPoint(d / 2, d / 2), QSize(d, d)); QStyleOption iOption = *option; iOption.rect = rect; iOption.palette.setCurrentColorGroup(QPalette::Disabled); // iOption.state &= ~QStyle::State_Enabled; iOption.palette.setColor(QPalette::Button, iOption.palette.color(QPalette::Window)); paintCachedGrip(painter, &iOption, QPalette::Window); } /*-----------------------------------------------------------------------*/ void paintRubberBand(QPainter *painter, const QStyleOptionRubberBand *option, const QWidget */*widget*/, const QStyle */*style*/) { painter->save(); if (true || option->shape == QRubberBand::Rectangle) { QColor color = option->palette.color(QPalette::Highlight); color.setAlphaF(0.2 * color.alphaF()); painter->fillRect(option->rect, color); color = option->palette.color(QPalette::Highlight); color.setAlphaF(0.8 * color.alphaF()); painter->setPen(QPen(color /*, 1.0, Qt::DotLine*/)); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); } else { // painter->fillRect(option->rect, Qt::green); } painter->restore(); } int getRubberBandMask(QStyleHintReturnMask *mask, const QStyleOption *option, const QWidget *widget) { static const int rubber_width = 4; int r = rubber_width; Q_UNUSED(widget); mask->region = option->rect; if (option->rect.width() > 2 * r && option->rect.height() > 2 * r) { mask->region -= option->rect.adjusted(r, r, -r, -r); } return 1; } /* * skulpture_progressbar.cpp * */ #include "skulpture_p.h" #include #include #include #include #if 0 #define FG_ROLE_PROGRESS QPalette::WindowText #define BG_ROLE_PROGRESS QPalette::Window #elif 1 #define FG_ROLE_PROGRESS QPalette::Text #define BG_ROLE_PROGRESS QPalette::Base #else #define FG_ROLE_PROGRESS QPalette::QPalette::Highlight #define BG_ROLE_PROGRESS QPalette::Base #endif #define FG_ROLE_CHUNK QPalette::HighlightedText #define BG_ROLE_CHUNK QPalette::Highlight /*-----------------------------------------------------------------------*/ static bool isPasswordStrengthIndicator(const QWidget *widget) { return widget && widget->parentWidget() && widget->parentWidget()->parentWidget() && widget->parentWidget()->parentWidget()->inherits("KNewPasswordDialog"); } static bool isDiskSpaceIndicator(const QWidget *widget) { return false && widget && widget->inherits("StatusBarSpaceInfo"); } /*-----------------------------------------------------------------------*/ #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) static bool progressBarContentsCentered(const QStyleOptionProgressBarV2 *option, const QWidget *widget) #else static bool progressBarContentsCentered(const QStyleOptionProgressBar *option, const QWidget *widget) #endif { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) const bool vertical = option->version >= 2 && option->orientation == Qt::Vertical; #else Q_UNUSED(option); const bool vertical = false; #endif if (vertical) { return false; } if (isPasswordStrengthIndicator(widget) || isDiskSpaceIndicator(widget)) { return false; } return true; } #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) static QRect progressBarContentsRect(const QStyleOptionProgressBarV2 *option, bool contentsCentered) #else static QRect progressBarContentsRect(const QStyleOptionProgressBar *option, bool contentsCentered) #endif { // configuration options const int border = 2; QRect contentsRect = option->rect.adjusted(border, border, -border, -border); if (option->minimum < option->maximum) { if (option->progress > option->minimum) { if (option->progress < option->maximum) { // progress qreal progress = qreal(option->progress - option->minimum) / (option->maximum - option->minimum); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (option->version >= 2 && option->orientation == Qt::Vertical) { if (contentsCentered) { int adjustment = int((contentsRect.height() / 2) * (1 - progress)); contentsRect.adjust(0, adjustment, 0, -adjustment); } else { int contentsHeight = qMax(1, int(contentsRect.height() * progress + 0.5)); if (option->version >= 2 && option->invertedAppearance) { contentsRect.setHeight(contentsHeight); } else { contentsRect.setTop(contentsRect.top() + contentsRect.height() - contentsHeight); } } } else { #endif if (contentsCentered) { int adjustment = int((contentsRect.width() / 2) * (1 - progress)); contentsRect.adjust(adjustment, 0, -adjustment, 0); } else { int contentsWidth = qMax(1, int(contentsRect.width() * progress + 0.5)); if ((option->version >= 2 && option->invertedAppearance) ^ (option->direction != Qt::LeftToRight)) { contentsRect.setLeft(contentsRect.left() + contentsRect.width() - contentsWidth); } else { contentsRect.setWidth(contentsWidth); } } #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) } #endif } else { // finished } } else { // starting contentsRect = QRect(); } } else if (option->minimum == option->maximum) { // busy indicator } else { // invalid values contentsRect = QRect(); } return contentsRect; } /*-----------------------------------------------------------------------*/ void paintProgressBarGroove(QPainter *painter, const QStyleOptionProgressBar *option, const QWidget */*widget*/, const QStyle */*style*/) { painter->fillRect(option->rect.adjusted(2, 2, -2, -2), option->palette.brush(BG_ROLE_PROGRESS)); } #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintProgressBarLabel(QPainter *painter, const QStyleOptionProgressBarV2 *option, const QWidget *widget, const QStyle *style) #else void paintProgressBarLabel(QPainter *painter, const QStyleOptionProgressBar *option, const QWidget *widget, const QStyle *style) #endif { if (!option->textVisible || option->text.isEmpty()) { return; } Qt::Alignment alignment = option->textAlignment; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) const bool vertical = option->version >= 2 && option->orientation == Qt::Vertical; #else const bool vertical = false; #endif if (vertical) { if (!(alignment & (Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter))) { alignment |= Qt::AlignVCenter; } alignment &= ~(Qt::AlignLeft | Qt::AlignRight); alignment |= Qt::AlignHCenter; } else { if (!(alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter))) { alignment |= Qt::AlignHCenter; } alignment &= ~(Qt::AlignTop | Qt::AlignBottom); alignment |= Qt::AlignVCenter; } // FIXME currently forces centering if (true) { alignment &= ~(Qt::AlignLeft | Qt::AlignRight); alignment &= ~(Qt::AlignTop | Qt::AlignBottom); alignment |= Qt::AlignCenter; } const bool contentsCentered = progressBarContentsCentered(option, widget); const QRect contentsRect = progressBarContentsRect(option, contentsCentered); QTransform mat; if (vertical) { QPointF c = QRectF(option->rect).center(); mat.translate(c.x(), c.y()); mat.rotate(option->bottomToTop ? -90 : 90); mat.translate(-c.x(), -c.y()); } QRect r = mat.mapRect(option->rect).adjusted(6, 2, -6, -2); painter->save(); painter->setClipRegion(contentsRect); painter->setTransform(mat, true); style->drawItemText(painter, r, alignment, option->palette, true, option->text, FG_ROLE_CHUNK); painter->restore(); painter->save(); QRegion region = option->rect; region -= contentsRect; painter->setClipRegion(region); painter->setTransform(mat, true); style->drawItemText(painter, r, alignment, option->palette, option->state & QStyle::State_Enabled, option->text, FG_ROLE_PROGRESS); painter->restore(); } /*-----------------------------------------------------------------------*/ enum AnimationMode { NoAnimation, FloatAnimation, LiquidAnimation }; #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) static QColor progressBarFillColor(const QStyleOptionProgressBarV2 *option, const QWidget *widget) #else static QColor progressBarFillColor(const QStyleOptionProgressBar *option, const QWidget *widget) #endif { QColor fillColor = option->palette.color(BG_ROLE_CHUNK); if (isPasswordStrengthIndicator(widget)) { int p = option->minimum < option->maximum ? 100 * (option->progress - option->minimum) / (option->maximum - option->minimum) : 0; fillColor.setHsv(p * 85 / 100, 200, 240 - p); } else if (isDiskSpaceIndicator(widget)) { int p = option->minimum < option->maximum ? 100 * (option->progress - option->minimum) / (option->maximum - option->minimum) : 0; if (p < 75) p = 100; else p = (100 - p) * 4; fillColor.setHsv(p * 85 / 100, 200, 240 - p); } return fillColor; } #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintProgressBarContents(QPainter *painter, const QStyleOptionProgressBarV2 *option, const QWidget *widget, const QStyle *style) #else void paintProgressBarContents(QPainter *painter, const QStyleOptionProgressBar *option, const QWidget *widget, const QStyle *style) #endif { // configuration const bool busyIndicator = option->minimum == option->maximum; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) const bool vertical = option->version >= 2 && option->orientation == Qt::Vertical; #else const bool vertical = false; #endif const AnimationMode animationMode = busyIndicator ? FloatAnimation : vertical ? LiquidAnimation : FloatAnimation; const int chunkWidth = 4 * qMax(1, style->pixelMetric(QStyle::PM_ProgressBarChunkWidth, option, widget)); const bool reverseAnimation = busyIndicator; const int animationSpeed = (busyIndicator ? 1000 : 1000) * (reverseAnimation ? -1 : 1); const int floatAlpha = busyIndicator ? 100 : 255; const bool contentsCentered = progressBarContentsCentered(option, widget); const QRect contentsRect = progressBarContentsRect(option, contentsCentered); const int cornerSmoothing = 0; const int centerSmoothing = busyIndicator ? 100 : 0; const int borderSmoothing = 0; const bool contentsFrame = false; const int gradientSharpness = 0; const int gradientRatio = 50; const int gradientAngle = 0; // contents if (!contentsRect.isEmpty()) { QColor fillColor = progressBarFillColor(option, widget); qreal rounding = -1; if (!busyIndicator && option->progress < option->maximum) { rounding = contentsCentered ? 0.6 : 0.5; } switch (animationMode) { case NoAnimation: { painter->fillRect(contentsRect, fillColor); break; } case FloatAnimation: { QColor floatColor; if (option->palette.color(FG_ROLE_CHUNK).value() > fillColor.value()) { floatColor = fillColor.lighter(105); } else { floatColor = fillColor.darker(105); } floatColor.setAlpha(floatAlpha); int m = QTime(0, 0).msecsTo(QTime::currentTime()) / (animationSpeed / chunkWidth); QPoint startPoint = contentsCentered ? contentsRect.topLeft() : contentsRect.center(); startPoint += vertical ? QPoint(0, chunkWidth - 1 - m % chunkWidth) : QPoint(m % chunkWidth, 0); QLinearGradient fillGradient(startPoint, startPoint + (vertical ? QPoint(0, chunkWidth) : QPoint(chunkWidth, qRound(chunkWidth * sin(gradientAngle * M_PI / 180))))); fillGradient.setSpread(QGradient::RepeatSpread); const qreal delta = gradientRatio * gradientSharpness * 0.000049999; fillGradient.setColorAt(0.0, fillColor); fillGradient.setColorAt(0.0 + delta, fillColor); fillGradient.setColorAt(gradientRatio / 100.0 - delta, floatColor); fillGradient.setColorAt(gradientRatio / 100.0 + delta, floatColor); fillGradient.setColorAt(gradientRatio / 50.0 - delta, fillColor); fillGradient.setColorAt(1.0, fillColor); if (contentsCentered) { painter->save(); if (vertical) { painter->setClipRect(QRect(contentsRect.x(), contentsRect.y() + (contentsRect.height() >> 1), contentsRect.width(), contentsRect.height() - (contentsRect.height() >> 1))); } else { painter->setClipRect(QRect(contentsRect.x(), contentsRect.y(), contentsRect.width() >> 1, contentsRect.height())); } painter->translate(QRectF(contentsRect).center()); painter->scale(vertical ? 1 : -1, vertical ? -1 : 1); painter->translate(-QRectF(contentsRect).center()); painter->fillRect(contentsRect, fillGradient); painter->restore(); painter->save(); if (vertical) { painter->setClipRect(QRect(contentsRect.x(), contentsRect.y(), contentsRect.width(), contentsRect.height() >> 1)); } else { painter->setClipRect(QRect(contentsRect.x() + (contentsRect.width() >> 1), contentsRect.y(), contentsRect.width() - (contentsRect.width() >> 1), contentsRect.height())); } painter->fillRect(contentsRect, fillGradient); painter->restore(); } else { painter->fillRect(contentsRect, fillGradient); } if (contentsCentered && centerSmoothing > 0) { QColor centerColor = fillColor; const int contentsSize = vertical ? contentsRect.height() : contentsRect.width(); const int centerSize = qMin(3 * chunkWidth, contentsSize >> 1); const int delta = (contentsSize - centerSize) >> 1; const QRect centerRect = vertical ? contentsRect.adjusted(0, delta, 0, -delta) : contentsRect.adjusted(delta, 0, -delta, 0); QLinearGradient centerGradient(centerRect.topLeft(), vertical ? centerRect.bottomLeft() : centerRect.topRight()); // ### work around Qt 4.5 bug QColor transparentCenterColor = centerColor; transparentCenterColor.setAlpha(0); centerGradient.setColorAt(0.0, transparentCenterColor); centerGradient.setColorAt(0.4, centerColor); centerGradient.setColorAt(0.6, centerColor); centerGradient.setColorAt(1.0, transparentCenterColor); painter->fillRect(centerRect, centerGradient); } break; } case LiquidAnimation: { painter->fillRect(contentsRect, fillColor); if (rounding >= 0) { int m = QTime(0, 0).msecsTo(QTime::currentTime()); rounding = (sin(m / 100.0) + 1) / 2; } } } if (rounding >= 0) { QLinearGradient lineGradient(contentsRect.topLeft(), vertical ? contentsRect.topRight() : contentsRect.bottomLeft()); QColor innerColor = blend_color(option->palette.color(BG_ROLE_PROGRESS), fillColor, rounding); QColor outerColor = blend_color(fillColor, option->palette.color(BG_ROLE_PROGRESS), rounding); lineGradient.setColorAt(0.0, outerColor); lineGradient.setColorAt(0.5, innerColor); lineGradient.setColorAt(1.0, outerColor); if (contentsCentered || (option->version >= 2 && option->invertedAppearance)) { if (vertical) { painter->fillRect(QRect(contentsRect.x(), contentsRect.bottom(), contentsRect.width(), 1), lineGradient); } else { painter->fillRect(QRect(contentsRect.left(), contentsRect.y(), 1, contentsRect.height()), lineGradient); } } if (contentsCentered || !(option->version >= 2 && option->invertedAppearance)) { if (vertical) { painter->fillRect(QRect(contentsRect.x(), contentsRect.top(), contentsRect.width(), 1), lineGradient); } else { painter->fillRect(QRect(contentsRect.right(), contentsRect.y(), 1, contentsRect.height()), lineGradient); } } } if (cornerSmoothing > 0) { painter->save(); QColor color = option->palette.color(BG_ROLE_PROGRESS); color.setAlpha(cornerSmoothing); painter->setPen(color); painter->drawPoint(contentsRect.left(), contentsRect.top()); painter->drawPoint(contentsRect.left(), contentsRect.bottom()); painter->drawPoint(contentsRect.right(), contentsRect.top()); painter->drawPoint(contentsRect.right(), contentsRect.bottom()); painter->restore(); } if (borderSmoothing > 0) { painter->save(); QColor frameColor = option->palette.color(BG_ROLE_PROGRESS); frameColor.setAlpha(borderSmoothing); painter->setPen(frameColor); painter->drawRect(contentsRect.adjusted(0, 0, -1, -1)); painter->restore(); } if (contentsFrame) { paintThinFrame(painter, contentsRect, option->palette, -20, 60, BG_ROLE_CHUNK); } } // overlay gradient QLinearGradient glassyGradient(option->rect.topLeft(), vertical ? option->rect.topRight() : option->rect.bottomLeft()); glassyGradient.setColorAt(0.0, QColor(255, 255, 255, 0)); glassyGradient.setColorAt(0.47, QColor(0, 0, 0, 2)); glassyGradient.setColorAt(0.475, QColor(0, 0, 0, 21)); glassyGradient.setColorAt(1.0, QColor(255, 255, 255, 0)); painter->fillRect(option->rect.adjusted(2, 2, -2, -2), glassyGradient); paintRecessedFrame(painter, option->rect, option->palette, RF_Small); } /* * skulpture_scrollbar.cpp * */ #include "skulpture_p.h" #include #include #include #include /*-----------------------------------------------------------------------*/ extern void paintScrollArrow(QPainter *painter, const QStyleOption *option, Qt::ArrowType arrow, bool spin); void paintScrollArea(QPainter *painter, const QStyleOption *option) { QColor color = option->palette.color(QPalette::Disabled, QPalette::Window); if (option->state & QStyle::State_Enabled || option->type != QStyleOption::SO_Slider) { #if 0 if (option->state & QStyle::State_Sunken) { color = color.lighter(107); } else { color = color.darker(107); } #elif 0 color = option->palette.color(QPalette::Base); #elif 1 if (option->state & QStyle::State_Sunken) { color = color.darker(107); } else { // ### if (false && option->state & QStyle::State_MouseOver) { color = color.lighter(110); } else { color = color.lighter(107); } } #endif } painter->fillRect(option->rect, color); // painter->fillRect(option->rect, Qt::red); } void paintScrollAreaCorner(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle */*style*/) { QStyleOption opt; opt = *option; opt.type = QStyleOption::SO_Default; if (qobject_cast(widget)) { // ### work around bug in Qt 4.5 if (option->rect.y() + option->rect.height() > widget->rect().height() || option->rect.x() + option->rect.width() > widget->rect().width()) { return; } opt.type = QStyleOption::SO_Slider; opt.state &= ~QStyle::State_Enabled; if (widget->isEnabled()) { opt.state |= QStyle::State_Enabled; } } paintScrollArea(painter, &opt); } extern void paintSliderGroove(QPainter *painter, QRect &rect, const QStyleOptionSlider *option); void paintScrollBarPage(QPainter *painter, const QStyleOptionSlider *option, const QWidget */*widget*/, const QStyle */*style*/) { const bool paintGroove = true; paintScrollArea(painter, option); if (paintGroove) { QRect rect = option->rect.adjusted(1, 1, -1, -1); paintSliderGroove(painter, rect, option); } } void paintScrollBarAddLine(QPainter *painter, const QStyleOptionSlider *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArea(painter, option); // paintThinFrame(painter, option->rect, option->palette, -40, 120); if (option->minimum != option->maximum) { QStyleOptionSlider opt = *option; opt.fontMetrics = QApplication::fontMetrics(); opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::WindowText)); paintScrollArrow(painter, &opt, option->orientation == Qt::Horizontal ? (option->direction == Qt::LeftToRight ? Qt::RightArrow : Qt::LeftArrow) : Qt::DownArrow, false); } } void paintScrollBarSubLine(QPainter *painter, const QStyleOptionSlider *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArea(painter, option); // paintThinFrame(painter, option->rect, option->palette, -40, 120); if (option->minimum != option->maximum) { QStyleOptionSlider opt = *option; opt.fontMetrics = QApplication::fontMetrics(); opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::WindowText)); paintScrollArrow(painter, &opt, option->orientation == Qt::Horizontal ? (option->direction == Qt::LeftToRight ? Qt::LeftArrow : Qt::RightArrow) : Qt::UpArrow, false); } } void paintScrollBarFirst(QPainter *painter, const QStyleOptionSlider *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollBarSubLine(painter, option, 0, 0); if (option->minimum != option->maximum) { painter->fillRect(option->rect.adjusted(2, 2, -2, -2), option->palette.color(QPalette::WindowText)); } } void paintScrollBarLast(QPainter *painter, const QStyleOptionSlider *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollBarAddLine(painter, option, 0, 0); if (option->minimum != option->maximum) { painter->fillRect(option->rect.adjusted(2, 2, -2, -2), option->palette.color(QPalette::WindowText)); } } /*-----------------------------------------------------------------------*/ class ComplexControlLayout { public: struct SubControlItem { QStyle::SubControl subControl; QStyle::ControlElement controlElement; char layoutSpec; }; protected: ComplexControlLayout(const SubControlItem *controlItem, uint controlCount, const QStyleOptionComplex *opt, const QWidget *w = 0, const QStyle *s = 0) : subControlItem(controlItem), subControlCount(controlCount), option(opt), widget(w), style(s), layoutCount(0) { /* */ } ~ComplexControlLayout() { } public: QStyle::SubControl hitTestComplexControl(const QPoint &position) const; QRect subControlRect(QStyle::SubControl subControl) const; void paintComplexControl(QPainter *painter) const; protected: struct LayoutItem { QStyle::SubControl subControl; QRect rect; }; protected: void addLayoutItem(QStyle::SubControl subControl, const QRect &rect); protected: static const uint maxLayoutCount = 16; protected: const SubControlItem * const subControlItem; const uint subControlCount; const QStyleOptionComplex * const option; const QWidget * const widget; const QStyle * const style; uint layoutCount; LayoutItem layoutItem[maxLayoutCount]; }; /*-----------------------------------------------------------------------*/ void ComplexControlLayout::addLayoutItem(QStyle::SubControl subControl, const QRect &rect) { if (layoutCount < maxLayoutCount) { layoutItem[layoutCount].subControl = subControl; layoutItem[layoutCount].rect = style->visualRect(option->direction, option->rect, rect); ++layoutCount; } } QStyle::SubControl ComplexControlLayout::hitTestComplexControl(const QPoint &position) const { for (uint i = 0; i < subControlCount; ++i) { for (uint j = 0; j < layoutCount; ++j) { if (layoutItem[j].subControl == subControlItem[i].subControl) { if (layoutItem[j].rect.contains(position)) { return layoutItem[j].subControl; } } } } return QStyle::SC_None; } QRect ComplexControlLayout::subControlRect(QStyle::SubControl subControl) const { QRect rect; for (uint i = 0; i < layoutCount; ++i) { if (layoutItem[i].subControl == subControl) { rect |= layoutItem[i].rect; } } return rect; } void ComplexControlLayout::paintComplexControl(QPainter *painter) const { for (int i = subControlCount; --i >= 0; ) { if (subControlItem[i].controlElement != QStyle::CE_CustomBase && option->subControls & subControlItem[i].subControl) { for (uint j = 0; j < layoutCount; ++j) { if (layoutItem[j].subControl == subControlItem[i].subControl) { QStyleOptionSlider opt = *static_cast(ComplexControlLayout::option); opt.rect = layoutItem[j].rect; if (!(option->activeSubControls & subControlItem[i].subControl)) { opt.state &= ~(QStyle::State_Sunken | QStyle::State_MouseOver); } style->drawControl(subControlItem[i].controlElement, &opt, painter, widget); } } } } } /*-----------------------------------------------------------------------*/ static const ComplexControlLayout::SubControlItem scrollBarSubControlItem[] = { /* hitTest in forward order, paint in reverse order */ { QStyle::SC_ScrollBarSlider, QStyle::CE_ScrollBarSlider, '*' }, { QStyle::SC_ScrollBarAddLine, QStyle::CE_ScrollBarAddLine, '>' }, { QStyle::SC_ScrollBarSubLine, QStyle::CE_ScrollBarSubLine, '<' }, { QStyle::SC_ScrollBarFirst, QStyle::CE_ScrollBarFirst, '[' }, { QStyle::SC_ScrollBarLast, QStyle::CE_ScrollBarLast, ']' }, { QStyle::SC_ScrollBarAddPage, QStyle::CE_ScrollBarAddPage, ')' }, { QStyle::SC_ScrollBarSubPage, QStyle::CE_ScrollBarSubPage, '(' }, { QStyle::SC_ScrollBarGroove, QStyle::CE_CustomBase, '#' } }; class ScrollBarLayout : public ComplexControlLayout { public: ScrollBarLayout(const QStyleOptionSlider *opt, const QWidget *w = 0, const QStyle *s = 0) : ComplexControlLayout(scrollBarSubControlItem, array_elements(scrollBarSubControlItem), opt, w, s) { /* */ } ~ScrollBarLayout() { } public: void initLayout(const char *layoutSpec); void initLayout(ArrowPlacementMode placementMode); protected: void addLayoutItem(const char layoutSpec, int pos, int size); }; /*-----------------------------------------------------------------------*/ void ScrollBarLayout::addLayoutItem(char c, int pos, int size) { const QStyleOptionSlider *option = static_cast(ComplexControlLayout::option); if (size > 0) { for (uint i = 0; i < subControlCount; ++i) { if (subControlItem[i].layoutSpec == c) { QRect rect; if (option->orientation == Qt::Horizontal) { rect = QRect(option->rect.left() + pos, option->rect.top(), size, option->rect.height()); } else { rect = QRect(option->rect.left(), option->rect.top() + pos, option->rect.width(), size); } ComplexControlLayout::addLayoutItem(subControlItem[i].subControl, rect); return; } } } } void ScrollBarLayout::initLayout(ArrowPlacementMode placementMode) { static const char *layoutSpec[] = { "(*)", // NoArrowsMode "(<*>)", // SkulptureMode "<(*)>", // WindowsMode "<(*)<>", // KDEMode "(*)<>", // PlatinumMode "<>(*)" // NextMode }; initLayout(layoutSpec[uint(placementMode)]); } void ScrollBarLayout::initLayout(const char *layoutSpec) { const QStyleOptionSlider *option = static_cast(ComplexControlLayout::option); uint range = option->maximum - option->minimum; int pos = option->orientation == Qt::Horizontal ? option->rect.left() : option->rect.top(); int maxSize = option->orientation == Qt::Horizontal ? option->rect.width() : option->rect.height(); int endPos = pos + maxSize; int groovePos = pos, grooveSize = maxSize; int pagePos = pos, pageSize = maxSize; int buttonSize = style->pixelMetric(QStyle::PM_ScrollBarExtent, option, widget); buttonSize = qMin(maxSize >> 1, buttonSize); if (qstrcmp(layoutSpec, "(*)")) { if (!qstrcmp(layoutSpec, "<(*)<>")) { if (maxSize < 4 * buttonSize) { layoutSpec = "<(*)>"; } } if (maxSize < 3 * buttonSize) { layoutSpec = "(<*>)"; } } if (layoutSpec && range != 0) { // layout items before slider const char *p = layoutSpec; char c; while ((c = *p)) { if (c == '*') { pagePos = pos; break; } else if (c == '(') { groovePos = pos; } else { addLayoutItem(c, pos, buttonSize); pos += buttonSize; } ++p; } // layout items after slider while (*p) { ++p; } --p; pos = endPos; while (p >= layoutSpec) { c = *p; if (c == '*') { pageSize = pos - pagePos; break; } else if (c == ')') { grooveSize = pos - groovePos; } else { pos -= buttonSize; addLayoutItem(c, pos, buttonSize); } --p; } } if (layoutCount > maxLayoutCount - 4) { layoutCount = maxLayoutCount - 4; } if (range != 0) { int sliderSize = (qint64(option->pageStep) * grooveSize) / (range + option->pageStep); int sliderMin = style->pixelMetric(QStyle::PM_ScrollBarSliderMin, option, widget); if (sliderMin > grooveSize >> 1) { sliderMin = grooveSize >> 1; if (sliderSize > sliderMin) { sliderSize = sliderMin; } } if (sliderSize < sliderMin || range > INT_MAX / 2) { sliderSize = sliderMin; } if (grooveSize != pageSize) { if (sliderSize > grooveSize - buttonSize) { sliderSize = grooveSize - buttonSize; } } int sliderPos = groovePos + style->sliderPositionFromValue(option->minimum, option->maximum, option->sliderPosition, grooveSize - sliderSize, option->upsideDown); addLayoutItem('(', pagePos, sliderPos - pagePos); addLayoutItem(')', sliderPos + sliderSize, (pagePos + pageSize) - (sliderPos + sliderSize)); addLayoutItem('*', sliderPos, sliderSize); } else { addLayoutItem('*', groovePos, grooveSize); } addLayoutItem('#', groovePos, grooveSize); } /*-----------------------------------------------------------------------*/ extern void paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole bgrole = QPalette::Window); extern void paintSliderHandle(QPainter *painter, const QRect &rect, const QStyleOptionSlider *option); void paintScrollBarSlider(QPainter *painter, const QStyleOptionSlider *option, const QWidget */*widget*/, const QStyle */*style*/) { if (option->minimum == option->maximum) { paintScrollArea(painter, option); } else { paintSliderHandle(painter, option->rect, option); } } /*-----------------------------------------------------------------------*/ void paintScrollBar(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style, ArrowPlacementMode horizontalArrowMode, ArrowPlacementMode verticalArrowMode) { // paint scrollbar ScrollBarLayout layout(option, widget, style); layout.initLayout(option->orientation == Qt::Horizontal ? horizontalArrowMode : verticalArrowMode); layout.paintComplexControl(painter); // get frame this scrollbar is in QFrame *frame = 0; if (widget && widget->parentWidget()) { QWidget *container = widget->parentWidget(); if (container->inherits("Q3ListView")) { if (option->orientation == Qt::Vertical) { frame = qobject_cast(container); } } else if (container->inherits("Q3Table")) { frame = qobject_cast(container); } else if (container->parentWidget()) { frame = qobject_cast(container->parentWidget()); } } // paint shadow if (frame && frame->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken)) { QRect rect = option->rect; if (option->orientation == Qt::Vertical) { if (option->direction == Qt::LeftToRight) { rect.adjust(-3, 0, 1, 0); } else { rect.adjust(-1, 0, 2, 0); } // ### temporary hack to detect corner widget if (widget->height() == frame->height() - 4) { rect.adjust(0, -1, 0, 1); } else { rect.adjust(0, -1, 0, 4); } } else { rect.adjust(0, -3, 0, 1); // ### temporary hack to detect corner widget if (widget->width() == frame->width() - 4) { rect.adjust(-1, 0, 1, 0); } else { if (option->direction == Qt::LeftToRight) { rect.adjust(-1, 0, 4, 0); } else { rect.adjust(-4, 0, 1, 0); } } } paintRecessedFrameShadow(painter, rect.adjusted(1, 1, -1, -1), RF_Small); } } QRect subControlRectScrollBar(const QStyleOptionSlider *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style, ArrowPlacementMode horizontalArrowMode, ArrowPlacementMode verticalArrowMode) { ScrollBarLayout layout(option, widget, style); layout.initLayout(option->orientation == Qt::Horizontal ? horizontalArrowMode : verticalArrowMode); return layout.subControlRect(subControl); } QStyle::SubControl hitTestComplexControlScrollBar(const QStyleOptionSlider *option, const QPoint &position, const QWidget *widget, const QStyle *style, ArrowPlacementMode horizontalArrowMode, ArrowPlacementMode verticalArrowMode) { ScrollBarLayout layout(option, widget, style); layout.initLayout(option->orientation == Qt::Horizontal ? horizontalArrowMode : verticalArrowMode); return layout.hitTestComplexControl(position); } /* * skulpture_shadows.cpp * */ #include "skulpture_p.h" #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) #include #endif #include #include #include #include /*-----------------------------------------------------------------------*/ /** * FrameShadow - overlay a shadow inside a frame * * This class is used to give the impression of sunken * frames that cast shadows over the contents inside. * * To create the shadow, call installFrameShadow() * on the sunken QFrame that you want the shadow * to be added to. * * Side-effects: * * Adds transparent widgets to the frame, which may * affect performance. * */ FrameShadow::FrameShadow(QWidget *parent) : QWidget(parent) { init(); } FrameShadow::FrameShadow(ShadowArea area, QWidget *parent) : QWidget(parent) { init(); area_ = area; } FrameShadow::~FrameShadow() { /* */ } /*-----------------------------------------------------------------------*/ void SkulptureStyle::Private::installFrameShadow(QWidget *widget) { // printf("adding shadow to %s\n", widget->metaObject()->className()); widget->installEventFilter(this); removeFrameShadow(widget); for (int i = 0; i < 4; ++i) { FrameShadow *shadow = new FrameShadow(FrameShadow::ShadowArea(i)); shadow->hide(); shadow->setParent(widget); shadow->updateGeometry(); shadow->show(); } } void SkulptureStyle::Private::removeFrameShadow(QWidget *widget) { const QList shadows = widget->children(); Q_FOREACH (QObject *child, shadows) { FrameShadow *shadow; if ((shadow = qobject_cast(child))) { shadow->hide(); shadow->setParent(0); shadow->deleteLater(); } } } void SkulptureStyle::Private::updateFrameShadow(QWidget *widget) { const QList shadows = widget->children(); Q_FOREACH (QObject *child, shadows) { FrameShadow *shadow; if ((shadow = qobject_cast(child))) { if (shadow->isVisible()) { shadow->updateGeometry(); } } } } /*-----------------------------------------------------------------------*/ #define SHADOW_SIZE_TOP 4 #define SHADOW_SIZE_BOTTOM 2 #define SHADOW_SIZE_LEFT 4 #define SHADOW_SIZE_RIGHT 4 void FrameShadow::updateGeometry() { QWidget *widget = parentWidget(); QRect cr = widget->contentsRect(); // printf("cr-top: %d in class %s\n", cr.top(), widget->metaObject()->className()); switch (shadowArea()) { case FrameShadow::Top: cr.setHeight(SHADOW_SIZE_TOP); break; case FrameShadow::Left: cr.setWidth(SHADOW_SIZE_LEFT); cr.adjust(0, SHADOW_SIZE_TOP, 0, -SHADOW_SIZE_BOTTOM); break; case FrameShadow::Bottom: cr.setTop(cr.bottom() - SHADOW_SIZE_BOTTOM + 1); break; case FrameShadow::Right: cr.setLeft(cr.right() - SHADOW_SIZE_RIGHT + 1); cr.adjust(0, SHADOW_SIZE_TOP, 0, -SHADOW_SIZE_BOTTOM); break; } setGeometry(cr); } /*-----------------------------------------------------------------------*/ bool FrameShadow::event(QEvent *e) { if (e->type() == QEvent::Paint) { return QWidget::event(e); } QWidget *viewport = 0; if (parentWidget()) { if (QAbstractScrollArea *widget = qobject_cast(parentWidget())) { viewport = widget->viewport(); } else if (parentWidget()->inherits("Q3ScrollView")) { // FIXME: get viewport? needs Qt3Support linkage! viewport = 0; } else { viewport = 0; } } if (!viewport) { return false; } #if 1 switch (e->type()) { case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave: case QEvent::Drop: { setAcceptDrops(viewport->acceptDrops()); QObject *o = viewport; return o->event(e); } break; case QEvent::Enter: setCursor(viewport->cursor()); setAcceptDrops(viewport->acceptDrops()); break; case QEvent::ContextMenu: { QContextMenuEvent *me = reinterpret_cast(e); QContextMenuEvent *ne = new QContextMenuEvent(me->reason(), parentWidget()->mapFromGlobal(me->globalPos()), me->globalPos()); QApplication::sendEvent(viewport, ne); e->accept(); return true; } break; case QEvent::MouseButtonPress: releaseMouse(); // Fall thru... case QEvent::MouseMove: case QEvent::MouseButtonRelease: { QMouseEvent *me = reinterpret_cast(e); QMouseEvent *ne = new QMouseEvent(e->type(), parentWidget()->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers()); QApplication::sendEvent(viewport, ne); e->accept(); return true; } break; case QEvent::Paint: return QWidget::event(e); default: break; } e->ignore(); return false; #else return QWidget::event(e); #endif } /*-----------------------------------------------------------------------*/ void FrameShadow::paintEvent(QPaintEvent *) { // this fixes shadows in frames that change frameStyle() after polish() if (QFrame *frame = qobject_cast(parentWidget())) { if (frame->frameStyle() != (QFrame::StyledPanel | QFrame::Sunken)) { return; } } QPainter painter(this); QWidget *parent = parentWidget(); QRect r = parent->contentsRect(); r.translate(mapFromParent(QPoint(0, 0))); // painter.fillRect(QRect(-100, -100, 1000, 1000), Qt::red); paintRecessedFrameShadow(&painter, r, RF_Large); } /*-----------------------------------------------------------------------*/ void FrameShadow::init() { // setAttribute(Qt::WA_NoSystemBackground, true); // setAttribute(Qt::WA_NoBackground, true); setAttribute(Qt::WA_OpaquePaintEvent, false); setFocusPolicy(Qt::NoFocus); // TODO: check if this is private setAttribute(Qt::WA_TransparentForMouseEvents, true); setContextMenuPolicy(Qt::NoContextMenu); QWidget *viewport; if (parentWidget()) { if (QAbstractScrollArea *widget = qobject_cast(parentWidget())) { setAcceptDrops(true); viewport = widget->viewport(); } else if (parentWidget()->inherits("Q3ScrollView")) { // FIXME: get viewport? needs Qt3Support linkage! viewport = parentWidget(); } else { viewport = 0; } if (viewport) { setCursor(viewport->cursor()); } } } /*-----------------------------------------------------------------------*/ void paintRecessedFrameShadow(QPainter *painter, const QRect &rect, enum RecessedFrame rf) { if (rf == RF_None) return; #if 1 int c1 = (rf == RF_Small) ? 10 : 10; int c2 = (rf == RF_Small) ? 24 : 36; #else int c1 = 0; int c2 = 0; #endif #if 0 c1 += c1 >> 1; c2 += c2 >> 1; int intensityTop = c2; int intensityLeft = c2; int intensityBottom = c1; int intensityRight = c1; #endif QRect r = rect; while (c1 > 3 || c2 > 3) { QBrush brush1(QColor(0, 0, 0, c1)); QBrush brush2(QColor(0, 0, 0, c2)); painter->fillRect(QRect(rect.left(), r.top(), rect.width(), 1), brush2); painter->fillRect(QRect(r.left(), rect.top(), 1, rect.height()), brush2); painter->fillRect(QRect(rect.left(), r.bottom(), rect.width(), 1), brush1); painter->fillRect(QRect(r.right(), rect.top(), 1, rect.height()), brush1); c1 >>= 1; c2 >>= 1; // c1 = int(c1 * 0.7); c2 = int(c2 * 0.7); r.adjust(1, 1, -1, -1); } } /*-----------------------------------------------------------------------*/ /** * WidgetShadow - add a drop shadow to a widget * * This class renders a shadow below a widget, such * as a QMdiSubWindow. * */ WidgetShadow::WidgetShadow(QWidget *parent) : QWidget(parent) { init(); } /*-----------------------------------------------------------------------*/ void WidgetShadow::init() { setObjectName(QLatin1String("WidgetShadow")); // setAttribute(Qt::WA_NoSystemBackground, true); // setAttribute(Qt::WA_NoBackground, true); setAttribute(Qt::WA_OpaquePaintEvent, false); // setAutoFillBackground(false); setFocusPolicy(Qt::NoFocus); // TODO: check if this is private setAttribute(Qt::WA_TransparentForMouseEvents, true); // setContextMenuPolicy(Qt::NoContextMenu); widget_ = 0; } /*-----------------------------------------------------------------------*/ bool WidgetShadow::event(QEvent *e) { switch (e->type()) { case QEvent::Paint: if (widget_) { QRect r(- 10, - 5, widget_->frameGeometry().width() + 20, widget_->frameGeometry().height() + 15); r.translate(qMin(widget_->x(), 10), qMin(widget_->y(), 5)); QPainter p(this); QRegion region(r); region -= QRect(r.adjusted(10, 5, -10, -10)); p.setClipRegion(region); #if 0 for (int i = 0; i < 10; ++i) { int k = 9 - i; p.fillRect(r.adjusted(k, i, -k, -i), QColor(0, 0, 0, i)); p.fillRect(r.adjusted(i, k, -i, -k), QColor(0, 0, 0, i)); } #else for (int i = 0; i < 10; ++i) { p.fillRect(r, QColor(0, 0, 0, 2 + i)); r.adjust(1, 1, -1, -1); } #endif e->ignore(); return (true); } default: break; } return QWidget::event(e); } void WidgetShadow::updateGeometry() { if (widget_) { if (widget_->isHidden()) { hide(); } else { QWidget *parent = parentWidget(); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (parent && !qobject_cast(parent) && qobject_cast(parent->parentWidget())) { parent = parent->parentWidget(); } #endif if (parent) { QRect geo(widget_->x() - 10, widget_->y() - 5, widget_->frameGeometry().width() + 20, widget_->frameGeometry().height() + 15); setGeometry(geo & parent->rect()); } show(); } } } void WidgetShadow::updateZOrder() { if (widget_) { if (widget_->isHidden()) { hide(); } else { stackUnder(widget_); QWidget *parent = parentWidget(); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (parent && !qobject_cast(parent) && qobject_cast(parent->parentWidget())) { parent = parent->parentWidget(); } #endif if (parent) { QRect geo(widget_->x() - 10, widget_->y() - 5, widget_->frameGeometry().width() + 20, widget_->frameGeometry().height() + 15); setGeometry(geo & parent->rect()); } show(); } } } /* * skulpture_shapes.cpp * */ #include "skulpture_p.h" #include "sk_factory.h" /*-----------------------------------------------------------------------*/ /** * ShapeFactory - create a QPainterPath from a description * * The shape description is a bytecode stream that allows simple arithmetic, * conditionals, and looping. * * Syntax is as follows: * Description: Instruction* End * Instruction: Close | Move X Y | Line X Y | Quad X1 Y1 X2 Y2 | Cubic X1 Y1 X2 Y2 X3 Y3 * Instruction: Nop | SetVar X | Begin Instruction* End | While Condition Instruction | If Condition Instruction1 [ Else Instruction2 ] * Condition: Not Condition | And Condition1 Condition2 | Or Condition1 Condition2 | EQ X Y | NE X Y | LT X Y | GE X Y | GT X Y | LE X Y * Expression: Number | GetVar | Add X Y | Sub X Y | Mul X Y | Div X Y | Min X Y | Max X Y | Mix V X Y | Cond Condition X Y * * TODO * * Mod, MultiLine, DoWhile, Integer/Float, Switch, Exp, Sin, Cos, Tan, Atan, Atan2, Pi * Colors, Gradients, Functions (Call/Ret), Frames, Text * */ /*-----------------------------------------------------------------------*/ void ShapeFactory::executeCode(Code code) { qreal v[6]; switch (code) { case Move: case Line: v[0] = evalValue(); v[1] = evalValue(); if (code == Move) { path.moveTo(v[0], v[1]); } else { path.lineTo(v[0], v[1]); } break; case Close: path.closeSubpath(); break; case Quad: case Cubic: { for (int n = 0; n < (code == Quad ? 4 : 6); ++n) { v[n] = evalValue(); } if (code == Quad) { path.quadTo(v[0], v[1], v[2], v[3]); } else { path.cubicTo(v[0], v[1], v[2], v[3], v[4], v[5]); } break; } default: AbstractFactory::executeCode(code); break; } } void ShapeFactory::skipCode(Code code) { switch (code) { case Move: case Line: skipValue(); skipValue(); break; case Close: break; case Quad: case Cubic: { for (int n = 0; n < (code == Quad ? 4 : 6); ++n) { skipValue(); } break; } default: AbstractFactory::skipCode(code); break; } } /*-----------------------------------------------------------------------*/ QPainterPath ShapeFactory::createShape(ShapeFactory::Description description, qreal var[]) { ShapeFactory factory; factory.setDescription(description); for (int n = MinVar; n <= MaxVar; ++n) { factory.setVar(n, var[n]); } factory.create(); for (int n = MinVar; n <= MaxVar; ++n) { var[n] = factory.getVar(n); } return factory.getPath(); } QPainterPath ShapeFactory::createShape(ShapeFactory::Description description) { ShapeFactory factory; factory.setDescription(description); factory.create(); return factory.getPath(); } /* * skulpture_shortcuts.cpp * */ #include "skulpture_p.h" #include #include #include #include #include #include #include #include #include #include #include /*-----------------------------------------------------------------------*/ /** * Class to manage the applications keyboard shortcuts * * It acts as an eventfilter for the application, and does the following: * * * the shortcuts are only underlined when the Alt key is pressed, and * the underline is removed once it is released. * * on many widgets the focus frame is not displayed if the focus was * received using the mouse. It is, however, still displayed if * you use the Tab key. * * Additionally, this class is responsible for blanking the mouse pointer: * * * when the tablet pen leaves proximity * * Any other keyboard shortcut and focus issues should also be handled here. * */ /*-----------------------------------------------------------------------*/ bool ShortcutHandler::underlineShortcut(const QWidget *widget) const { if (widget && widget->isEnabled()) { if (alt_pressed.contains(widget->window())) { return true; } if (qobject_cast(widget)) { if (widget->hasFocus()) { return true; } QList children = widget->findChildren(); Q_FOREACH (QWidget *child, children) { if (child->hasFocus()) { return true; } } } if (qobject_cast(widget)) { return true; } } return false; } static inline bool hasShortcut(QWidget *widget) { if (qobject_cast(widget) // && (qobject_cast(widget))->text.contains(QChar('&', 0)) || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) // || qobject_cast(widget) || qobject_cast(widget) || qobject_cast(widget) // && (qobject_cast(widget))->isCheckable() || qobject_cast(widget)) { return true; } return false; } static inline void updateShortcuts(QWidget *widget) { QList children = widget->findChildren(); Q_FOREACH (QWidget *child, children) { if (child->isVisible() && hasShortcut(child)) { child->update(); } } } bool ShortcutHandler::eventFilter(QObject *watched, QEvent *event) { if (!watched->isWidgetType()) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) switch (event->type()) { case QEvent::TabletEnterProximity: if (tabletCursorState != TabletCursor) { if (tabletCursorState != DefaultCursor) { QApplication::restoreOverrideCursor(); } tabletCursorState = DefaultCursor; } break; case QEvent::TabletLeaveProximity: if (tabletCursorState != BlankCursor) { if (tabletCursorState != DefaultCursor) { QApplication::restoreOverrideCursor(); } QApplication::setOverrideCursor(Qt::BlankCursor); tabletCursorState = BlankCursor; } break; default: break; } #endif return QObject::eventFilter(watched, event); } QWidget *widget = reinterpret_cast(watched); switch (event->type()) { case QEvent::MouseMove: if (tabletCursorState != DefaultCursor) { QApplication::restoreOverrideCursor(); tabletCursorState = DefaultCursor; } break; case QEvent::FocusIn: { Qt::FocusReason reason = ((QFocusEvent *) event)->reason(); if (reason != Qt::TabFocusReason && reason != Qt::BacktabFocusReason) { QWidget *window = widget->window(); window->setAttribute(Qt::WA_KeyboardFocusChange, false); } } break; case QEvent::KeyPress: if (((QKeyEvent *) event)->key() == Qt::Key_Alt) { QWidget *window = widget->window(); if (!alt_pressed.contains(window)) { alt_pressed.append(window); window->installEventFilter(this); updateShortcuts(window); } } break; case QEvent::Close: if (widget->isWindow()) { alt_pressed.removeAll(widget); widget->removeEventFilter(this); } break; case QEvent::WindowDeactivate: if (widget->isWindow()) { alt_pressed.removeAll(widget); widget->removeEventFilter(this); updateShortcuts(widget); } break; case QEvent::KeyRelease: if (((QKeyEvent *) event)->key() == Qt::Key_Alt) { QWidget *window = widget->window(); if (alt_pressed.contains(window)) { alt_pressed.removeAll(window); window->removeEventFilter(this); updateShortcuts(window); } } break; default: break; } return QObject::eventFilter(watched, event); } /*-----------------------------------------------------------------------*/ ShortcutHandler::ShortcutHandler(QObject *parent) : QObject(parent), tabletCursorState(DefaultCursor) { init(); } ShortcutHandler::~ShortcutHandler() { if (tabletCursorState != DefaultCursor) { tabletCursorState = DefaultCursor; QApplication::restoreOverrideCursor(); } } /* * skulpture_slider.cpp * */ #include "skulpture_p.h" #include #include /*-----------------------------------------------------------------------*/ void paintSliderGroove(QPainter *painter, QRect &rect, const QStyleOptionSlider *option) { if (option->orientation == Qt::Horizontal) { int d = rect.height() / 2; rect.adjust(0, d, 0, -d); } else { int d = rect.width() / 2; rect.adjust(d, 0, -d, 0); } QColor color = option->palette.color(QPalette::Window); if (option->state & QStyle::State_Enabled) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) color = color.darker(120); #else color = color.dark(120); #endif painter->fillRect(rect, color); paintThinFrame(painter, rect.adjusted(-1, -1, 1, 1), option->palette, -30, -90); } else { painter->fillRect(rect, color); paintThinFrame(painter, rect.adjusted(-1, -1, 1, 1), option->palette, -20, -60); } } void paintSliderHandle(QPainter *painter, const QRect &rect, const QStyleOptionSlider *option) { // shadow painter->fillRect(rect.adjusted(2, 2, 2, 2), QColor(0, 0, 0, 5)); painter->fillRect(rect.adjusted(1, 1, 1, 1), QColor(0, 0, 0, 8)); // slider color QColor color = option->palette.color(QPalette::Button); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_Sunken) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) color = color.lighter(102); #else color = color.light(102); #endif } else if (option->state & QStyle::State_MouseOver) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) color = color.lighter(104); #else color = color.light(104); #endif } } else { color = option->palette.color(QPalette::Window); } painter->fillRect(rect, color); #if 1 // slider gradient if ((option->state & QStyle::State_Enabled) && !(option->state & QStyle::State_Sunken)) { QLinearGradient gradient(rect.topLeft(), option->orientation == Qt::Horizontal ? rect.bottomLeft() : rect.topRight()); #if 1 // SkandaleStyle 0.0.2 gradient.setColorAt(0.0, shaded_color(color, 40)); gradient.setColorAt(0.5, shaded_color(color, 0)); gradient.setColorAt(1.0, shaded_color(color, 70)); #else // glassy gradient.setColorAt(0.0, shaded_color(color, 40)); gradient.setColorAt(0.4, shaded_color(color, -5)); gradient.setColorAt(0.405, shaded_color(color, -15)); gradient.setColorAt(1.0, shaded_color(color, 70)); #endif painter->fillRect(rect, gradient); } #endif // slider frame paintThinFrame(painter, rect, option->palette, -70, -20, QPalette::Button); paintThinFrame(painter, rect.adjusted(1, 1, -1, -1), option->palette, -30, 130, QPalette::Button); } /*-----------------------------------------------------------------------*/ void paintSlider(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style) { // groove if (option->subControls & QStyle::SC_SliderGroove) { // painter->fillRect(option->rect, option->palette.color(QPalette::Window).darker(105)); // paintThinFrame(painter, option->rect, option->palette, 130, -30); #if 0 int handlesize = style->pixelMetric(QStyle::PM_SliderLength, option, widget); int e = handlesize / 2 - 1; #else int e = 1; #endif #if 0 QRect rect = option->rect; // QRect rect = style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderGroove, widget); if (option->orientation == Qt::Horizontal) { rect.adjust(e, 0, -e, 0); } else { rect.adjust(0, e, 0, -e); } paintSliderGroove(painter, rect, option); #else QRect rect = style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderGroove, widget); //QRect rect = option->rect; QRect handle_rect = style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderHandle, widget); QStyleOptionSlider aOption = *option; aOption.palette.setColor(QPalette::Window, aOption.palette.color(QPalette::Highlight)); if (option->orientation == Qt::Horizontal) { handle_rect.adjust(0, 2, 0, -2); rect.adjust(e, 0, -e, 0); rect.setWidth(handle_rect.left() - rect.left() - 1); if (rect.width() > -3) { paintSliderGroove(painter, rect, option->upsideDown ? option : &aOption); } rect.setLeft(handle_rect.right() + 2); rect.setWidth(option->rect.right() - handle_rect.right() - 1 - e); if (rect.width() > -3) { paintSliderGroove(painter, rect, option->upsideDown ? &aOption : option); } } else { handle_rect.adjust(2, 0, -2, 0); rect.adjust(0, e, 0, -e); rect.setHeight(handle_rect.top() - rect.top() - 1); if (rect.height() > -3) { paintSliderGroove(painter, rect, option->upsideDown ? option : &aOption); } rect.setTop(handle_rect.bottom() + 2); rect.setHeight(option->rect.bottom() - handle_rect.bottom() - e); if (rect.height() > -3) { paintSliderGroove(painter, rect, option->upsideDown ? &aOption : option); } } #endif } #if 1 // tickmarks if (option->subControls & QStyle::SC_SliderTickmarks) { QStyleOptionSlider slider = *option; slider.subControls = QStyle::SC_SliderTickmarks; // ### for now, just use common tickmarks QPalette palette = slider.palette; QColor col = palette.color(QPalette::WindowText); col.setAlpha(51); palette.setColor(QPalette::WindowText, col); slider.palette = palette; if (option->orientation == Qt::Horizontal) { slider.rect.adjust(-1, 0, -1, 0); } else { slider.rect.adjust(0, -1, 0, -1); } ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_Slider, &slider, painter, widget); slider.rect = option->rect; palette.setColor(QPalette::WindowText, QColor(255, 255, 255, 77)); slider.palette = palette; ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_Slider, &slider, painter, widget); } #endif // focus rect if (option->state & QStyle::State_HasFocus) { QStyleOptionFocusRect focus; focus.QStyleOption::operator=(*option); focus.rect = style->subElementRect(QStyle::SE_SliderFocusRect, option, widget); focus.state |= QStyle::State_FocusAtBorder; style->drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget); } // handle if (option->subControls & QStyle::SC_SliderHandle) { QStyleOptionSlider aOption = *option; if (!(option->activeSubControls & QStyle::SC_SliderHandle)) { aOption.state &= ~QStyle::State_MouseOver; aOption.state &= ~QStyle::State_Sunken; } QRect rect = style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderHandle, widget); if (option->orientation == Qt::Horizontal) { rect.adjust(0, 2, 0, -2); } else { rect.adjust(2, 0, -2, 0); } #if 0 if (option->orientation == Qt::Horizontal) { rect.setTop(option->rect.top()); rect.setHeight(option->rect.height()); // rect.adjust(0, 1, 0, -1); } else { rect.setLeft(option->rect.left()); rect.setWidth(option->rect.width()); // rect.adjust(1, 0, -1, 0); } #endif // rect.adjust(0, 0, -1, -1); paintSliderHandle(painter, rect, &aOption); // rect.adjust(0, 0, 1, 1); // paintThinFrame(painter, rect.adjusted(1, 1, 1, 1), option->palette, -20, 0); #if 0 // grip const int o = 5; const int s = 6; if (option->orientation == Qt::Horizontal) { int d = (rect.width() - 2) / 2; rect.adjust(d, 0, -d, 0); rect.translate(-s, 0); } else { int d = (rect.height() - 2) / 2; rect.adjust(0, d, 0, -d); rect.translate(0, -s); } for (int k = -1; k < 2; ++k) { if (option->orientation == Qt::Horizontal) { painter->fillRect(rect.adjusted(0, o, 0, -o), QColor(0, 0, 0, 30)); painter->fillRect(rect.adjusted(1, o, 1, -o), QColor(255, 255, 255, 80)); rect.translate(s, 0); } else { painter->fillRect(rect.adjusted(o, 0, -o, 0), QColor(0, 0, 0, 30)); painter->fillRect(rect.adjusted(o, 1, -o, 1), QColor(255, 255, 255, 80)); rect.translate(0, s); } } #endif } #if 0 painter->fillRect(style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderGroove, widget), QColor(0, 0, 0, 70)); if (option->subControls & QStyle::SC_SliderGroove) { painter->fillRect(style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderGroove, widget), QColor(255, 0, 0, 70)); } if (option->subControls & QStyle::SC_SliderHandle) { painter->fillRect(style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderHandle, widget), QColor(0, 100, 255, 70)); } if (option->subControls & QStyle::SC_SliderTickmarks) { painter->fillRect(style->subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderTickmarks, widget), QColor(0, 255, 0, 170)); } #endif } /*-----------------------------------------------------------------------*/ QRect subControlRectSlider(const QStyleOptionSlider *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { QRect rect = ((QCommonStyle *) style)->QCommonStyle::subControlRect(QStyle::CC_Slider, option, subControl, widget); switch (subControl) { case QStyle::SC_SliderGroove: case QStyle::SC_SliderTickmarks: case QStyle::SC_SliderHandle: default: break; } return rect; #if 0 /* option->orientation option->tickPosition: QSlider::TicksAbove | QSlider::TicksBelow option->state option->tickInterval */ switch (subControl) { case SC_SliderGrove: case SC_SliderTickmarks: case SC_SliderHandle: } #endif } /* * skulpture_spinbox.cpp * */ #include "skulpture_p.h" #include #include #include /*-----------------------------------------------------------------------*/ extern void paintScrollArrow(QPainter *painter, const QStyleOption *option, Qt::ArrowType arrow, bool spin); void paintIndicatorSpinDown(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::DownArrow, true); } void paintIndicatorSpinUp(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::UpArrow, true); } void paintIndicatorSpinMinus(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::LeftArrow, true); } void paintIndicatorSpinPlus(QPainter *painter, const QStyleOption *option, const QWidget */*widget*/, const QStyle */*style*/) { paintScrollArrow(painter, option, Qt::RightArrow, true); } /*-----------------------------------------------------------------------*/ QRect subControlRectSpinBox(const QStyleOptionSpinBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { int fw = option->frame ? style->pixelMetric(QStyle::PM_SpinBoxFrameWidth, option, widget) : 0; int bw; #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (option->buttonSymbols == QAbstractSpinBox::NoButtons) { bw = 0; } else #endif { bw = qMax(style->pixelMetric(QStyle::PM_ScrollBarExtent, option, widget), 0); } bool strutMode = 0 > (option->rect.height() >> 1); QRect rect; switch (subControl) { case QStyle::SC_SpinBoxUp: case QStyle::SC_SpinBoxDown: { int h = option->rect.height() - 2 * fw; int t = option->rect.top() + fw; int l = option->rect.right() - bw - fw + 1; if (strutMode) { if (subControl == QStyle::SC_SpinBoxUp) { l -= bw; } } else { if (subControl == QStyle::SC_SpinBoxDown) { t += (h >> 1); } h = (h + 1) >> 1; } rect = QRect(l, t, bw, h); break; } case QStyle::SC_SpinBoxEditField: { if (strutMode) { bw *= 2; } rect = option->rect.adjusted(fw, fw, -fw - bw, -fw); break; } case QStyle::SC_SpinBoxFrame: default: // avoid warning rect = option->rect; break; } return style->visualRect(option->direction, option->rect, rect); } /*-----------------------------------------------------------------------*/ void paintComplexControlArea(QPainter *painter, const QStyleOption *option) { // configuration const bool paintBackground = true; const bool paintSeparator = true; // background QColor color; if (paintBackground && option->state & QStyle::State_Enabled) { color = option->palette.color(QPalette::Window); // ### should arrow areas have hover highlight? if (false && option->state & QStyle::State_MouseOver) { #if QT_VERSION >= QT_VERSION_CHECK(4, 3, 0) color = color.lighter(110); #else color = color.light(110); #endif } else { #if QT_VERSION >= QT_VERSION_CHECK(4, 3, 0) color = color.lighter(107); #else color = color.light(107); #endif } } else { color = option->palette.color(QPalette::Base); } painter->fillRect(option->rect, color); // separator if (paintSeparator) { QRect rect = option->rect; if (option->direction == Qt::LeftToRight) { rect.setWidth(1); } else { rect.setLeft(rect.left() + rect.width() - 1); } painter->fillRect(rect, shaded_color(option->palette.color(QPalette::Window), -5)); } } static void paintSpinBoxUpDown(QPainter *painter, const QStyleOptionSpinBox *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { QStyleOption opt; opt.QStyleOption::operator=(*option); opt.rect = style->subControlRect(QStyle::CC_SpinBox, option, subControl, widget); if (!(option->activeSubControls & subControl)) { opt.state &= ~(QStyle::State_Sunken | QStyle::State_On | QStyle::State_MouseOver); } // button background paintComplexControlArea(painter, &opt); // button symbol QStyle::PrimitiveElement pe; if (!(option->stepEnabled & (subControl == QStyle::SC_SpinBoxUp ? QAbstractSpinBox::StepUpEnabled : QAbstractSpinBox::StepDownEnabled))) { opt.state &= ~(QStyle::State_Enabled | QStyle::State_MouseOver); opt.palette.setCurrentColorGroup(QPalette::Disabled); } // micro adjustments if (subControl == QStyle::SC_SpinBoxUp) { opt.rect.translate(0, 1); } else if (opt.rect.height() & 1) { opt.rect.translate(0, -1); } switch (option->buttonSymbols) { case QAbstractSpinBox::PlusMinus: pe = subControl == QStyle::SC_SpinBoxUp ? QStyle::PE_IndicatorSpinPlus : QStyle::PE_IndicatorSpinMinus; break; default: pe = subControl == QStyle::SC_SpinBoxUp ? QStyle::PE_IndicatorSpinUp : QStyle::PE_IndicatorSpinDown; break; } style->drawPrimitive(pe, &opt, painter, widget); } void paintSpinBox(QPainter *painter, const QStyleOptionSpinBox *option, const QWidget *widget, const QStyle *style) { // up/down controls #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (option->buttonSymbols != QAbstractSpinBox::NoButtons) #endif { for (uint sc = QStyle::SC_SpinBoxUp; sc != QStyle::SC_SpinBoxFrame; sc <<= 1) { if (option->subControls & sc) { paintSpinBoxUpDown(painter, option, (QStyle::SubControl) sc, widget, style); } } } // frame if (option->frame && (option->subControls & QStyle::SC_SpinBoxFrame)) { QStyleOptionFrame frameOpt; frameOpt.QStyleOption::operator=(*option); frameOpt.rect = style->subControlRect(QStyle::CC_SpinBox, option, QStyle::SC_SpinBoxFrame, widget); frameOpt.state |= QStyle::State_Sunken; frameOpt.lineWidth = style->pixelMetric(QStyle::PM_SpinBoxFrameWidth, &frameOpt, widget); frameOpt.midLineWidth = 0; style->drawPrimitive(QStyle::PE_FrameLineEdit, &frameOpt, painter, widget); } } /* * skulpture_tabs.cpp * */ #include "skulpture_p.h" #include #include /*-----------------------------------------------------------------------*/ enum Pos { North, South, West, East }; static inline Pos tabPos(QTabBar::Shape shape) { return Pos(int(shape) & 3); } static inline bool isVertical(QTabBar::Shape shape) { return (int(shape) & 2); } struct Affinity { int x1, y1, x2, y2; }; static inline void tabAffinity(QTabBar::Shape shape, Affinity &affinity, int amount) { affinity.x1 = affinity.y1 = affinity.x2 = affinity.y2 = 0; switch (tabPos(shape)) { case North: affinity.y1 = amount; break; case South: affinity.y2 = -amount; break; case West: affinity.x1 = amount; break; case East: affinity.x2 = -amount; break; } } /*-----------------------------------------------------------------------*/ #if 0 enum TabState { TS_New, TS_Removed, TS_Inactive, TS_HoverAnim, TS_Hover, TS_ActiveAnim, TS_Active, TS_Moved, TS_LabelChanged // text, icon or color changed TS_StateChanged // disabled changed }; class TabAnim { qreal pos; qreal speed; int color; }; class Tab { public: TabState state; TabAnim anim; #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) QStyleOptionTabV3 oldOption; #else QStyleOptionTabV2 oldOption; #endif }; /*-----------------------------------------------------------------------*/ class TabBarState { public: TabBarState() : active_tab(0), hover_tab(0) { } public: QList tabs; Tab *active_tab; Tab *hover_tab; int hover_x; int hover_y; int hover_counter; }; const TabBarState *SkulpturePrivate::tabBarState(const QWidget *widget) { if (qobject_cast(widget)) { if ((int i = tabBarStates.indexOf(widget))) { return tabBarStates.at(i); } // add state if not found TabBarState *state = new TabBarState; if (state) { } } return 0; } #endif /*-----------------------------------------------------------------------*/ static void paintTabBase(QPainter *painter, const QRect &r, const QStyleOption *option, QTabBar::Shape shape) { QRect rect = r; #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) if (!isVertical(shape) && option->version >= QStyleOptionTabBarBaseV2::Version) { if (((const QStyleOptionTabBarBaseV2 *) option)->documentMode) { rect.adjust(-10, 0, 10, 0); } } #endif if (true /*option->state & QStyle::State_Enabled*/) { QLinearGradient tabGradient(rect.topLeft(), isVertical(shape) ? rect.topRight() : rect.bottomLeft()); tabGradient.setColorAt(0.0, option->palette.color(QPalette::Window).darker(118)); tabGradient.setColorAt(1.0, option->palette.color(QPalette::Window).darker(105)); painter->fillRect(rect.adjusted(1, 1, -1, -1), tabGradient); } else { painter->fillRect(rect.adjusted(1, 1, -1, -1), option->palette.color(QPalette::Window).darker(106)); } paintThinFrame(painter, rect.adjusted(1, 1, -1, -1), option->palette, -20, -40); paintRecessedFrameShadow(painter, rect.adjusted(2, 2, -2, -2), RF_Small); } void paintFrameTabBarBase(QPainter *painter, const QStyleOptionTabBarBase *option, const QWidget *widget, const QStyle */*style*/) { #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) if (option->version >= QStyleOptionTabBarBaseV2::Version) { if (((const QStyleOptionTabBarBaseV2 *) option)->documentMode) { QRect r = option->rect; if (tabPos(option->shape) == North && r.top() > 0) { r.setTop(0); } else if (tabPos(option->shape) == South && qobject_cast(widget) && widget->rect().bottom() != r.bottom()) { r.setBottom(widget->rect().bottom()); } else { return; } painter->save(); painter->setClipRect(r); paintTabBase(painter, r, option, option->shape); paintThinFrame(painter, r.adjusted(-10, 0, 10, 0), option->palette, 60, -20); painter->restore(); return; } } #else Q_UNUSED(widget); #endif // ### remove clipping painter->save(); QRect r = option->rect; #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) r = r.united(option->tabBarRect); #else r = r.unite(option->tabBarRect); #endif QRegion region(r); region -= option->tabBarRect; painter->setClipRegion(region); paintTabBase(painter, r, option, option->shape); QRect rect = r; #if 0 Affinity affinity; tabAffinity(option->shape, affinity, 1); rect.adjust(affinity.x2, affinity.y2, affinity.x1, affinity.y1); #endif paintThinFrame(painter, rect, option->palette, 60, -20); painter->restore(); } void paintTabWidgetFrame(QPainter *painter, const QStyleOptionTabWidgetFrame *option, const QWidget *widget, const QStyle */*style*/) { Q_UNUSED(widget); QRect base = option->rect; int s = (isVertical(option->shape) ? option->tabBarSize.width() : option->tabBarSize.height()); if (s < 2) s = 2; if (isVertical(option->shape)) { base.setWidth(s); } else { base.setHeight(s); } const int overlap = 2; switch (tabPos(option->shape)) { case North: base.translate(0, -(s - overlap)); break; case West: base.translate(-(s - overlap), 0); break; case South: base.translate(0, option->rect.height() - overlap); break; case East: base.translate(option->rect.width() - overlap, 0); break; } if (s != 2) { paintTabBase(painter, base, option, option->shape); } Affinity affinity; tabAffinity(option->shape, affinity, -(s - overlap)); // painter->save(); // painter->setClipRect(base); paintThinFrame(painter, option->rect.adjusted(affinity.x1, affinity.y1, affinity.x2, affinity.y2), option->palette, 60, -20); paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -40, 160); #if 1 painter->save(); painter->setPen(QPen(QColor(0, 0, 0, 20), 1)); painter->drawLine(option->rect.x() + 1, option->rect.bottom(), option->rect.right() - 1, option->rect.bottom()); painter->drawLine(option->rect.right(), option->rect.top() + 1, option->rect.right(), option->rect.bottom()); painter->restore(); #endif #if 0 QRect r = option->rect.adjusted(2, 2, -2, -2); painter->fillRect(r, option->palette.color(QPalette::Window)); QLinearGradient gradient(r.topLeft(), r.bottomLeft()); gradient.setColorAt(0.0, QColor(255, 255, 255, 0)); gradient.setColorAt(1.0, QColor(0, 0, 0, 20)); painter->fillRect(r, gradient); #endif // painter->restore(); } /*-----------------------------------------------------------------------*/ #define TAB_SHIFT 1 void paintTabBarTabShape(QPainter *painter, const QStyleOptionTab *option, const QWidget *widget, const QStyle *style) { Q_UNUSED(style); const QColor tabBackgroundColor = option->palette.color(QPalette::Active, QPalette::Window); bool mouse = (option->state & QStyle::State_MouseOver) && !(option->state & QStyle::State_Selected) && (option->state & QStyle::State_Enabled); QRect c_rect = option->rect; bool konq = false; if (widget && widget->parentWidget()) { if (!qstrcmp(widget->metaObject()->className(), "KTabBar") && !qstrcmp(widget->parentWidget()->metaObject()->className(), "KonqFrameTabs")) { konq = true; #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) if (option->version >= QStyleOptionTabV3::Version) { if (((const QStyleOptionTabV3 *) option)->documentMode) { konq = false; } } #endif } } if (konq || (widget && !(qobject_cast(widget->parentWidget())))) { // ### remove clipping painter->save(); painter->setClipRect(option->rect); QRect rect = widget->rect(); if (konq) { rect.adjust(-10, 0, 10, 0); } paintTabBase(painter, rect, option, option->shape); #if 0 Affinity affinity; tabAffinity(option->shape, affinity, 1); rect.adjust(affinity.x2, affinity.y2, affinity.x1, affinity.y1); #endif paintThinFrame(painter, rect, option->palette, 60, -20); painter->restore(); } switch (tabPos(option->shape)) { case North: c_rect.adjust(1, 1, -2, 0); if (option->position != QStyleOptionTab::Beginning && option->position != QStyleOptionTab::OnlyOneTab) { c_rect.adjust(-1, 0, 0, 0); } if (option->state & QStyle::State_Selected) { painter->fillRect(c_rect.adjusted(0, 0, -1, 0), tabBackgroundColor); if (option->state & QStyle::State_Enabled) { QLinearGradient gradient(c_rect.topLeft(), c_rect.bottomLeft()); #if 0 QColor c = option->palette.color(QPalette::Highlight); gradient.setColorAt(0.0, c); gradient.setColorAt(0.2, QColor(255, 255, 255, 20)); gradient.setColorAt(1.0, QColor(255, 255, 255, 0)); #else gradient.setColorAt(0.0, shaded_color(tabBackgroundColor, 20)); gradient.setColorAt(1.0, shaded_color(tabBackgroundColor, 0)); #endif painter->fillRect(c_rect.adjusted(0, 0, -1, 0), gradient); } // ### flat tabs: 50->20, 180->80 // painter->fillRect(c_rect, QColor(255, 0, 0, 100)); Affinity affinity; tabAffinity(option->shape, affinity, 1); paintThinFrame(painter, c_rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1), option->palette, -50, 180); // shadows painter->fillRect(QRect(c_rect.right() + 1, c_rect.top(), 1, c_rect.height()), QColor(0, 0, 0, 25)); painter->fillRect(QRect(c_rect.right() + 2, c_rect.top(), 1, c_rect.height()), QColor(0, 0, 0, 10)); } else { // ### install clip painter->save(); Affinity affinity; tabAffinity(option->shape, affinity, -1); painter->setClipRect(option->rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1)); painter->fillRect(c_rect.adjusted(1, mouse ? 1 : 2, -1, -1), mouse ? tabBackgroundColor.darker(104) : tabBackgroundColor.darker(108)); paintThinFrame(painter, c_rect.adjusted(1, mouse ? 1 : 2, -1, 1), option->palette, -40, 90); // shadows painter->fillRect(QRect(c_rect.right(), c_rect.top() + 3, 1, c_rect.height() - 4), QColor(0, 0, 0, 15)); painter->fillRect(QRect(c_rect.right() + 1, c_rect.top() + 3, 1, c_rect.height() - 4), QColor(0, 0, 0, 5)); painter->restore(); // shadow below base painter->fillRect(QRect(c_rect.left() + 1, c_rect.bottom() - 1, c_rect.width() - 2, 1), QColor(0, 0, 0, 10)); painter->fillRect(QRect(c_rect.left() + 1, c_rect.bottom() - 2, c_rect.width() - 2, 1), QColor(0, 0, 0, 4)); } break; case South: c_rect.adjust(1, 0, -2, -1); if (option->position != QStyleOptionTab::Beginning && option->position != QStyleOptionTab::OnlyOneTab) { c_rect.adjust(-1, 0, 0, 0); } if (option->state & QStyle::State_Selected) { painter->fillRect(c_rect.adjusted(0, 0, -1, 0), tabBackgroundColor); if (option->state & QStyle::State_Enabled) { QLinearGradient gradient(c_rect.topLeft(), c_rect.bottomLeft()); gradient.setColorAt(0.0, shaded_color(tabBackgroundColor, 0)); gradient.setColorAt(1.0, shaded_color(tabBackgroundColor, -5)); painter->fillRect(c_rect.adjusted(0, 0, -1, 0), gradient); } Affinity affinity; tabAffinity(option->shape, affinity, 1); paintThinFrame(painter, c_rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1), option->palette, -50, 180); //paintThinFrame(painter, c_rect.adjusted(0, -1, 0, 0), option->palette, -50, 180); // shadows painter->fillRect(QRect(c_rect.right() + 1, c_rect.top() + 1, 1, c_rect.height() - 1), QColor(0, 0, 0, 25)); painter->fillRect(QRect(c_rect.right() + 2, c_rect.top() + 1, 1, c_rect.height() - 1), QColor(0, 0, 0, 10)); painter->fillRect(QRect(c_rect.left() + 1, c_rect.bottom() + 1, c_rect.width(), 1), QColor(0, 0, 0, 20)); } else { // ### install clip painter->save(); Affinity affinity; tabAffinity(option->shape, affinity, -1); painter->setClipRect(option->rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1)); painter->fillRect(c_rect.adjusted(1, 1, -1, mouse ? -1 : -2), mouse ? tabBackgroundColor.darker(104) : tabBackgroundColor.darker(108)); paintThinFrame(painter, c_rect.adjusted(1, -1, -1, mouse ? -1 : -2), option->palette, -40, 90); // shadows painter->fillRect(QRect(c_rect.right(), c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 15)); painter->fillRect(QRect(c_rect.right() + 1, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 5)); if (!mouse) { painter->fillRect(QRect(c_rect.left() + 2, c_rect.bottom() - 1, c_rect.width() - 3, 1), QColor(0, 0, 0, 10)); } painter->restore(); // shadow below base painter->fillRect(QRect(c_rect.left() + 1, c_rect.top() + 1, c_rect.width() - 2, 1), QColor(0, 0, 0, 30)); painter->fillRect(QRect(c_rect.left() + 1, c_rect.top() + 2, c_rect.width() - 2, 1), QColor(0, 0, 0, 15)); painter->fillRect(QRect(c_rect.left() + 1, c_rect.top() + 3, c_rect.width() - 2, 1), QColor(0, 0, 0, 8)); painter->fillRect(QRect(c_rect.left() + 1, c_rect.top() + 4, c_rect.width() - 2, 1), QColor(0, 0, 0, 4)); } break; case West: c_rect.adjust(1, 1, 0, -2); if (option->state & QStyle::State_Selected) { painter->fillRect(c_rect.adjusted(0, 0, 0, -1), tabBackgroundColor); if (option->state & QStyle::State_Enabled) { QLinearGradient gradient(c_rect.topLeft(), c_rect.topRight()); gradient.setColorAt(0.0, shaded_color(tabBackgroundColor, 20)); gradient.setColorAt(1.0, shaded_color(tabBackgroundColor, 0)); painter->fillRect(c_rect.adjusted(0, 0, 0, -1), gradient); } Affinity affinity; tabAffinity(option->shape, affinity, 1); paintThinFrame(painter, c_rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1), option->palette, -50, 180); // shadows painter->fillRect(QRect(c_rect.left(), c_rect.bottom() + 1, c_rect.width(), 1), QColor(0, 0, 0, 25)); painter->fillRect(QRect(c_rect.left(), c_rect.bottom() + 2, c_rect.width(), 1), QColor(0, 0, 0, 10)); } else { // ### install clip painter->save(); Affinity affinity; tabAffinity(option->shape, affinity, -1); painter->setClipRect(option->rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1)); painter->fillRect(c_rect.adjusted(mouse ? 1 : 2, 1, 1, -1), mouse ? tabBackgroundColor.darker(104) : tabBackgroundColor.darker(108)); paintThinFrame(painter, c_rect.adjusted(mouse ? 1 : 2, 1, 1, -1), option->palette, -40, 90); // shadows painter->fillRect(QRect(c_rect.left() + 2, c_rect.bottom() + 0, c_rect.width() - 3, 1), QColor(0, 0, 0, 15)); painter->fillRect(QRect(c_rect.left() + 2, c_rect.bottom() + 1, c_rect.width() - 3, 1), QColor(0, 0, 0, 5)); painter->restore(); // shadow below base painter->fillRect(QRect(c_rect.right() - 1, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 10)); painter->fillRect(QRect(c_rect.right() - 2, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 4)); } break; case East: c_rect.adjust(0, 1, -1, -2); if (option->state & QStyle::State_Selected) { painter->fillRect(c_rect.adjusted(0, 0, 0, -1), tabBackgroundColor); if (option->state & QStyle::State_Enabled) { QLinearGradient gradient(c_rect.topLeft(), c_rect.topRight()); gradient.setColorAt(0.0, shaded_color(tabBackgroundColor, 0)); gradient.setColorAt(1.0, shaded_color(tabBackgroundColor, 10)); painter->fillRect(c_rect.adjusted(0, 0, 0, -1), gradient); } Affinity affinity; tabAffinity(option->shape, affinity, 1); paintThinFrame(painter, c_rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1), option->palette, -50, 180); // shadows painter->fillRect(QRect(c_rect.left(), c_rect.bottom() + 1, c_rect.width(), 1), QColor(0, 0, 0, 25)); painter->fillRect(QRect(c_rect.left(), c_rect.bottom() + 2, c_rect.width(), 1), QColor(0, 0, 0, 10)); painter->fillRect(QRect(c_rect.right() + 1, c_rect.top() + 1, 1, c_rect.height()), QColor(0, 0, 0, 20)); } else { // ### install clip painter->save(); Affinity affinity; tabAffinity(option->shape, affinity, -1); painter->setClipRect(option->rect.adjusted(affinity.x2, affinity.y2, affinity.x1, affinity.y1)); painter->fillRect(c_rect.adjusted(-2, 1, mouse ? -1 : -2, -1), mouse ? tabBackgroundColor.darker(104) : tabBackgroundColor.darker(108)); paintThinFrame(painter, c_rect.adjusted(-2, 1, mouse ? -1 : -2, -1), option->palette, -40, 90); // shadows painter->fillRect(QRect(c_rect.left() + 1, c_rect.bottom() + 0, c_rect.width() - 3, 1), QColor(0, 0, 0, 15)); painter->fillRect(QRect(c_rect.left() + 1, c_rect.bottom() + 1, c_rect.width() - 3, 1), QColor(0, 0, 0, 5)); painter->restore(); // shadow below base painter->fillRect(QRect(c_rect.left() + 1, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 20)); painter->fillRect(QRect(c_rect.left() + 2, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 10)); painter->fillRect(QRect(c_rect.left() + 3, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 5)); // painter->fillRect(QRect(c_rect.left() + 4, c_rect.top() + 1, 1, c_rect.height() - 2), QColor(0, 0, 0, 4)); } break; } } #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) void paintIndicatorTabClose(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style) { int offset = 0; QTabBar::Shape shape = QTabBar::RoundedNorth; if (widget) { if (QTabBar *tabbar = qobject_cast(widget->parentWidget())) { offset = TAB_SHIFT; shape = tabbar->shape(); for (int i = 0; i < tabbar->count(); ++i) { if (tabbar->tabRect(i).contains(widget->mapToParent(QPoint(1, 1)))) { if (i == tabbar->currentIndex()) { offset = 0; } else if (tabbar->tabRect(i).contains(tabbar->mapFromGlobal(QCursor::pos()))) { offset = 0; } break; } } if (false /*tabPos(shape) == East || tabPos(shape) == South*/) { offset += 1; } } } QIcon::Mode iconMode = QIcon::Normal; painter->save(); if (option->state & QStyle::State_Enabled) { if (option->state & QStyle::State_MouseOver || option->state & QStyle::State_Sunken) { // paintThinFrame(painter, option->rect, option->palette, 90, -30); iconMode = QIcon::Active; //painter->fillRect(option->rect.adjusted(1, 1, -1, -1), QColor(220, 0, 0)); if (!(option->state & QStyle::State_Sunken)) { // paintThinFrame(painter, option->rect.adjusted(1, 1, -1, -1), option->palette, -60, 180); } else { //iconMode = QIcon::Selected; } } else { painter->setOpacity(0.7); } } else { //iconMode = QIcon::Disabled; painter->setOpacity(0.7); } QRect r = QRect(option->rect.center() - QPoint(option->state & QStyle::State_Sunken ? 3 : 4, option->state & QStyle::State_Sunken ? 3 : 4), QSize(10, 10)); if (offset) { Affinity affinity; tabAffinity(shape, affinity, offset); r.translate(affinity.x1 + affinity.x2, affinity.y1 + affinity.y2); } painter->drawPixmap(r, style->standardIcon(QStyle::SP_TitleBarCloseButton, option, widget).pixmap(10, 10, iconMode)); painter->restore(); } #endif void paintTabBarTabLabel(QPainter *painter, const QStyleOptionTab *option, const QWidget *widget, const QStyle *style) { // bool mouse = (option->state & QStyle::State_MouseOver) && !(option->state & QStyle::State_Selected) && (option->state & QStyle::State_Enabled); // painter->save(); #if 0 if (!(option->state & QStyle::State_Selected)) { if (mouse) { painter->setOpacity(0.7); } else { painter->setOpacity(0.5); } } else { painter->setOpacity(0.8); } // QFont font(painter->font()); // font.setBold(true); // painter->setFont(font); #endif #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) QStyleOptionTabV2 opt; #else QStyleOptionTab opt; #endif int offset = TAB_SHIFT; if (option->state & QStyle::State_Selected || (option->state & QStyle::State_MouseOver && option->state & QStyle::State_Enabled)) { offset = 0; } #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) if (option->version > 1) opt = *((QStyleOptionTabV2 *) option); else #endif opt = *option; Affinity affinity; tabAffinity(option->shape, affinity, offset); opt.rect.translate(affinity.x1 + affinity.x2, affinity.y1 + affinity.y2); switch (tabPos(option->shape)) { case North: opt.rect.adjust(-2, 1, -1, 1); break; case South: opt.rect.adjust(-2, 0, -1, 0); break; case West: case East: painter->save(); QTransform mat; if (tabPos(option->shape) == West) { opt.rect.adjust(3, 0, 3, 0); } else { opt.rect.adjust(-1, 0, -1, 0); } QPointF c = opt.rect.center(); mat.translate(c.x(), c.y()); mat.rotate(tabPos(option->shape) == West ? -90 : 90); mat.translate(-c.x(), -c.y()); opt.rect = mat.mapRect(opt.rect); painter->setTransform(mat, true); opt.shape = (QTabBar::Shape) 0; break; } ((QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_TabBarTabLabel, &opt, painter, widget); if (isVertical(option->shape)) { painter->restore(); } } /* * skulpture_text.cpp * */ #include "skulpture_p.h" #include #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) #include #endif #include #include #include #include #include /*-----------------------------------------------------------------------*/ void SkulptureStyle::Private::removeCursorLine(QAbstractScrollArea *edit) { Q_UNUSED (edit); if (oldEdit) { oldEdit->viewport()->update(QRect(0, oldCursorTop, oldCursorWidth, oldCursorHeight)); oldEdit = 0; } } void SkulptureStyle::Private::updateCursorLine(QAbstractScrollArea *edit, const QRect &cursorRect) { const int highlightMargin = qMin(2, widgetSize); QRect cursorLine = cursorRect; cursorLine.setLeft(0); cursorLine.setWidth(edit->viewport()->width()); cursorLine.adjust(0, -highlightMargin, 0, highlightMargin); if (edit != oldEdit || cursorLine.top() != oldCursorTop || cursorLine.width() != oldCursorWidth || cursorLine.height() != oldCursorHeight || edit->viewport()->height() != oldHeight) { removeCursorLine(edit); oldEdit = edit; oldCursorTop = cursorLine.top(); oldCursorWidth = cursorLine.width(); oldCursorHeight = cursorLine.height(); oldHeight = edit->viewport()->height(); edit->viewport()->update(cursorLine); } } void SkulptureStyle::Private::paintCursorLine(QAbstractScrollArea *edit) { if (edit == oldEdit) { QRect cursorLine = QRect(0, oldCursorTop, oldCursorWidth, oldCursorHeight); QPainter painter(edit->viewport()); QPalette palette = edit->palette(); QColor color = palette.color(QPalette::Highlight); color.setAlpha(40); painter.fillRect(cursorLine, color); if (edit->window()->testAttribute(Qt::WA_KeyboardFocusChange)) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) color = palette.color(QPalette::Highlight).darker(120); #else color = palette.color(QPalette::Highlight).dark(120); #endif color.setAlpha(120); painter.fillRect(cursorLine.adjusted(0, cursorLine.height() - 3, 0, -2), color); } } } #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) void SkulptureStyle::Private::handleCursor(QPlainTextEdit *edit) { if (edit->hasFocus() && !edit->isReadOnly()) { QStyleOption option; option.initFrom(edit); int cursorWidth = q->SkulptureStyle::pixelMetric(PM_TextCursorWidth, &option, edit); if (edit->cursorWidth() != cursorWidth) { edit->setCursorWidth(cursorWidth); } updateCursorLine(edit, edit->cursorRect()); } else { if (edit == oldEdit) { removeCursorLine(edit); } } } #endif void SkulptureStyle::Private::handleCursor(QTextEdit *edit) { if (edit->hasFocus() && !edit->isReadOnly()) { QStyleOption option; option.initFrom(edit); #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) int cursorWidth = q->SkulptureStyle::pixelMetric(PM_TextCursorWidth, &option, edit); #else int cursorWidth = q->SkulptureStyle::pixelMetric((QStyle::PixelMetric)((int) PM_CustomBase + 1), &option, edit); #endif if (edit->cursorWidth() != cursorWidth) { edit->setCursorWidth(cursorWidth); } #endif updateCursorLine(edit, edit->cursorRect()); } else { if (edit == oldEdit) { removeCursorLine(edit); } } } /*-----------------------------------------------------------------------*/ void SkulptureStyle::Private::updateTextEditMargins(QTextEdit *edit) { int margin = 1 + edit->fontMetrics().height() / 5; if (margin > 4) margin = 4; if (qobject_cast(edit)) { margin = edit->fontMetrics().height(); if (margin < 4 || edit->height() < 4 * edit->fontMetrics().height()) { margin = 4; } } if (margin < 2 || edit->height() < 2 * edit->fontMetrics().height()) { margin = 2; } QTextDocument *doc = edit->document(); // printf("doc: %p\n", doc); if (!doc) return; if (doc->isEmpty()) { // create valid root frame QTextCursor cursor(doc); } QTextFrame *root = doc->rootFrame(); // printf("root: %p\n", root); if (!root) return; QTextFrameFormat format = root->frameFormat(); if (!format.isValid()) return; if (format.margin() == 2.0 && margin != 2) { // printf("set margin %d\n", margin); // ### crash on setText(), disable signals //disconnect(edit, SIGNAL(textChanged()), &mapper, SLOT(map())); doc->blockSignals(true); format.setMargin(margin); #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) if (margin < 12) { format.setTopMargin(widgetSize - ((textShift + 1) >> 1)); format.setBottomMargin(widgetSize + ((textShift + 1) >> 1)); } #endif root->setFrameFormat(format); // edit->insertPlainText(QLatin1String("")); // edit->update(); doc->blockSignals(false); //connect(edit, SIGNAL(textChanged()), &mapper, SLOT(map())); // clear undo buffer bool undo = edit->isUndoRedoEnabled(); edit->setUndoRedoEnabled(false); doc->setModified(false); // emit doc->contentsChanged(); edit->setUndoRedoEnabled(undo); // force relayout edit->resize(edit->size() + QSize(-1, 0)); edit->resize(edit->size() + QSize(1, 0)); } } void SkulptureStyle::Private::textEditSourceChanged(QWidget *widget) { if (QTextEdit *edit = qobject_cast(widget)) { updateTextEditMargins(edit); } } /*-----------------------------------------------------------------------*/ QRect SkulptureStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const { Q_UNUSED(enabled); return ParentStyle::itemTextRect(metrics, rectangle, alignment, true, text); } void SkulptureStyle::drawItemText(QPainter * painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole) const { int textShift = 0; if (!(alignment & (Qt::AlignTop | Qt::AlignBottom))) { textShift = d->verticalTextShift(painter->fontMetrics()); if (runtimeQtVersion() >= QT_VERSION_CHECK(4, 6, 1)) { if (textShift & 1 && ((painter->fontMetrics().height() ^ rectangle.height()) & 1)) { textShift -= 1; } } else { if (textShift & 1 && !(rectangle.height() & 1)) { textShift += 1; } } } ParentStyle::drawItemText(painter, textShift == 0 || textShift == -1 ? rectangle : rectangle.adjusted(0, (-textShift) >> 1, 0, (-textShift) >> 1), alignment, palette, enabled, text, textRole); } /* * skulpture_toolbar.cpp * */ #include "skulpture_p.h" #include #include #include #include /*-----------------------------------------------------------------------*/ #define PAINT_SEPARATOR 0 /*-----------------------------------------------------------------------*/ extern void paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole bgrole); void paintToolBarSeparator(QPainter *painter, const QStyleOptionToolBar *option, const QWidget */*widget*/, const QStyle */*style*/) { #if 0 int d = 3; QRect rect(QRect(option->rect).center() - QPoint(d / 2, d / 2), QSize(d, d)); QStyleOption iOption; iOption.QStyleOption::operator=(*option); if (option->state & QStyle::State_Horizontal) { iOption.rect = rect.adjusted(1, 0, 1, 0); } else { iOption.rect = rect.adjusted(0, 1, 0, 1); } iOption.palette.setCurrentColorGroup(QPalette::Disabled); // iOption.state &= ~QStyle::State_Enabled; iOption.palette.setColor(QPalette::Button, iOption.palette.color(QPalette::Window)); paintCachedGrip(painter, &iOption, QPalette::Window); #else #if PAINT_SEPARATOR QRect rect = option->rect; if (option->state & QStyle::State_Horizontal) { // rect.adjust(2, 3, -2, -3); rect.adjust(2, -1, -2, 1); } else { // rect.adjust(3, 2, -3, -2); rect.adjust(-1, 2, 1, -2); } paintThinFrame(painter, rect, option->palette, 60, -20); #else Q_UNUSED(painter); Q_UNUSED(option); #endif #endif } /*-----------------------------------------------------------------------*/ void paintToolBarHandle(QPainter *painter, const QStyleOptionToolBar *option, const QWidget */*widget*/, const QStyle */*style*/) { #if 1 int d = 5; QRect rect(QRect(option->rect).center() - QPoint(d / 2, d / 2), QSize(d, d)); QStyleOption iOption; iOption.QStyleOption::operator=(*option); iOption.rect = rect; iOption.palette.setCurrentColorGroup(QPalette::Disabled); // iOption.state &= ~QStyle::State_Enabled; iOption.palette.setColor(QPalette::Button, iOption.palette.color(QPalette::Window)); paintCachedGrip(painter, &iOption, QPalette::Window); #else QRect rect = option->rect; if (option->state & QStyle::State_Horizontal) { rect.adjust(2, 2, -2, -2); #if PAINT_SEPARATOR rect.adjust(0, 1, 0, 1); #endif } else { rect.adjust(2, 2, -2, -2); #if PAINT_SEPARATOR rect.adjust(1, 0, 1, 0); #endif } paintThinFrame(painter, rect.adjusted(-1, -1, 1, 1), option->palette, 60, -20); paintThinFrame(painter, rect, option->palette, -30, 80); #endif } /*-----------------------------------------------------------------------*/ void paintPanelToolBar(QPainter *painter, const QStyleOptionToolBar *option, const QWidget */*widget*/, const QStyle */*style*/) { #if 0 QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft()); gradient.setColorAt(0.0, option->palette.color(QPalette::Window).lighter(105)); gradient.setColorAt(1.0, option->palette.color(QPalette::Window)); painter->fillRect(option->rect, gradient); QRect r; // r = option->rect; // r.setTop(r.top() + r.height() - 1); // painter->fillRect(r, option->palette.color(QPalette::Window).darker(105)); r = option->rect; r.setHeight(1); painter->fillRect(r, option->palette.color(QPalette::Window).darker(105)); // painter->fillRect(option->rect, option->palette.color(QPalette::Window)); // paintThinFrame(painter, option->rect, option->palette, -20, 60); #endif #if PAINT_SEPARATOR QRect r = option->rect; if (option->state & QStyle::State_Horizontal) { r.setHeight(2); } else { r.setWidth(2); } paintThinFrame(painter, r, option->palette, 60, -20); #else Q_UNUSED(painter); Q_UNUSED(option); #if 0 if (option->state & QStyle::State_Horizontal) { paintThinFrame(painter, option->rect.adjusted(-1, 0, 1, 0), option->palette, 80, -30); painter->fillRect(option->rect.adjusted(0, 1, 0, -1), QColor(200, 210, 230)); QLinearGradient toolBarGradient(option->rect.topLeft(), option->rect.bottomLeft()); toolBarGradient.setColorAt(0.0, QColor(0, 0, 0, 30)); toolBarGradient.setColorAt(0.05, QColor(0, 0, 0, 0)); #if 0 toolBarGradient.setColorAt(0.5, QColor(0, 0, 0, 10)); toolBarGradient.setColorAt(0.51, QColor(0, 0, 0, 30)); #endif toolBarGradient.setColorAt(0.8, QColor(0, 0, 0, 20)); toolBarGradient.setColorAt(1.0, QColor(0, 0, 0, 0)); painter->fillRect(option->rect.adjusted(0, 1, 0, -1), toolBarGradient); } else { paintThinFrame(painter, option->rect.adjusted(0, -1, 0, 1), option->palette, 80, -30); } #else // painter->fillRect(option->rect, QColor(0, 0, 0, 10)); #endif #endif } /*-----------------------------------------------------------------------*/ static inline bool inVerticalToolBar(const QStyleOption *option, const QWidget *widget) { // ### option->state does not reflect orientation Q_UNUSED(option); bool verticalBar = false; if (widget && widget->parentWidget()) { const QToolBar *toolBar = qobject_cast(widget->parentWidget()); // printf("toolbar: %p\n", toolBar); if (toolBar && toolBar->orientation() == Qt::Vertical) { verticalBar = true; } } return verticalBar; } /*-----------------------------------------------------------------------*/ // FIXME #if (QT_VERSION < QT_VERSION_CHECK(4, 3, 0)) #define HasMenu Menu #endif extern void paintMenuTitle(QPainter *painter, const QStyleOptionToolButton *option, const QWidget *widget, const QStyle *style); void paintToolButton(QPainter *painter, const QStyleOptionToolButton *option, const QWidget *widget, const QStyle *style) { if (widget) { QTabBar *bar = qobject_cast(widget->parentWidget()); if (bar) { // tabbar scroll button QStyleOptionToolButton opt = *option; if (int(bar->shape()) & 2) { opt.rect.adjust(4, 0, -4, -1); } else { opt.rect.adjust(0, 4, 0, -3); } painter->save(); painter->setClipRect(opt.rect); painter->fillRect(opt.rect, option->palette.color(QPalette::Window)); ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_ToolButton, &opt, painter, widget); painter->restore(); return; } else if (widget->objectName() == QLatin1String("qt_menubar_ext_button") || widget->objectName() == QLatin1String("qt_toolbar_ext_button")) { QStyleOptionToolButton opt = *option; /* do not render menu arrow, because extension buttons already have an arrow */ opt.features &= ~(QStyleOptionToolButton::Menu | QStyleOptionToolButton::HasMenu); ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_ToolButton, &opt, painter, widget); return; } else { const QToolButton *button = qobject_cast(widget); if (button && button->isDown() && button->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { if (widget->parentWidget() && widget->parentWidget()->inherits("KMenu")) { paintMenuTitle(painter, option, widget, style); return; } } } } if (option->features & QStyleOptionToolButton::HasMenu) { if (option->features & QStyleOptionToolButton::Menu) { if (option->subControls & QStyle::SC_ToolButton) { painter->save(); QStyleOptionToolButton opt = *option; opt.rect = style->subControlRect(QStyle::CC_ToolButton, option, QStyle::SC_ToolButton, widget); // opt.features &= ~(QStyleOptionToolButton::Menu | QStyleOptionToolButton::HasMenu | QStyleOptionToolButton::Arrow); opt.arrowType = Qt::NoArrow; opt.features = QStyleOptionToolButton::ToolButtonFeatures(); opt.subControls &= ~(QStyle::SC_ToolButtonMenu); opt.activeSubControls &= ~(QStyle::SC_ToolButtonMenu); if (opt.state & QStyle::State_Sunken) { opt.state |= QStyle::State_MouseOver; } if (inVerticalToolBar(option, widget)) { painter->setClipRect(opt.rect.adjusted(0, 0, 0, -1)); } else { painter->setClipRect(opt.rect.adjusted(option->direction == Qt::LeftToRight ? 0 : 1, 0, option->direction == Qt::LeftToRight ? -1 : 0, 0)); } ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_ToolButton, &opt, painter, widget); painter->restore(); } if (option->subControls & QStyle::SC_ToolButtonMenu) { painter->save(); QStyleOptionToolButton opt = *option; opt.rect = style->subControlRect(QStyle::CC_ToolButton, option, QStyle::SC_ToolButtonMenu, widget); QStyle::State state = option->state; state &= ~(QStyle::State_Sunken | QStyle::State_Raised); if (!(state & QStyle::State_AutoRaise) || (state & QStyle::State_MouseOver)) { state |= QStyle::State_Raised; } #if (QT_VERSION < QT_VERSION_CHECK(4, 5, 0)) if (runtimeQtVersion() < QT_VERSION_CHECK(4, 5, 0)) { if (option->activeSubControls & QStyle::SC_ToolButtonMenu) { state |= QStyle::State_Sunken; } } else #endif { if (option->state & QStyle::State_Sunken) { state |= QStyle::State_Sunken; } else { if (!(option->activeSubControls & QStyle::SC_ToolButtonMenu)) { state &= ~QStyle::State_MouseOver; } } } opt.state = state; if (inVerticalToolBar(option, widget)) { painter->setClipRect(opt.rect.adjusted(0, 1, 0, 0)); } else { painter->setClipRect(opt.rect.adjusted(option->direction == Qt::LeftToRight ? 1 : 0, 0, option->direction == Qt::LeftToRight ? 0 : -1, 0)); } if (state & (QStyle::State_Sunken | QStyle::State_On | QStyle::State_Raised)) { style->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, painter, widget); } painter->restore(); QRect r; if (inVerticalToolBar(option, widget)) { if (option->direction == Qt::LeftToRight) { r = QRect(opt.rect.right() - 9, opt.rect.top(), 7, opt.rect.height()); } else { r = QRect(3, opt.rect.top(), 7, opt.rect.height()); } } else { r = QRect(opt.rect.left(), opt.rect.bottom() - 9, opt.rect.width(), 7); } if (option->state & QStyle::State_Sunken) { if (option->direction == Qt::LeftToRight) { r.adjust(1, 1, 1, 1); } else { r.adjust(-1, 1, -1, 1); } } QFont font; font.setPixelSize(9); opt.fontMetrics = QFontMetrics(font); opt.rect = r; style->drawPrimitive(inVerticalToolBar(option, widget) ? QStyle::PE_IndicatorArrowRight : QStyle::PE_IndicatorArrowDown, &opt, painter, widget); } // painter->fillRect(opt.rect.adjusted(3, 3, -3, -3), Qt::red); } else { QStyleOptionToolButton opt = *option; opt.features &= ~QStyleOptionToolButton::HasMenu; ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_ToolButton, &opt, painter, widget); QRect r; if (option->direction == Qt::LeftToRight) { r = QRect(option->rect.right() - 6, option->rect.bottom() - 6, 5, 5); if (option->state & QStyle::State_Sunken) { r.adjust(1, 1, 1, 1); } } else { r = QRect(2, option->rect.bottom() - 6, 5, 5); if (option->state & QStyle::State_Sunken) { r.adjust(-1, 1, -1, 1); } } QFont font; font.setPixelSize(7); opt.fontMetrics = QFontMetrics(font); opt.rect = r; style->drawPrimitive(inVerticalToolBar(option, widget) ? QStyle::PE_IndicatorArrowRight : QStyle::PE_IndicatorArrowDown, &opt, painter, widget); } } else { ((QCommonStyle *) style)->QCommonStyle::drawComplexControl(QStyle::CC_ToolButton, option, painter, widget); } } void paintToolButtonLabel(QPainter *painter, const QStyleOptionToolButton *option, const QWidget *widget, const QStyle *style) { QStyleOptionToolButton opt = *option; if (option->state & QStyle::State_AutoRaise) { if (!(option->state & QStyle::State_Enabled) || !(option->state & QStyle::State_MouseOver)) { opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::WindowText)); } } ((QCommonStyle *) style)->QCommonStyle::drawControl(QStyle::CE_ToolButtonLabel, &opt, painter, widget); } /*-----------------------------------------------------------------------*/ QRect subControlRectToolButton(const QStyleOptionToolButton *option, QStyle::SubControl subControl, const QWidget *widget, const QStyle *style) { QRect r = option->rect; if (option->features & QStyleOptionToolButton::Menu) { int pm = style->pixelMetric(QStyle::PM_MenuButtonIndicator, option, widget) - 2; bool verticalBar = inVerticalToolBar(option, widget); switch (subControl) { case QStyle::SC_ToolButton: if (verticalBar) { r.adjust(0, 0, 0, -pm); } else { r.adjust(0, 0, -pm, 0); } break; case QStyle::SC_ToolButtonMenu: if (verticalBar) { r.adjust(0, r.height() - pm - 2, 0, 0); } else { r.adjust(r.width() - pm - 2, 0, 0, 0); } break; default: break; } return style->visualRect(option->direction, option->rect, r); } return ((QCommonStyle *) style)->QCommonStyle::subControlRect(QStyle::CC_ToolButton, option, subControl, widget); } QSize sizeFromContentsToolButton(const QStyleOptionToolButton *option, const QSize &contentsSize, const QWidget *widget, const QStyle *style, int toolButtonSize) { QSize size = contentsSize + QSize(4, 4); if (toolButtonSize >= 0) { if (option->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { size += QSize(toolButtonSize, qMax(2, toolButtonSize)); } else { size += QSize(toolButtonSize, toolButtonSize); } } else { size += QSize(4, 4); } if (widget && !qstrcmp(widget->metaObject()->className(), "KAnimatedButton")) { return contentsSize + QSize(4, 4); } if (widget && !qstrcmp(widget->metaObject()->className(), "QtColorButton")) { return contentsSize + QSize(12, 12); } if (option->features & QStyleOptionToolButton::Menu) { int pm = style->pixelMetric(QStyle::PM_MenuButtonIndicator, option, widget); size -= QSize(pm, 0); pm -= 2; bool verticalBar = inVerticalToolBar(option, widget); if (verticalBar) { size += QSize(0, pm); } else { size += QSize(pm, 0); } } return size; } /*-----------------------------------------------------------------------*/ void SkulptureStyle::Private::updateToolBarOrientation(Qt::Orientation /*orientation */) { QToolBar *toolbar = static_cast(sender()); QList toolbuttons = toolbar->findChildren(); bool changed = false; Q_FOREACH (QToolButton *toolbutton, toolbuttons) { if (toolbutton->popupMode() == QToolButton::MenuButtonPopup) { // ### this hack forces Qt to invalidate the size hint Qt::ToolButtonStyle oldstyle = toolbutton->toolButtonStyle(); Qt::ToolButtonStyle newstyle; if (oldstyle == Qt::ToolButtonIconOnly) { newstyle = Qt::ToolButtonTextOnly; } else { newstyle = Qt::ToolButtonIconOnly; } toolbutton->setToolButtonStyle(newstyle); toolbutton->setToolButtonStyle(oldstyle); changed = true; } } if (changed) { // ### Qt does not update dragged toolbars... toolbar->updateGeometry(); } } /* * skulpture_p.cpp * */ #include "skulpture_p.h" #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) #include #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) #include #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) #include #endif /*-----------------------------------------------------------------------*/ struct StyleSetting { enum Type { Bool, Char, Frame, Alignment, Orientation, Pixels, Points, Milliseconds, Color, Size, Parent, VarParent, Value }; const char * const label; int id; int type; int value; }; static const struct StyleSetting styleHintSettings[] = { /* entries are stricly sorted in Qt order for future lookup table */ { "General/EtchDisabledText", QStyle::SH_EtchDisabledText, StyleSetting::Bool, 1 }, /// { "General/DitherDisabledText", QStyle::SH_DitherDisabledText, StyleSetting::Bool, 0 }, { "ScrollBar/MiddleClickAbsolutePosition", QStyle::SH_ScrollBar_MiddleClickAbsolutePosition, StyleSetting::Bool, 1 }, // { "ScrollBar/ScrollWhenPointerLeavesControl", QStyle::SH_ScrollBar_ScrollWhenPointerLeavesControl, StyleSetting::Parent, 0 }, // { "TabWidget/SelectMouseType", QStyle::SH_TabBar_SelectMouseType, StyleSetting::Parent, 0 }, /// { "TabWidget/TabBarAlignment", QStyle::SH_TabBar_Alignment, StyleSetting::Alignment, Qt::AlignCenter }, // { "ItemView/HeaderArrowAlignment", QStyle::SH_Header_ArrowAlignment, StyleSetting::Parent, 0 }, { "Slider/SnapToValue", QStyle::SH_Slider_SnapToValue, StyleSetting::Bool, 1 }, // { "Slider/SloppyKeyEvents", QStyle::SH_Slider_SloppyKeyEvents, StyleSetting::Parent, 0 }, // { "ProgressDialog/CenterCancelButton", QStyle::SH_ProgressDialog_CenterCancelButton, StyleSetting::Parent, 0 }, // { "ProgressDialog/TextLabelAlignment", QStyle::SH_ProgressDialog_TextLabelAlignment, StyleSetting::Parent, 0 }, { "PrintDialog/RightAlignButtons", QStyle::SH_PrintDialog_RightAlignButtons, StyleSetting::Bool, 1 }, // { "Window/SpaceBelowMenuBar", QStyle::SH_MainWindow_SpaceBelowMenuBar, StyleSetting::Parent, 0 }, { "FontDialog/SelectAssociatedText", QStyle::SH_FontDialog_SelectAssociatedText, StyleSetting::Bool, 1 }, { "Menu/AllowActiveAndDisabled", QStyle::SH_Menu_AllowActiveAndDisabled, StyleSetting::Bool, 1 }, // { "Menu/SpaceActivatesItem", QStyle::SH_Menu_SpaceActivatesItem, StyleSetting::Parent, 0 }, // ### dynamic { "Menu/SubMenuPopupDelay", QStyle::SH_Menu_SubMenuPopupDelay, StyleSetting::Milliseconds, 100 }, /// { "ItemView/FrameOnlyAroundContents", QStyle::SH_ScrollView_FrameOnlyAroundContents, StyleSetting::Bool, 0 }, { "Menu/AltKeyNavigation", QStyle::SH_MenuBar_AltKeyNavigation, StyleSetting::Bool, 1 }, { "ComboBox/ListMouseTracking", QStyle::SH_ComboBox_ListMouseTracking, StyleSetting::Bool, 1 }, { "Menu/MouseTracking", QStyle::SH_Menu_MouseTracking, StyleSetting::Bool, 1 }, { "Menu/BarMouseTracking", QStyle::SH_MenuBar_MouseTracking, StyleSetting::Bool, 1 }, // { "ItemView/ChangeHighlightOnFocus", QStyle::SH_ItemView_ChangeHighlightOnFocus, StyleSetting::Parent, 0 }, // { "Window/ShareActivation", QStyle::SH_Widget_ShareActivation, StyleSetting::Parent, 0 }, // { "MDI/Workspace/FillSpaceOnMaximize", QStyle::SH_Workspace_FillSpaceOnMaximize, StyleSetting::Parent, 0 }, // { "ComboBox/Popup", QStyle::SH_ComboBox_Popup, StyleSetting::Parent, 0 }, /// { "MDI/TitleBar/NoBorder", QStyle::SH_TitleBar_NoBorder, StyleSetting::Bool, 0 }, #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) /// { "Slider/StopMouseOverSlider", QStyle::SH_Slider_StopMouseOverSlider, StyleSetting::Bool, 1 }, #else /// { "Slider/StopMouseOverSlider", QStyle::SH_ScrollBar_StopMouseOverSlider, StyleSetting::Bool, 1 }, #endif // { "General/BlinkCursorWhenTextSelected", QStyle::SH_BlinkCursorWhenTextSelected, StyleSetting::Parent, 0 }, // { "General/FullWidthSelection", QStyle::SH_RichText_FullWidthSelection, StyleSetting::Bool, 1 }, // { "Menu/Scrollable", QStyle::SH_Menu_Scrollable, StyleSetting::Parent, 0 }, // { "GroupBox/TextLabelVerticalAlignment", QStyle::SH_GroupBox_TextLabelVerticalAlignment, StyleSetting::Parent, 0 }, // ### dynamic { "GroupBox/TextLabelColor", QStyle::SH_GroupBox_TextLabelColor, StyleSetting::Color, 0xFF000000 }, // { "Menu/SloppySubMenus", QStyle::SH_Menu_SloppySubMenus, StyleSetting::Parent, 0 }, // ### dynamic { "ItemView/GridLineColor", QStyle::SH_Table_GridLineColor, StyleSetting::Color, 0xFFD0D0D0 }, // ### dynamic { "LineEdit/PasswordCharacter", QStyle::SH_LineEdit_PasswordCharacter, StyleSetting::Char, 10039 }, // { "Dialog/DefaultButton", QStyle::SH_DialogButtons_DefaultButton, StyleSetting::Parent, 0 }, // { "ToolBox/SelectedPageTitleBold", QStyle::SH_ToolBox_SelectedPageTitleBold, StyleSetting::Bool, 1 }, // { "TabWidget/TabBarPreferNoArrows", QStyle::SH_TabBar_PreferNoArrows, StyleSetting::Parent, 0 }, // { "ScrollBar/LeftClickAbsolutePosition", QStyle::SH_ScrollBar_LeftClickAbsolutePosition, StyleSetting::Parent, 0 }, // { "ItemView/Compat/ExpansionSelectMouseType", QStyle::SH_Q3ListViewExpand_SelectMouseType, StyleSetting::Parent, 0 }, // ### dynamic { "General/UnderlineShortcut", QStyle::SH_UnderlineShortcut, StyleSetting::Bool, 0 }, // { "SpinBox/AnimateButton", QStyle::SH_SpinBox_AnimateButton, StyleSetting::Parent, 0 }, // { "SpinBox/KeyPressAutoRepeatRate", QStyle::SH_SpinBox_KeyPressAutoRepeatRate, StyleSetting::Parent, 0 }, // { "SpinBox/ClickAutoRepeatRate", QStyle::SH_SpinBox_ClickAutoRepeatRate, StyleSetting::Parent, 0 }, // { "Menu/FillScreenWithScroll", QStyle::SH_Menu_FillScreenWithScroll, StyleSetting::Parent, 0 }, // { "ToolTip/Opacity", QStyle::SH_ToolTipLabel_Opacity, StyleSetting::Parent, 0 }, // { "Menu/DrawMenuBarSeparator", QStyle::SH_DrawMenuBarSeparator, StyleSetting::Parent, 0 }, // { "MDI/TitleBar/ModifyNotification", QStyle::SH_TitleBar_ModifyNotification, StyleSetting::Parent, 0 }, // { "Button/FocusPolicy", QStyle::SH_Button_FocusPolicy, StyleSetting::Parent, 0 }, // { "Menu/DismissOnSecondClick", QStyle::SH_MenuBar_DismissOnSecondClick, StyleSetting::Parent, 0 }, // { "MessageBox/UseBorderForButtonSpacing", QStyle::SH_MessageBox_UseBorderForButtonSpacing, StyleSetting::Parent, 0 }, { "MDI/TitleBar/AutoRaise", QStyle::SH_TitleBar_AutoRaise, StyleSetting::Bool, 1 }, { "ToolBar/PopupDelay", QStyle::SH_ToolButton_PopupDelay, StyleSetting::Milliseconds, 250 }, // ### dynamic { "General/FocusFrameMask", QStyle::SH_FocusFrame_Mask, StyleSetting::Parent, 0 }, // ### dynamic { "General/RubberBandMask", QStyle::SH_RubberBand_Mask, StyleSetting::Parent, 0 }, // ### dynamic { "General/WindowFrameMask", QStyle::SH_WindowFrame_Mask, StyleSetting::Parent, 0 }, // { "SpinBox/DisableControlsOnBounds", QStyle::SH_SpinControls_DisableOnBounds, StyleSetting::Parent, 0 }, // { "Dial/BackgroundRole", QStyle::SH_Dial_BackgroundRole, StyleSetting::Parent, 0 }, // { "ComboBox/LayoutDirection", QStyle::SH_ComboBox_LayoutDirection, StyleSetting::Parent, 0 }, // { "ItemView/EllipsisLocation", QStyle::SH_ItemView_EllipsisLocation, StyleSetting::Parent, 0 }, // { "ItemView/ShowDecorationSelected", QStyle::SH_ItemView_ShowDecorationSelected, StyleSetting::Parent, 0 }, // ### from KDE { "ItemView/ActivateItemOnSingleClick", QStyle::SH_ItemView_ActivateItemOnSingleClick, StyleSetting::Bool, 1 }, // { "ScrollBar/ContextMenu", QStyle::SH_ScrollBar_ContextMenu, StyleSetting::Parent, 0 }, // { "ScrollBar/RollBetweenButtons", QStyle::SH_ScrollBar_RollBetweenButtons, StyleSetting::Parent, 0 }, #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) // { "Slider/AbsoluteSetButtons", QStyle::SH_Slider_AbsoluteSetButtons, StyleSetting::Parent, 0 }, // { "Slider/PageSetButtons", QStyle::SH_Slider_PageSetButtons, StyleSetting::Parent, 0 }, // { "Menu/KeyboardSearch", QStyle::SH_Menu_KeyboardSearch, StyleSetting::Parent, 0 }, // { "TabWidget/ElideMode", QStyle::SH_TabBar_ElideMode, StyleSetting::Parent, 0 }, #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) // { "Dialog/ButtonLayout", QStyle::SH_DialogButtonLayout, StyleSetting::Value, QDialogButtonBox::KdeLayout }, #else { "Dialog/ButtonLayout", QStyle::SH_DialogButtonLayout, StyleSetting::Value, QDialogButtonBox::KdeLayout }, #endif // { "ComboBox/PopupFrameStyle", QStyle::SH_ComboBox_PopupFrameStyle, StyleSetting::Parent, 0 }, { "MessageBox/AllowTextInteraction", QStyle::SH_MessageBox_TextInteractionFlags, StyleSetting::Bool, 1 }, // ### from KDE { "Dialog/ButtonsHaveIcons", QStyle::SH_DialogButtonBox_ButtonsHaveIcons, StyleSetting::Bool, 0 }, // { "General/SpellCheckUnderlineStyle", QStyle::SH_SpellCheckUnderlineStyle, StyleSetting::Parent, 0 }, { "MessageBox/CenterButtons", QStyle::SH_MessageBox_CenterButtons, StyleSetting::Bool, 0 }, // { "Menu/SelectionWrap", QStyle::SH_Menu_SelectionWrap, StyleSetting::Parent, 0 }, // { "ItemView/MovementWithoutUpdatingSelection", QStyle::SH_ItemView_MovementWithoutUpdatingSelection, StyleSetting::Parent, 0 }, #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) // ### dynamic { "General/ToolTipMask", QStyle::SH_ToolTip_Mask, StyleSetting::Parent, 0 }, // { "General/FocusFrameAboveWidget", QStyle::SH_FocusFrame_AboveWidget, StyleSetting::Parent, 0 }, // { "General/FocusIndicatorTextCharFormat", QStyle::SH_TextControl_FocusIndicatorTextCharFormat, StyleSetting::Parent, 0 }, // { "Dialog/WizardStyle", QStyle::SH_WizardStyle, StyleSetting::Value, QWizard::ModernStyle }, { "ItemView/ArrowKeysNavigateIntoChildren", QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, StyleSetting::Bool, 1 }, // ### dynamic { "General/MenuMask", QStyle::SH_Menu_Mask, StyleSetting::Parent, 0 }, #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) // { "Menu/FlashTriggeredItem", QStyle::SH_Menu_FlashTriggeredItem, StyleSetting::Parent, 0 }, // { "Menu/FadeOutOnHide", QStyle::SH_Menu_FadeOutOnHide, StyleSetting::Parent, 0 }, // { "SpinBox/ClickAutoRepeatThreshold", QStyle::SH_SpinBox_ClickAutoRepeatThreshold, StyleSetting::Parent, 0 }, // { "ItemView/PaintAlternatingRowColorsForEmptyArea", QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea, StyleSetting::Parent, 0 }, // { "FormLayout/WrapPolicy", QStyle::SH_FormLayoutWrapPolicy, StyleSetting::Value, QFormLayout::DontWrapRows }, // { "TabWidget/DefaultTabPosition", QStyle::SH_TabWidget_DefaultTabPosition, StyleSetting::Parent, 0 }, // { "ToolBar/Movable", QStyle::SH_ToolBar_Movable, StyleSetting::Parent, 0 }, { "FormLayout/FieldGrowthPolicy", QStyle::SH_FormLayoutFieldGrowthPolicy, StyleSetting::Value, QFormLayout::ExpandingFieldsGrow }, // { "FormLayout/FormAlignment", QStyle::SH_FormLayoutFormAlignment, StyleSetting::Alignment, Qt::AlignLeft | Qt::AlignTop }, { "FormLayout/LabelAlignment", QStyle::SH_FormLayoutLabelAlignment, StyleSetting::Alignment, Qt::AlignRight | Qt::AlignTop }, #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) // { "ItemView/DrawDelegateFrame", QStyle::SH_, StyleSetting::Parent, 0 }, // { "TabWidget/CloseButtonPosition", QStyle::SH_TabBar_CloseButtonPosition, StyleSetting::Parent, 0 }, // { "DockWidget/ButtonsHaveFrame", QStyle::SH_DockWidget_ButtonsHaveFrame, StyleSetting::Parent, 0 }, #endif { 0, -1, 0, 0 } }; extern int getRubberBandMask(QStyleHintReturnMask *mask, const QStyleOption *option, const QWidget *widget); extern int getWindowFrameMask(QStyleHintReturnMask *mask, const QStyleOptionTitleBar *option, const QWidget *widget); int SkulptureStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const { // return ParentStyle::styleHint(hint, option, widget, returnData); // TODO implement caching const StyleSetting *setting = &styleHintSettings[0]; QVariant value; switch (hint) { case QStyle::SH_Menu_SubMenuPopupDelay: { return d->subMenuDelay; } case QStyle::SH_TabBar_Alignment: { return d->centerTabs ? Qt::AlignHCenter : Qt::AlignLeft; } #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) case QStyle::SH_Slider_StopMouseOverSlider: { #else case QStyle::SH_ScrollBar_StopMouseOverSlider: { #endif // this works around a bug with Qt 4.4.2 return qobject_cast(widget) != 0; } case QStyle::SH_ItemView_ActivateItemOnSingleClick: { if (d->useSingleClickToActivateItems != -1) { return d->useSingleClickToActivateItems; } // use platform setting break; } #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) case QStyle::SH_DialogButtonBox_ButtonsHaveIcons: { // ### use KDE setting return 0; } #endif #if 1 case QStyle::SH_GroupBox_TextLabelColor: { QPalette palette; if (option) { palette = option->palette; } else if (widget) { palette = widget->palette(); } return palette.color(QPalette::WindowText).rgba(); } #endif case QStyle::SH_Table_GridLineColor: { QPalette palette; if (option) { palette = option->palette; } else if (widget) { palette = widget->palette(); } #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) return palette.color(QPalette::Base).darker(120).rgba(); #else return palette.color(QPalette::Base).dark(120).rgba(); #endif } case QStyle::SH_LineEdit_PasswordCharacter: { QFontMetrics fm = option ? option->fontMetrics : (widget ? widget->fontMetrics() : QFontMetrics(QFont())); for (int i = 0; i < d->passwordCharacters.length(); ++i) { if (fm.inFont(d->passwordCharacters.at(i))) { return d->passwordCharacters.at(i).unicode(); } } return int('*'); } case QStyle::SH_UnderlineShortcut: { if (d->hideShortcutUnderlines) { return (d->shortcut_handler->underlineShortcut(widget)); } return true; } case QStyle::SH_RubberBand_Mask: { QStyleHintReturnMask *mask = qstyleoption_cast(returnData); if (mask) { return getRubberBandMask(mask, option, widget); } return 0; } case QStyle::SH_WindowFrame_Mask: { QStyleHintReturnMask *mask = qstyleoption_cast(returnData); const QStyleOptionTitleBar *titleBarOption = qstyleoption_cast(option); if (mask && titleBarOption) { return getWindowFrameMask(mask, titleBarOption, widget); } return 0; } default: break; } while (setting->label) { if (setting->id == int(hint)) { break; } ++setting; } if (setting->label) { value = setting->value; switch (setting->type) { case StyleSetting::Parent: value = ParentStyle::styleHint(hint, option, widget, returnData); break; case StyleSetting::Bool: value = setting->value != 0; break; case StyleSetting::Char: value = QString(QChar(setting->value)); break; case StyleSetting::Color: value = QChar('#', 0) + QString::number(value.toInt() - qRgba(0, 0, 0, 255), 16); break; } } else { value = ParentStyle::styleHint(hint, option, widget, returnData); setting = 0; } #if 1 if (setting && d->settings && setting->type != StyleSetting::Parent && !d->settings->contains(QLatin1String(setting->label))) { d->settings->setValue(QLatin1String(setting->label), value); } #endif if (setting) { if (d->settings) { value = d->settings->value(QLatin1String(setting->label), value); } switch (setting->type) { case StyleSetting::Color: value = qRgba(0, 0, 0, 255) + value.toString().mid(1).toInt(0, 16); break; case StyleSetting::Bool: value = value.toBool(); break; case StyleSetting::Char: QString s = value.toString(); if (s.size() == 1) { return s.at(0).unicode(); } return setting->value; } } return value.toInt(); } /*-----------------------------------------------------------------------*/ /* * Read color out of current settings group * * color - where to store the resulting color * s - Settings * colorName - name of color, such as "checkMark", first letter should be not be capitalized * n - for multiple color entries, returns the "n"th color (n = 1, 2, ...) otherwise use n = 0. * * This will do the following: * * 1. check if "customColor" is set to "false" -> return false with "color" unmodified * 2. read color entry from "Color" * 3. read color opacity from "ColorOpacity" * 4. return true with "color" modified accordingly * */ static bool readSettingsColor(QColor &color, const QSettings &s, const QString &colorName, int n = 0) { QString cName = colorName + QLatin1String("Color"); if (n > 0) { cName += QString::number(n); } if (s.value(QLatin1String("custom") + cName.at(0).toUpper() + cName.mid(1), true).toBool() == false) { return false; } QString val = s.value(cName).toString(); if (!val.isEmpty()) { QColor c = QColor(val); if (c.isValid()) { color = c; int opacity = s.value(cName + QLatin1String("Opacity"), -1).toInt(); if (opacity >= 0 && opacity <= 255) { color.setAlpha(opacity); } return true; } } return false; } /*-----------------------------------------------------------------------*/ /* * Read gradient out of current settings group * * gradient - where to store the resulting gradient (only the color stops are modified) * s - Settings * gradientName - name of gradient, such as "activeTabTop", first letter should be not be capitalized * * This returns true with "gradient" colors modified accordingly, or false, if no color was found. * * Limitations: * * Maximum number of gradients per background: 9 * Maximum number of colors per gradient: 2 * */ #define MIN_STOP 0 // must be 0 #define MAX_STOP 100 static inline qreal topToStop(int v) { if (v <= MIN_STOP) { return qreal(0.00000); } else if (v >= MAX_STOP) { return qreal(0.99999); } return v / qreal(MAX_STOP) - qreal(0.00001); } static inline qreal bottomToStop(int v) { if (v <= 0) { return qreal(0.00001); } else if (v >= MAX_STOP) { return qreal(1.00000); } return v / qreal(MAX_STOP) + qreal(0.00001); } static bool readSettingsGradient(QGradient &gradient, const QSettings &s, const QString &gradientName) { QColor background(s.value(gradientName + QLatin1String("background")).toString()); if (!background.isValid()) { return false; } bool hasTop = false; bool hasBottom = false; int numGradients = s.value(gradientName + QLatin1String("numGradients"), 0).toInt(); numGradients = qMin(numGradients, 9); // single digit limit for (int i = 1; i <= numGradients; ++i) { QString gradientPrefix = gradientName + QChar('g', 0) + QChar('0' + i, 0); int top = s.value(gradientPrefix + QLatin1String("Top"), -1).toInt(); int bottom = s.value(gradientPrefix + QLatin1String("Bottom"), -1).toInt(); if (top == MIN_STOP) { hasTop = true; } if (bottom == MAX_STOP) { hasBottom = true; } if (top >= 0 && bottom >= 0) { QColor c[9 + 1]; int k = 0; for (int n = 1; n <= 9; ++n) { // single digit limit if (readSettingsColor(c[n], s, gradientPrefix, n)) { ++k; } else { // force continous color numbering break; } } // k colors are found, spread lineary between top ... bottom if (k > 1) { // FIXME blindly assumes k == 2 for now gradient.setColorAt(topToStop(top), c[1]); gradient.setColorAt(bottomToStop(bottom), c[2]); } else if (k == 1) { gradient.setColorAt(topToStop(top), c[1]); gradient.setColorAt(bottomToStop(bottom), c[1]); } } } // FIXME does not detect "holes" between gradients // that are to be "filled" with background if (!hasTop) { gradient.setColorAt(0, background); } if (!hasBottom) { gradient.setColorAt(1, background); } return true; } /*-----------------------------------------------------------------------*/ /* * Read domino settings out of current settings group * */ void SkulptureStyle::Private::readDominoSettings(const QSettings &s) { static const char * const gradientName[] = { "tabTop", "tabBottom", "activeTabTop", "activeTabBottom", "btn", "checkItem", "header", "scrollBar", "scrollBarGroove" }; static const char * const colorName[] = { "checkMark", "groupBoxBackground", "popupMenu", "selMenuItem", "toolTip" }; for (uint i = 0; i < array_elements(gradientName); ++i) { QGradient gradient; if (readSettingsGradient(gradient, s, QLatin1String(gradientName[i]) + QLatin1String("Surface_"))) { #if 0 printf("domino: gradient[%s]=", gradientName[i]); QGradientStops stops = gradient.stops(); for (int i = 0; i < stops.size(); ++i) { QGradientStop stop = stops.at(i); QColor color = stop.second; printf("(%.6g=#%2x%2x%2x/a=#%2x)", stop.first, color.red(), color.green(), color.blue(), color.alpha()); } printf("\n"); #endif // only save stops from the gradient // dominoGradientStops[i] = gradient.stops(); } } for (uint i = 0; i < array_elements(colorName); ++i) { QColor color; if (readSettingsColor(color, s, QLatin1String(colorName[i]))) { #if 0 printf("domino: color[%s]=#%2x%2x%2x/a=#%2x\n", colorName[i], color.red(), color.green(), color.blue(), color.alpha()); #endif // dominoCustomColors[i] = color; } } animateProgressBars = s.value(QLatin1String("animateProgressBar"), animateProgressBars).toBool(); centerTabs = s.value(QLatin1String("centerTabs"), centerTabs).toBool(); #if 0 readSettingsColor(buttonContourColor, s, QLatin1String("buttonContour")); readSettingsColor(buttonDefaultContourColor, s, QLatin1String("buttonDefaultContour")); readSettingsColor(buttonMouseOverContourColor, s, QLatin1String("buttonMouseOverContour")); readSettingsColor(buttonPressedContourColor, s, QLatin1String("buttonPressedContour")); readSettingsColor(indicatorButtonColor, s, QLatin1String("indicatorButton")); readSettingsColor(indicatorColor, s, QLatin1String("indicator")); readSettingsColor(rubberBandColor, s, QLatin1String("rubberBand")); readSettingsColor(textEffectButtonColor, s, QLatin1String("textEffectButton")); readSettingsColor(textEffectColor, s, QLatin1String("textEffect")); highlightToolBtnIcon = s.value(QLatin1String("highlightToolBtnIcon"), highlightToolBtnIcon).toBool(); indentPopupMenuItems = s.value(QLatin1String("indentPopupMenuItems"), indentPopupMenuItems).toBool(); smoothScrolling = s.value(QLatin1String("smoothScrolling"), smoothScrolling).toBool(); tintGroupBoxBackground = s.value(QLatin1String("tintGroupBoxBackground"), tintGroupBoxBackground).toBool(); indicateFocus = s.value(QLatin1String("indicateFocus"), indicateFocus).toBool(); drawButtonSunkenShadow = s.value(QLatin1String("drawButtonSunkenShadow"), drawButtonSunkenShadow).toBool(); drawFocusUnderline = s.value(QLatin1String("drawFocusUnderline"), drawFocusUnderline).toBool(); drawPopupMenuGradient = s.value(QLatin1String("drawPopupMenuGradient"), drawPopupMenuGradient).toBool(); drawTextEffect = s.value(QLatin1String("drawTextEffect"), drawTextEffect).toBool(); drawToolButtonAsButton = s.value(QLatin1String("drawToolButtonAsButton"), drawToolButtonAsButton).toBool(); drawTriangularExpander = s.value(QLatin1String("drawTriangularExpander"), drawTriangularExpander).toBool(); #endif } /*-----------------------------------------------------------------------*/ void SkulptureStyle::Private::readSettings(const QSettings &s) { // defaults animateProgressBars = true; verticalArrowMode = SkulptureMode; horizontalArrowMode = SkulptureMode; hideShortcutUnderlines = true; centerTabs = false; makeDisabledWidgetsTransparent = true; transparentPlacesPanel = false; forceSpacingAndMargins = false; visualizeLayouts = false; useIconColumnForCheckIndicators = false; useSelectionColorForCheckedIndicators = false; useSelectionColorForSelectedMenuItems = false; useSingleClickToActivateItems = runtimeQtVersion() >= QT_VERSION_CHECK(4, 6, 0) ? -1 : 1; expensiveShadows = true; allowTabulations = false; dialogMargins = -1; horizontalSpacing = -1; labelSpacing = -1; menuBarSize = -1; menuItemSize = -1; pushButtonSize = -1; scrollBarSize = -1; scrollBarLength = -1; sliderSize = -1; sliderLength = -1; tabBarSize = -1; toolButtonSize = -1; verticalSpacing = -1; widgetMargins = -1; widgetSize = -1; textShift = 0; buttonGradient = 0; buttonRoundness = 0; passwordCharacters = QString(QChar(ushort(10039))); textCursorWidth = 0; subMenuDelay = 100; // legacy settings import: domino 0.4 QString dominoConfigFile = s.value(QLatin1String("LegacyImport/DominoConfiguration")).toString(); if (!dominoConfigFile.isEmpty()) { QSettings s(dominoConfigFile, QSettings::IniFormat); s.beginGroup(QLatin1String("Settings")); readDominoSettings(s); s.endGroup(); } // native settings animateProgressBars = s.value(QLatin1String("ProgressBar/AnimateProgressBars"), animateProgressBars).toBool(); if (s.contains(QLatin1String("ScrollBar/AllowScrollBarSliderToCoverArrows")) && !s.contains(QLatin1String("ScrollBar/VerticalArrowMode"))) { verticalArrowMode = s.value(QLatin1String("ScrollBar/AllowScrollBarSliderToCoverArrows"), true).toBool() ? SkulptureMode : WindowsMode; } else { QString mode = s.value(QLatin1String("ScrollBar/VerticalArrowMode"), QLatin1String("Covered")).toString(); if (mode == QLatin1String("Top")) { verticalArrowMode = NextMode; } else if (mode == QLatin1String("Bottom")) { verticalArrowMode = PlatinumMode; } else if (mode == QLatin1String("BottomTop") || mode == QLatin1String("Bottom/Top")) { verticalArrowMode = WindowsMode; } else if (mode == QLatin1String("KDEMode")) { verticalArrowMode = KDEMode; } else if (mode == QLatin1String("Covered")) { verticalArrowMode = SkulptureMode; } else if (mode == QLatin1String("None")) { verticalArrowMode = NoArrowsMode; } else { verticalArrowMode = SkulptureMode; } } if (s.contains(QLatin1String("ScrollBar/AllowScrollBarSliderToCoverArrows")) && !s.contains(QLatin1String("ScrollBar/HorizontalArrowMode"))) { horizontalArrowMode = s.value(QLatin1String("ScrollBar/AllowScrollBarSliderToCoverArrows"), true).toBool() ? SkulptureMode : WindowsMode; } else { QString mode = s.value(QLatin1String("ScrollBar/HorizontalArrowMode"), QLatin1String("Covered")).toString(); if (mode == QLatin1String("Left")) { horizontalArrowMode = NextMode; } else if (mode == QLatin1String("Right")) { horizontalArrowMode = PlatinumMode; } else if (mode == QLatin1String("RightLeft") || mode == QLatin1String("Right/Left")) { horizontalArrowMode = WindowsMode; } else if (mode == QLatin1String("KDEMode")) { horizontalArrowMode = KDEMode; } else if (mode == QLatin1String("Covered")) { horizontalArrowMode = SkulptureMode; } else if (mode == QLatin1String("None")) { horizontalArrowMode = NoArrowsMode; } else { horizontalArrowMode = SkulptureMode; } } hideShortcutUnderlines = s.value(QLatin1String("General/HideShortcutUnderlines"), hideShortcutUnderlines).toBool(); makeDisabledWidgetsTransparent = s.value(QLatin1String("General/MakeDisabledWidgetsTransparent"), makeDisabledWidgetsTransparent).toBool(); transparentPlacesPanel = s.value(QLatin1String("Views/TransparentPlacesPanel"), transparentPlacesPanel).toBool(); forceSpacingAndMargins = s.value(QLatin1String("Layout/ForceSpacingAndMargins"), forceSpacingAndMargins).toBool(); visualizeLayouts = s.value(QLatin1String("Layout/VisualizeLayouts"), visualizeLayouts).toBool(); useIconColumnForCheckIndicators = s.value(QLatin1String("Menus/UseIconColumnForCheckIndicators"), useIconColumnForCheckIndicators).toBool(); useSelectionColorForCheckedIndicators = s.value(QLatin1String("General/UseSelectionColorForCheckedIndicators"), useSelectionColorForCheckedIndicators).toBool(); useSelectionColorForSelectedMenuItems = s.value(QLatin1String("Menus/UseSelectionColorForSelectedMenuItems"), useSelectionColorForSelectedMenuItems).toBool(); if (s.contains(QLatin1String("General/UseSingleClickToActivateItems"))) { bool singleClick = s.value(QLatin1String("General/UseSingleClickToActivateItems"), true).toBool(); useSingleClickToActivateItems = singleClick ? 1 : 0; } expensiveShadows = s.value(QLatin1String("General/ExpensiveShadows"), expensiveShadows).toBool(); allowTabulations = s.value(QLatin1String("General/AllowTabulations"), allowTabulations).toBool(); dialogMargins = s.value(QLatin1String("Layout/DialogMargins"), dialogMargins).toInt(); horizontalSpacing = s.value(QLatin1String("Layout/HorizontalSpacing"), horizontalSpacing).toInt(); labelSpacing = s.value(QLatin1String("Layout/LabelSpacing"), labelSpacing).toInt(); menuBarSize = s.value(QLatin1String("Layout/MenuBarSize"), menuBarSize).toInt(); menuItemSize = s.value(QLatin1String("Layout/MenuItemSize"), menuItemSize).toInt(); pushButtonSize = s.value(QLatin1String("Layout/PushButtonSize"), pushButtonSize).toInt(); scrollBarSize = s.value(QLatin1String("Layout/ScrollBarSize"), scrollBarSize).toInt(); scrollBarLength = s.value(QLatin1String("Layout/ScrollBarLength"), scrollBarLength).toInt(); sliderSize = s.value(QLatin1String("Layout/SliderSize"), sliderSize).toInt(); sliderLength = s.value(QLatin1String("Layout/SliderLength"), sliderLength).toInt(); tabBarSize = s.value(QLatin1String("Layout/TabBarSize"), tabBarSize).toInt(); toolButtonSize = s.value(QLatin1String("Layout/ToolButtonSize"), toolButtonSize).toInt(); verticalSpacing = s.value(QLatin1String("Layout/VerticalSpacing"), verticalSpacing).toInt(); widgetMargins = s.value(QLatin1String("Layout/WidgetMargins"), widgetMargins).toInt(); widgetSize = s.value(QLatin1String("Layout/WidgetSize"), widgetSize).toInt(); textShift = s.value(QLatin1String("General/TextShift"), textShift).toInt(); buttonGradient = s.value(QLatin1String("General/ButtonGradientIntensity"), buttonGradient).toInt(); buttonRoundness = s.value(QLatin1String("General/ButtonRoundness"), buttonRoundness).toInt(); passwordCharacters = s.value(QLatin1String("General/PasswordCharacters"), passwordCharacters).toString(); styleSheetFileName = s.value(QLatin1String("General/StyleSheetFileName"), QString()).toString(); textCursorWidth = s.value(QLatin1String("General/TextCursorWidth"), (double) textCursorWidth).toDouble(); subMenuDelay = s.value(QLatin1String("Menus/SubMenuDelay"), subMenuDelay).toInt(); // apply defaults if (widgetSize < 0) { widgetSize = 2; } if (pushButtonSize < 0) { pushButtonSize = 2; } if (tabBarSize < 0) { tabBarSize = 2; } if (menuItemSize < 0) { menuItemSize = 2; } } int SkulptureStyle::skulpturePrivateMethod(SkulptureStyle::SkulpturePrivateMethod id, void *data) { switch (id) { case SPM_SupportedMethods: { return SPM_SetSettingsFileName; } case SPM_SetSettingsFileName: { SkMethodDataSetSettingsFileName *md = (SkMethodDataSetSettingsFileName *) data; if (md && md->version >= 1) { QSettings s(md->fileName, QSettings::IniFormat); if (s.status() == QSettings::NoError) { d->readSettings(s); return 1; } } return 0; } default: return 0; } } /*-----------------------------------------------------------------------*/ void paintNothing(QPainter */*painter*/, const QStyleOption */*option*/, const QWidget */*widget*/, const QStyle */*style*/) { // } void paintDefault(QPainter */*painter*/, const QStyleOption */*option*/, const QWidget */*widget*/, const QStyle */*style*/) { // } /*-----------------------------------------------------------------------*/ void paintCommandButtonPanel(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style); void paintPushButtonBevel(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style); void paintTabWidgetFrame(QPainter *painter, const QStyleOptionTabWidgetFrame *option, const QWidget *widget, const QStyle *style); void paintIndicatorCheckBox(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style); void paintIndicatorItemViewItemCheck(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) void paintQ3CheckListIndicator(QPainter *painter, const QStyleOptionQ3ListView *option, const QWidget *widget, const QStyle *style); void paintQ3CheckListExclusiveIndicator(QPainter *painter, const QStyleOptionQ3ListView *option, const QWidget *widget, const QStyle *style); #endif void paintIndicatorRadioButton(QPainter *painter, const QStyleOptionButton *option, const QWidget *widget, const QStyle *style); void paintIndicatorSpinDown(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorSpinUp(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorSpinMinus(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorSpinPlus(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorArrowDown(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorArrowLeft(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorArrowRight(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintIndicatorArrowUp(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintHeaderSortIndicator(QPainter *painter, const QStyleOptionHeader *option, const QWidget *widget, const QStyle *style); void paintStyledFrame(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintFrameLineEdit(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintPanelLineEdit(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintFrameDockWidget(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintFrameWindow(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintToolBarSeparator(QPainter *painter, const QStyleOptionToolBar *option, const QWidget *widget, const QStyle *style); void paintToolBarHandle(QPainter *painter, const QStyleOptionToolBar *option, const QWidget *widget, const QStyle *style); void paintScrollArea(QPainter *painter, const QStyleOption *option); void paintPanelToolBar(QPainter *painter, const QStyleOptionToolBar *option, const QWidget *widget, const QStyle *style); void paintIndicatorMenuCheckMark(QPainter *painter, const QStyleOptionMenuItem *option, const QWidget *widget, const QStyle *style); void paintFrameGroupBox(QPainter *painter, const QStyleOptionFrame *option, const QWidget *widget, const QStyle *style); void paintFrameFocusRect(QPainter *painter, const QStyleOptionFocusRect *option, const QWidget *widget, const QStyle *style); void paintPanelButtonTool(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintSizeGrip(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintScrollAreaCorner(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintPanelItemViewItem(QPainter *painter, const QStyleOptionViewItemV4 *option, const QWidget *widget, const QStyle *style); #endif #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintIndicatorTabClose(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); #endif void paintMenuBarEmptyArea(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintPanelMenuBar(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintMenuBarItem(QPainter *painter, const QStyleOptionMenuItem *option, const QWidget *widget, const QStyle *style); void paintFrameMenu(QPainter *painter, const QStyleOptionFrame *frame, const QWidget *widget, const QStyle *style); void paintMenuItem(QPainter *painter, const QStyleOptionMenuItem *option, const QWidget *widget, const QStyle *style); void paintTabBarTabShape(QPainter *painter, const QStyleOptionTab *option, const QWidget *widget, const QStyle *style); void paintTabBarTabLabel(QPainter *painter, const QStyleOptionTab *option, const QWidget *widget, const QStyle *style); void paintFrameTabBarBase(QPainter *painter, const QStyleOptionTabBarBase *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintToolBoxTabShape(QPainter *painter, const QStyleOptionToolBoxV2 *option, const QWidget *widget, const QStyle *style); #else void paintToolBoxTabShape(QPainter *painter, const QStyleOptionToolBox *option, const QWidget *widget, const QStyle *style); #endif void paintToolBoxTabLabel(QPainter *painter, const QStyleOptionToolBox *option, const QWidget *widget, const QStyle *style); void paintHeaderEmptyArea(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintHeaderSection(QPainter *painter, const QStyleOptionHeader *option, const QWidget *widget, const QStyle *style); void paintHeaderLabel(QPainter *painter, const QStyleOptionHeader *option, const QWidget *widget, const QStyle *style); void paintIndicatorBranch(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintScrollBarSlider(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); void paintScrollBarAddLine(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); void paintScrollBarSubLine(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); void paintScrollBarFirst(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); void paintScrollBarLast(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); void paintScrollBarPage(QPainter *painter, const QStyleOptionSlider *option, const QWidget *widget, const QStyle *style); void paintProgressBarGroove(QPainter *painter, const QStyleOptionProgressBar *option, const QWidget *widget, const QStyle *style); #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) void paintProgressBarContents(QPainter *painter, const QStyleOptionProgressBarV2 *option, const QWidget *widget, const QStyle *style); void paintProgressBarLabel(QPainter *painter, const QStyleOptionProgressBarV2 *option, const QWidget *widget, const QStyle *style); #else void paintProgressBarContents(QPainter *painter, const QStyleOptionProgressBar *option, const QWidget *widget, const QStyle *style); void paintProgressBarLabel(QPainter *painter, const QStyleOptionProgressBar *option, const QWidget *widget, const QStyle *style); #endif void paintSplitter(QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style); void paintDockWidgetTitle(QPainter *painter, const QStyleOptionDockWidget *option, const QWidget *widget, const QStyle *style); void paintRubberBand(QPainter *paint, const QStyleOptionRubberBand *option, const QWidget *widget, const QStyle *style); void paintComboBoxLabel(QPainter *painter, const QStyleOptionComboBox *option, const QWidget *widget, const QStyle *style); void paintToolButtonLabel(QPainter *painter, const QStyleOptionToolButton *option, const QWidget *widget, const QStyle *style); /*-----------------------------------------------------------------------*/ SkulptureStyle::Private::Private() { init(); } SkulptureStyle::Private::~Private() { delete shortcut_handler; delete settings; } int runtimeQtVersion() { const char *vs = qVersion(); int v = 0; int vp = 0; while (true) { char c = *vs++; if (c >= '0' && c <= '9') { vp *= 10; vp += c - '0'; } else if (c == '.') { v = (v | vp) << 8; } else { return v | vp; } } } void SkulptureStyle::Private::init() { shortcut_handler = new ShortcutHandler(this); timer = 0; updatingShadows = false; oldEdit = 0; #if 0 settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, QLatin1String("SkulptureStyle"), QLatin1String("")); #else settings = 0; #endif QSettings s(QSettings::IniFormat, QSettings::UserScope, QLatin1String("SkulptureStyle"), QLatin1String("")); readSettings(s); register_draw_entries(); } void SkulptureStyle::Private::register_draw_entries() { for (uint i = 0; i < sizeof(draw_primitive_entry) / sizeof(Private::DrawElementEntry); ++i) { draw_primitive_entry[i].func = 0; } for (uint i = 0; i < sizeof(draw_element_entry) / sizeof(Private::DrawElementEntry); ++i) { draw_element_entry[i].func = 0; } /* entries are stricly sorted in Qt order for future lookup table */ #define register_primitive(pe, f, so) draw_primitive_entry[QStyle::PE_ ## pe].type = QStyleOption::SO_ ## so; draw_primitive_entry[QStyle::PE_ ## pe].func = (drawElementFunc *) paint ## f; /* PRIMITIVE ELEMENT */ #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) // Qt 3.x compatibility //### register_primitive(Q3CheckListController, Nothing, Default); register_primitive(Q3CheckListExclusiveIndicator, Q3CheckListExclusiveIndicator, Default); register_primitive(Q3CheckListIndicator, Q3CheckListIndicator, Default); register_primitive(Q3DockWindowSeparator, ToolBarSeparator, Default); #endif //### register_primitive(Q3Separator, Q3Separator, Default); // Qt 4.0 Frames register_primitive(Frame, StyledFrame, Frame); register_primitive(FrameDefaultButton, Nothing, Button); register_primitive(FrameDockWidget, FrameDockWidget, Frame); register_primitive(FrameFocusRect, FrameFocusRect, FocusRect); register_primitive(FrameGroupBox, FrameGroupBox, Frame); register_primitive(FrameLineEdit, FrameLineEdit, Frame); register_primitive(FrameMenu, FrameMenu, Default); // ### Qt 4.3 calls FrameMenu with SO_ToolBar for a toolbar #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) register_primitive(FrameStatusBarItem, Nothing, Default); #else register_primitive(FrameStatusBar, Nothing, Default); #endif register_primitive(FrameTabWidget, TabWidgetFrame, TabWidgetFrame); register_primitive(FrameWindow, FrameWindow, Frame); register_primitive(FrameButtonBevel, PanelButtonTool, Default); register_primitive(FrameButtonTool, PanelButtonTool, Default); register_primitive(FrameTabBarBase, FrameTabBarBase, TabBarBase); // Qt 4.0 Panels register_primitive(PanelButtonCommand, CommandButtonPanel, Button); register_primitive(PanelButtonBevel, PanelButtonTool, Default); register_primitive(PanelButtonTool, PanelButtonTool, Default); register_primitive(PanelMenuBar, PanelMenuBar, Frame); register_primitive(PanelToolBar, PanelToolBar, Frame); register_primitive(PanelLineEdit, PanelLineEdit, Frame); // Qt 4.0 Indicators register_primitive(IndicatorArrowDown, IndicatorArrowDown, Default); register_primitive(IndicatorArrowLeft, IndicatorArrowLeft, Default); register_primitive(IndicatorArrowRight, IndicatorArrowRight, Default); register_primitive(IndicatorArrowUp, IndicatorArrowUp, Default); register_primitive(IndicatorBranch, IndicatorBranch, Default); register_primitive(IndicatorButtonDropDown, PanelButtonTool, Default); #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) register_primitive(IndicatorItemViewItemCheck, IndicatorItemViewItemCheck, Default); #else register_primitive(IndicatorViewItemCheck, IndicatorItemViewItemCheck, Default); #endif register_primitive(IndicatorCheckBox, IndicatorCheckBox, Button); register_primitive(IndicatorDockWidgetResizeHandle, Splitter, Default); register_primitive(IndicatorHeaderArrow, HeaderSortIndicator, Header); register_primitive(IndicatorMenuCheckMark, IndicatorMenuCheckMark, MenuItem); // register_primitive(IndicatorProgressChunk, , ); register_primitive(IndicatorRadioButton, IndicatorRadioButton, Button); register_primitive(IndicatorSpinDown, IndicatorSpinDown, Default); register_primitive(IndicatorSpinMinus, IndicatorSpinMinus, Default); register_primitive(IndicatorSpinPlus, IndicatorSpinPlus, Default); register_primitive(IndicatorSpinUp, IndicatorSpinUp, Default); register_primitive(IndicatorToolBarHandle, ToolBarHandle, ToolBar); register_primitive(IndicatorToolBarSeparator, ToolBarSeparator, Default); // register_primitive(PanelTipLabel, , ); // register_primitive(IndicatorTabTear, , ); // Qt 4.2 additions #if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) register_primitive(PanelScrollAreaCorner, ScrollAreaCorner, Default); // ### register_primitive(Widget, , ); #endif // Qt 4.3 additions #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) // TODO register_primitive(IndicatorColumnViewArrow, , ); #endif // Qt 4.4 additions #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) // register_primitive(IndicatorItemViewItemDrop, , ); register_primitive(PanelItemViewItem, PanelItemViewItem, ViewItem); // register_primitive(PanelItemViewRow, , ); // register_primitive(PanelStatusBar, , ); #endif // Qt 4.5 additions #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) register_primitive(IndicatorTabClose, IndicatorTabClose, Default); // register_primitive(PanelMenu, , ); #endif #define register_element(ce, f, so) draw_element_entry[QStyle::CE_ ## ce].type = QStyleOption::SO_ ## so; draw_element_entry[QStyle::CE_ ## ce].func = (drawElementFunc *) paint ## f; /* CONTROL ELEMENT */ // Qt 4.0 Buttons // register_element(PushButton, , ); register_element(PushButtonBevel, PushButtonBevel, Button); // register_element(PushButtonLabel, , ); // register_element(CheckBox, , ); // register_element(CheckBoxLabel, , ); // register_element(RadioButton, , ); // register_element(RadioButtonLabel, , ); // Qt 4.0 Controls // register_element(TabBarTab, , ); register_element(TabBarTabShape, TabBarTabShape, Tab); register_element(TabBarTabLabel, TabBarTabLabel, Tab); // register_element(ProgressBar, , ProgressBar); register_element(ProgressBarGroove, ProgressBarGroove, ProgressBar); register_element(ProgressBarContents, ProgressBarContents, ProgressBar); register_element(ProgressBarLabel, ProgressBarLabel, ProgressBar); // Qt 4.0 Menus register_element(MenuItem, MenuItem, MenuItem); // register_element(MenuScroller, , ); // register_element(MenuVMargin, , ); // register_element(MenuHMargin, , ); // register_element(MenuTearoff, , ); register_element(MenuEmptyArea, Nothing, Default); register_element(MenuBarItem, MenuBarItem, MenuItem); register_element(MenuBarEmptyArea, MenuBarEmptyArea, Default); // Qt 4.0 more Controls register_element(ToolButtonLabel, ToolButtonLabel, ToolButton); // register_element(Header, , ); register_element(HeaderSection, HeaderSection, Header); register_element(HeaderLabel, HeaderLabel, Header); // register_element(Q3DockWindowEmptyArea, , ); // register_element(ToolBoxTab, , ); register_element(SizeGrip, SizeGrip, Default); register_element(Splitter, Splitter, Default); register_element(RubberBand, RubberBand, RubberBand); register_element(DockWidgetTitle, DockWidgetTitle, DockWidget); // Qt 4.0 ScrollBar register_element(ScrollBarAddLine, ScrollBarAddLine, Slider); register_element(ScrollBarSubLine, ScrollBarSubLine, Slider); register_element(ScrollBarAddPage, ScrollBarPage, Slider); register_element(ScrollBarSubPage, ScrollBarPage, Slider); register_element(ScrollBarSlider, ScrollBarSlider, Slider); register_element(ScrollBarFirst, ScrollBarFirst, Slider); register_element(ScrollBarLast, ScrollBarLast, Slider); // Qt 4.0 even more Controls // register_element(FocusFrame, , ); register_element(ComboBoxLabel, ComboBoxLabel, ComboBox); // Qt 4.1 additions //#if (QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)) register_element(ToolBar, PanelToolBar, ToolBar); //#endif // Qt 4.3 additions #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) register_element(ToolBoxTabShape, ToolBoxTabShape, ToolBox); register_element(ToolBoxTabLabel, ToolBoxTabLabel, ToolBox); register_element(HeaderEmptyArea, HeaderEmptyArea, Default); register_element(ColumnViewGrip, Splitter, Default); #endif // Qt 4.4 additions #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) // register_element(ItemViewItem, , ); #endif } /*-----------------------------------------------------------------------*/ #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) #include class SkulptureStylePlugin : public QStylePlugin { #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.SkulptureStyle" FILE "skulpture.json") #endif public: QStringList keys() const; QStyle *create(const QString &key); }; Q_EXPORT_PLUGIN2(skulpture, SkulptureStylePlugin) #else #include "sk_plugin.h" #endif QStringList SkulptureStylePlugin::keys() const { return QStringList(QLatin1String("Skulpture")); } QStyle *SkulptureStylePlugin::create(const QString &key) { if (key.toLower() == QLatin1String("skulpture")) { return new SkulptureStyle; } return 0; } #pragma GCC diagnostic pop /*-----------------------------------------------------------------------*/ //#include "skulpture_p.moc" qxgedit-1.0.1/skulpture/PaxHeaders/skulpture.h0000644000000000000000000000013214772452451016514 xustar0030 mtime=1743410473.473607941 30 atime=1743410473.473607941 30 ctime=1743410473.473607941 qxgedit-1.0.1/skulpture/skulpture.h0000644000175000001440000001154014772452451016505 0ustar00rncbcusers/* * Skulpture - Classical Three-Dimensional Artwork for Qt 5 * * Copyright (c) 2017-2021 rncbc aka Rui Nuno Capela * Copyright (c) 2007, 2008 Christoph Feck * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef SKULPTURE_H #define SKULPTURE_H 1 #include /*-----------------------------------------------------------------------*/ // Skulpture is a subclass of QCommonStyle in order to // ease transition to KStyle later class SkulptureStyle : public QCommonStyle { Q_OBJECT typedef QCommonStyle ParentStyle; public: SkulptureStyle(); virtual ~SkulptureStyle(); QPalette standardPalette() const; void polish(QPalette &palette); void polish(QWidget *widget); void unpolish(QWidget *widget); void polish(QApplication *application); void unpolish(QApplication *application); void drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const; void drawItemText(QPainter * painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const; QRect itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap & pixmap) const; QRect itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text ) const; int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const; int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const; QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const; QSize sizeFromContents (ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const; QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const; SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget) const; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const; QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, const QWidget *widget) const; void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; void drawControl(ControlElement control, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const; public: // internal enum SkulpturePrivateMethod { SPM_SupportedMethods = 0, SPM_SetSettingsFileName = 1 }; public Q_SLOTS: int skulpturePrivateMethod(SkulpturePrivateMethod id, void *data = 0); protected Q_SLOTS: #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const; #endif private: void init(); class Private; Private * const d; }; /*-----------------------------------------------------------------------*/ #endif // SKULPTURE_H qxgedit-1.0.1/skulpture/PaxHeaders/skulpture_p.h0000644000000000000000000000013214772452451017033 xustar0030 mtime=1743410473.473607941 30 atime=1743410473.473607941 30 ctime=1743410473.473607941 qxgedit-1.0.1/skulpture/skulpture_p.h0000644000175000001440000002353214772452451017030 0ustar00rncbcusers/* * skulpture_p.h - Classical Three-Dimensional Artwork for Qt 5 * * Copyright (c) 2017-2021 rncbc aka Rui Nuno Capela * Copyright (c) 2007-2009 Christoph Feck * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef SKULPTURE_PRIVATE_H #define SKULPTURE_PRIVATE_H 1 /*-----------------------------------------------------------------------*/ #include class QWidget; class ShortcutHandler : public QObject { Q_OBJECT enum TabletCursorState { DefaultCursor, TabletCursor, BlankCursor }; public: explicit ShortcutHandler(QObject *parent = 0); virtual ~ShortcutHandler(); bool underlineShortcut(const QWidget *widget) const; protected: bool eventFilter(QObject *watched, QEvent *event); private: void init() { } private: QList alt_pressed; TabletCursorState tabletCursorState; }; /*-----------------------------------------------------------------------*/ enum ArrowPlacementMode { NoArrowsMode, // (*) SkulptureMode, // (<*>) WindowsMode, // <(*)> KDEMode, // <(*)<> PlatinumMode, // (*)<> NextMode // <>(*) }; /*-----------------------------------------------------------------------*/ #include "skulpture.h" #include //#include #include #include class QPainter; class QSettings; class QTextEdit; class QPlainTextEdit; class QAbstractScrollArea; class QLineEdit; #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) class QFormLayout; #endif class QMenu; class SkulptureStyle::Private : public QObject { Q_OBJECT public: Private(); ~Private(); SkulptureStyle *q; void setAnimated(QWidget *widget, bool animated); bool isAnimated(QWidget *widget); private: QList animations; int timer; public: void readSettings(const QSettings &s); void readDominoSettings(const QSettings &s); QSettings *settings; bool animateProgressBars; bool hideShortcutUnderlines; bool centerTabs; // from domino bool makeDisabledWidgetsTransparent; bool transparentPlacesPanel; bool forceSpacingAndMargins; bool visualizeLayouts; bool useIconColumnForCheckIndicators; bool useSelectionColorForCheckedIndicators; bool useSelectionColorForSelectedMenuItems; int useSingleClickToActivateItems; bool expensiveShadows; bool allowTabulations; ArrowPlacementMode verticalArrowMode; ArrowPlacementMode horizontalArrowMode; int dialogMargins; int horizontalSpacing; int labelSpacing; int menuBarSize; int menuItemSize; int pushButtonSize; int scrollBarSize; int scrollBarLength; int sliderSize; int sliderLength; int tabBarSize; int toolButtonSize; int verticalSpacing; int widgetMargins; int widgetSize; int textShift; int buttonGradient; int buttonRoundness; int subMenuDelay; QString passwordCharacters; QString styleSheetFileName; qreal textCursorWidth; enum Settings { Style, Metric, Icon }; typedef void (drawElementFunc)( QPainter *painter, const QStyleOption *option, const QWidget *widget, const QStyle *style ); struct DrawElementEntry { int type; drawElementFunc *func; }; void register_settings(const char *label, ...); //QSignalMapper mapper; #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0)) struct DrawElementEntry draw_primitive_entry[QStyle::PE_PanelMenu + 1]; #elif (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) struct DrawElementEntry draw_primitive_entry[QStyle::PE_PanelStatusBar + 1]; #elif (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) struct DrawElementEntry draw_primitive_entry[QStyle::PE_IndicatorColumnViewArrow + 1]; #elif (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)) struct DrawElementEntry draw_primitive_entry[QStyle::PE_Widget + 1]; #else struct DrawElementEntry draw_primitive_entry[QStyle::PE_IndicatorTabTear + 1]; #endif #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) struct DrawElementEntry draw_element_entry[QStyle::CE_ItemViewItem + 1]; #elif (QT_VERSION >= QT_VERSION_CHECK(4, 3, 0)) struct DrawElementEntry draw_element_entry[QStyle::CE_ColumnViewGrip + 1]; #else struct DrawElementEntry draw_element_entry[QStyle::CE_ToolBar + 1]; #endif ShortcutHandler *shortcut_handler; void register_draw_entries(); void installFrameShadow(QWidget *widget); void removeFrameShadow(QWidget *widget); void updateFrameShadow(QWidget *widget); void updateTextEditMargins(QTextEdit *edit); void removeCursorLine(QAbstractScrollArea *edit); void updateCursorLine(QAbstractScrollArea *edit, const QRect &cursorRect); void paintCursorLine(QAbstractScrollArea *edit); void handleCursor(QTextEdit *edit); void handleCursor(QPlainTextEdit *edit); int verticalTextShift(const QFontMetrics &fontMetrics); int textLineHeight(const QStyleOption *option, const QWidget *widget); void polishLayout(QLayout *layout); #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) void polishFormLayout(QFormLayout *layout); #endif QList > postEventWidgets; void addPostEventWidget(QWidget *widget); QAbstractScrollArea *oldEdit; int oldCursorTop; int oldCursorWidth; int oldCursorHeight; int oldHeight; QPalette oldPalette; bool updatingShadows; QLineEdit *hoverLineEdit; QLineEdit *focusLineEdit; QRect lineEditHoverCursorRect; struct MenuInfo { QPointer menu; QPointer lastAction; QPointer visibleSubMenu; QPointer lastSubMenuAction; int eventCount; QPoint lastPos; int delayTimer; }; QHash menuHash; bool menuEventFilter(QMenu *menu, QEvent *event); protected: void timerEvent(QTimerEvent *event); bool eventFilter(QObject *watched, QEvent *event); protected Q_SLOTS: void textEditSourceChanged(QWidget *); void updateToolBarOrientation(Qt::Orientation); void processPostEventWidgets(); private: void init(); }; /*-----------------------------------------------------------------------*/ class FrameShadow : public QWidget { Q_OBJECT public: enum ShadowArea { Left, Top, Right, Bottom }; public: explicit FrameShadow(QWidget *parent = 0); explicit FrameShadow(ShadowArea area, QWidget *parent = 0); virtual ~FrameShadow(); void setShadowArea(ShadowArea area) { area_ = area; } ShadowArea shadowArea() const { return area_; } void updateGeometry(); protected: bool event(QEvent *e); void paintEvent(QPaintEvent *); private: void init(); private: ShadowArea area_; }; /*-----------------------------------------------------------------------*/ class WidgetShadow : public QWidget { Q_OBJECT public: explicit WidgetShadow(QWidget *parent = 0); void setWidget(QWidget *w) { widget_ = w; } QWidget *widget() const { return widget_; } void updateGeometry(); void updateZOrder(); public: bool event(QEvent *e); private: void init(); private: QWidget *widget_; }; /*-----------------------------------------------------------------------*/ struct SkMethodData { int version; }; struct SkMethodDataSetSettingsFileName : public SkMethodData { // in version 1 QString fileName; }; /*-----------------------------------------------------------------------*/ class QPainterPath; QColor shaded_color(const QColor &color, int shade); QColor blend_color(const QColor &c0, const QColor &c1, qreal blend); QGradient path_edge_gradient(const QRectF &rect, const QStyleOption *option, const QPainterPath &path, const QColor &color2, const QColor &color1); void paintThinFrame(QPainter *painter, const QRect &rect, const QPalette &palette, int dark, int light, QPalette::ColorRole bgrole = QPalette::Window); enum RecessedFrame { RF_Small, RF_Large, RF_None }; void paintRecessedFrame(QPainter *painter, const QRect &rect, const QPalette &palette, enum RecessedFrame rf, QPalette::ColorRole bgrole = QPalette::Window); void paintRecessedFrameShadow(QPainter *painter, const QRect &rect, enum RecessedFrame rf); int runtimeQtVersion(); /*-----------------------------------------------------------------------*/ // FIXME #if (QT_VERSION < QT_VERSION_CHECK(4, 3, 0)) #define lighter light #define darker dark #endif /*-----------------------------------------------------------------------*/ #define array_elements(a) (sizeof(a) / sizeof(a[0])) /*-----------------------------------------------------------------------*/ #endif qxgedit-1.0.1/skulpture/PaxHeaders/sk_factory.h0000644000000000000000000000013214772452451016622 xustar0030 mtime=1743410473.472882643 30 atime=1743410473.472716786 30 ctime=1743410473.472882643 qxgedit-1.0.1/skulpture/sk_factory.h0000644000175000001440000001064614772452451016621 0ustar00rncbcusers/* * sk_factory.h - Classical Three-Dimensional Artwork for Qt 5 * * Copyright (c) 2017-2021 rncbc aka Rui Nuno Capela * Copyright (c) 2008 Christoph Feck * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef SKULPTURE_FACTORY_H #define SKULPTURE_FACTORY_H 1 /*-----------------------------------------------------------------------*/ #include #include #include class AbstractFactory { public: typedef qint8 Code; typedef const Code *Description; static const int MinVar = 1; static const int MaxVar = 9; public: enum OpCode { /* Values */ MinVal = -100, MaxVal = 100, GetVar = 100, Add = 110, Sub, Mul, Div, Min, Max, Mix, Cond, /* Colors */ RGB = 0, RGBA, RGBAf, Blend, Palette, Shade, Darker, Lighter, /* Conditions */ EQ = 0, NE, LT, GE, GT, LE, Or, And, Not, FactoryVersion, OptionVersion, OptionType, OptionComplex, OptionState, OptionRTL, /* Instructions */ SetVar = 100, /* Shape */ Move = 121, Line, Quad, Cubic, Close, /* Gradient */ ColorAt = 121, /* Frame */ /* Panel */ /* Primitive */ /* Control */ Begin = 118, Else = 119, End = 120, If = 126, While = 127, Nop = 0 }; protected: AbstractFactory() : p(0), opt(0) { } virtual ~AbstractFactory() { } protected: void setDescription(Description description) { p = description; } void setOption(const QStyleOption *option) { opt = option; } void setVar(int n, qreal value) { var[n] = value; } qreal getVar(int n) const { return var[n]; } void create(); protected: virtual void executeCode(Code code) QT_FASTCALL; virtual void skipCode(Code code) QT_FASTCALL; virtual int version() QT_FASTCALL { return 0; } protected: qreal evalValue() QT_FASTCALL; QColor evalColor() QT_FASTCALL; void skipValue() QT_FASTCALL; void skipColor() QT_FASTCALL; private: bool evalCondition() QT_FASTCALL; void skipCondition() QT_FASTCALL; private: Description p; const QStyleOption *opt; qreal var[MaxVar + 1]; }; /*-----------------------------------------------------------------------*/ class ShapeFactory : public AbstractFactory { public: static QPainterPath createShape(Description description, qreal var[]); static QPainterPath createShape(Description description); protected: ShapeFactory() : AbstractFactory() { } virtual ~ShapeFactory() { } void clear() { path = QPainterPath(); } const QPainterPath &getPath() const { return path; } protected: virtual void executeCode(Code code) QT_FASTCALL; virtual void skipCode(Code code) QT_FASTCALL; private: QPainterPath path; }; #define Pvalue(v) int(100 * (v) + 0.5) #define Pmove(x,y) ShapeFactory::Move, Pvalue(x), Pvalue(y) #define Pline(x,y) ShapeFactory::Line, Pvalue(x), Pvalue(y) #define Pquad(x,y,a,b) ShapeFactory::Quad, Pvalue(x), Pvalue(y), Pvalue(a), Pvalue(b) #define Pcubic(x,y,a,b,c,d) ShapeFactory::Cubic, Pvalue(x), Pvalue(y), Pvalue(a), Pvalue(b), Pvalue(c), Pvalue(d) #define Pend ShapeFactory::Close, ShapeFactory::End #define Pclose ShapeFactory::Close /*-----------------------------------------------------------------------*/ class GradientFactory : public AbstractFactory { public: static QGradient createGradient(Description description, qreal var[]); static QGradient createGradient(Description description); protected: GradientFactory() : AbstractFactory() { } virtual ~GradientFactory() { } protected: void clear() { gradient.setStops(QGradientStops()); } const QGradient &getGradient() const { return gradient; } protected: virtual void executeCode(Code code) QT_FASTCALL; virtual void skipCode(Code code) QT_FASTCALL; private: QGradient gradient; }; /*-----------------------------------------------------------------------*/ #endif qxgedit-1.0.1/skulpture/PaxHeaders/skulpture.json0000644000000000000000000000013214772452451017236 xustar0030 mtime=1743410473.473607941 30 atime=1743410473.473607941 30 ctime=1743410473.473607941 qxgedit-1.0.1/skulpture/skulpture.json0000644000175000001440000000003514772452451017224 0ustar00rncbcusers{ "Keys": [ "Skulpture" ] } qxgedit-1.0.1/PaxHeaders/src0000644000000000000000000000013214772452451012761 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.473607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/0000755000175000001440000000000014772452451013026 5ustar00rncbcusersqxgedit-1.0.1/src/PaxHeaders/qxgeditAmpEg.cpp0000644000000000000000000000013214772452451016121 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditAmpEg.cpp0000644000175000001440000001700214772452451016111 0ustar00rncbcusers// qxgeditAmpEg.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditAmpEg.h" #include #include #include //---------------------------------------------------------------------------- // qxgeditAmpEg -- Custom widget // Constructor. qxgeditAmpEg::qxgeditAmpEg ( QWidget *pParent ) : QFrame(pParent), m_iAttack(0), m_iRelease(0), m_iDecay1(0), m_iDecay2(0), m_iLevel1(0), m_iLevel2(0), m_poly(8), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditAmpEg::~qxgeditAmpEg (void) { } // Parameter accessors. void qxgeditAmpEg::setAttack ( unsigned short iAttack ) { if (m_iAttack != iAttack) { m_iAttack = iAttack; update(); emit attackChanged(attack()); } } unsigned short qxgeditAmpEg::attack (void) const { return m_iAttack; } void qxgeditAmpEg::setRelease ( unsigned short iRelease ) { if (m_iRelease != iRelease) { m_iRelease = iRelease; update(); emit releaseChanged(release()); } } unsigned short qxgeditAmpEg::release (void) const { return m_iRelease; } void qxgeditAmpEg::setDecay1 ( unsigned short iDecay1 ) { if (m_iDecay1 != iDecay1) { m_iDecay1 = iDecay1; update(); emit decay1Changed(decay1()); } } unsigned short qxgeditAmpEg::decay1 (void) const { return m_iDecay1; } void qxgeditAmpEg::setDecay2 ( unsigned short iDecay2 ) { if (m_iDecay2 != iDecay2) { m_iDecay2 = iDecay2; update(); emit decay2Changed(decay2()); } } unsigned short qxgeditAmpEg::decay2 (void) const { return m_iDecay2; } void qxgeditAmpEg::setLevel1 ( unsigned short iLevel1 ) { if (m_iLevel1 != iLevel1) { m_iLevel1 = iLevel1; if (m_iLevel2 > iLevel1) setLevel2(iLevel1); else update(); emit level1Changed(level1()); } } unsigned short qxgeditAmpEg::level1 (void) const { return m_iLevel1; } void qxgeditAmpEg::setLevel2 ( unsigned short iLevel2 ) { if (m_iLevel2 != iLevel2) { m_iLevel2 = iLevel2; if (m_iLevel1 < iLevel2) setLevel1(iLevel2); else update(); emit level2Changed(level2()); } } unsigned short qxgeditAmpEg::level2 (void) const { return m_iLevel2; } // Draw curve. void qxgeditAmpEg::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int w5 = (w - 3) / 5; const int x1 = int(((63 - m_iAttack) * w5) >> 6) + 6; const int x2 = int(((63 - m_iDecay1) * w5) >> 6) + x1; const int x3 = int(((63 - m_iDecay2) * w5) >> 6) + x2; const int x4 = int(((63 - m_iRelease) * w5) >> 6) + x3 + w5; const int y2 = h - int(((m_iLevel1 + 1) * (h - 12)) >> 7) - 6; const int y3 = h - int(((m_iLevel2 + 1) * (h - 12)) >> 7) - 6; m_poly.putPoints(0, 8, 0, h, 6, h - 6, x1, 6, x2, y2, x3, y3, x3 + w5 - 6, y3, x4 - 6, h - 6, x4, h); QPainterPath path; path.addPolygon(m_poly); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); QLinearGradient grad(0, 0, w << 1, h << 1); grad.setColorAt(0.0f, rgbLite); grad.setColorAt(1.0f, Qt::black); painter.setBrush(grad); painter.drawPath(path); painter.setBrush(pal.mid().color()); painter.drawRect(nodeRect(1)); painter.drawRect(nodeRect(5)); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(2)); painter.drawRect(nodeRect(3)); painter.drawRect(nodeRect(4)); painter.drawRect(nodeRect(6)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Attack (%1) Decay(%2,%3) Level(%4,%5) Release (%6)") .arg(int(attack()) .arg(int(decay1()) .arg(int(decay2()) .arg(int(level1())) .arg(int(level2())) .arg(int(release())); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditAmpEg::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditAmpEg::nodeIndex ( const QPoint& pos ) const { if (nodeRect(6).contains(pos)) return 6; // Release if (nodeRect(4).contains(pos)) return 4; // Decay2/Level1 if (nodeRect(3).contains(pos)) return 3; // Decay1/Level1 if (nodeRect(2).contains(pos)) return 2; // Attack return -1; } void qxgeditAmpEg::dragNode ( const QPoint& pos ) { static unsigned short m_iLevel0 = 0; // Dummy! unsigned short *piRate = nullptr; unsigned short *piLevel = nullptr; switch (m_iDragNode) { case 2: // Attack piRate = &m_iAttack; piLevel = &m_iLevel0; break; case 3: // Decay1/Level1 piRate = &m_iDecay1; piLevel = &m_iLevel1; break; case 4: // Decay2/Level1 piRate = &m_iDecay2; piLevel = &m_iLevel2; break; case 6: // Release piRate = &m_iRelease; piLevel = &m_iLevel0; break; } if (piRate && piLevel) { int iRate = int(*piRate) - ((pos.x() - m_posDrag.x()) << 6) / (width() >> 2); int iLevel = int(*piLevel) + ((m_posDrag.y() - pos.y()) << 7) / height(); if (iLevel < 0) iLevel = 0; else if (iLevel > 127) iLevel = 127; if (iRate < 0) iRate = 0; else if (iRate > 63) iRate = 63; if (*piRate != (unsigned short) iRate || *piLevel != (unsigned short) iLevel) { m_posDrag = pos; switch (m_iDragNode) { case 2: // Attack setAttack(iRate); break; case 3: // Decay1/Level1 setDecay1(iRate); setLevel1(iLevel); break; case 4: // Decay2/Level1 setDecay2(iRate); setLevel2(iLevel); break; case 6: // Release setRelease(iRate); break; } } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditAmpEg::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(iDragNode == 3 || iDragNode == 4 ? Qt::SizeAllCursor : Qt::SizeHorCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditAmpEg::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditAmpEg::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditAmpEg.cpp qxgedit-1.0.1/src/PaxHeaders/XGParamSysex.cpp0000644000000000000000000000013214772452451016075 xustar0030 mtime=1743410473.474607941 30 atime=1743410473.474607941 30 ctime=1743410473.474607941 qxgedit-1.0.1/src/XGParamSysex.cpp0000644000175000001440000000745014772452451016073 0ustar00rncbcusers// XGParamSysex.cpp // /**************************************************************************** Copyright (C) 2005-2022, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "XGParamSysex.h" #include "XGParam.h" #include //------------------------------------------------------------------------- // XG SysEx generic message. // // Constructor XGSysex::XGSysex ( unsigned short size ) : m_data(nullptr), m_size(size) { m_data = new unsigned char [m_size]; } // Destructor XGSysex::~XGSysex (void) { delete [] m_data; } // Basic accessors. unsigned char *XGSysex::data (void) const { return m_data; } unsigned short XGSysex::size (void) const { return m_size; } //------------------------------------------------------------------------- // XG Parameter Change SysEx message. // Constructor. XGParamSysex::XGParamSysex ( XGParam *param ) : XGSysex(8 + param->size()) { unsigned short i = 0; m_data[i++] = 0xf0; // SysEx status (SOX) m_data[i++] = 0x43; // Yamaha id. m_data[i++] = 0x10; // Device no. m_data[i++] = 0x4c; // XG Model id. m_data[i++] = param->high(); m_data[i++] = param->mid(); m_data[i++] = param->low(); if (param->high() == 0x08 && param->low() == 0x09) // DETUNE (2byte,4 bit). param->set_data_value2(&m_data[i], param->value()); else param->set_data_value(&m_data[i], param->value()); i += param->size(); // Coda... m_data[i] = 0xf7; // SysEx status (EOX) } //------------------------------------------------------------------------- // (QS300) USER VOICE Bulk Dump SysEx message. // Constructor. XGUserVoiceSysex::XGUserVoiceSysex ( unsigned short id ) : XGSysex(0x188) // (size = 0x188 = 11 + 0x17d) { XGParamMasterMap *pMasterMap = XGParamMasterMap::getInstance(); if (pMasterMap == nullptr) { ::memset(m_data, 0, m_size); return; } unsigned short high = 0x11; unsigned short mid = id; unsigned short low = 0x00; unsigned short i = 0; m_data[i++] = 0xf0; // SysEx status (SOX) m_data[i++] = 0x43; // Yamaha id. m_data[i++] = 0x00; // Device no. m_data[i++] = 0x4b; // QS300 Model id. m_data[i++] = 0x02; // Byte count MSB (= 0x17d >> 7). m_data[i++] = 0x7d; // Byte count LSB (= 0x17d & 0x7f). m_data[i++] = high; m_data[i++] = mid; m_data[i++] = low; unsigned short i0 = i; while (i < m_size - 2) { low = i - i0; XGParam *param = pMasterMap->find_param(high, mid, low); if (param) { if (param->size() > 4) { XGDataParam *dataparam = static_cast (param); ::memcpy(&m_data[i], dataparam->data(), dataparam->size()); } else if (high == 0x08 && low == 0x09) { // DETUNE (2byte, 4bit). param->set_data_value2(&m_data[i], param->value()); } else { param->set_data_value(&m_data[i], param->value()); } i += param->size(); } else { m_data[i++] = 0x00; } } // Compute checksum... unsigned char cksum = 0; for (unsigned short j = 4; j < i; ++j) { cksum += m_data[j]; cksum &= 0x7f; } m_data[i++] = 0x80 - cksum; // Coda... m_data[i] = 0xf7; // SysEx status (EOX) } // end of XGParamSysex.cpp qxgedit-1.0.1/src/PaxHeaders/XGParamObserver.h0000644000000000000000000000013214772452451016216 xustar0030 mtime=1743410473.474607941 30 atime=1743410473.474221551 30 ctime=1743410473.474607941 qxgedit-1.0.1/src/XGParamObserver.h0000644000175000001440000000342714772452451016214 0ustar00rncbcusers// XGParamObserver.h // /**************************************************************************** Copyright (C) 2005-2009, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __XGParamObserver_h #define __XGParamObserver_h // Forward declarations. class XGParam; //--------------------------------------------------------------------------- // XGParamObserver - Scalar parameter value control/view. class XGParamObserver { public: // Constructor. XGParamObserver(XGParam *param); // Virtual destructor. virtual ~XGParamObserver(); // Subject value accessor. void set_param(XGParam *param); XGParam *param() const; // Indirect value accessors. void set_value(unsigned short u); unsigned short value() const; // Busy flag predicate. bool busy() const; // Pure virtual view updater. virtual void reset() = 0; // Pure virtual view updater. virtual void update() = 0; private: // Instance variables. XGParam *m_param; }; #endif // __XGParamObserver_h // end of XGParamObserver.h qxgedit-1.0.1/src/PaxHeaders/XGParamSysex.h0000644000000000000000000000013214772452451015542 xustar0030 mtime=1743410473.474607941 30 atime=1743410473.474607941 30 ctime=1743410473.474607941 qxgedit-1.0.1/src/XGParamSysex.h0000644000175000001440000000364614772452451015543 0ustar00rncbcusers// XGParamSysex.h // /**************************************************************************** Copyright (C) 2005-2022, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __XGParamSysex_h #define __XGParamSysex_h // Forward ddeclarations. class XGParam; //------------------------------------------------------------------------- // XG SysEx generic message. // class XGSysex { public: // Constructor XGSysex(unsigned short size); // Destructor virtual ~XGSysex(); // Basic accessors. unsigned char *data() const; unsigned short size() const; protected: // Instance variables. unsigned char *m_data; unsigned short m_size; }; //------------------------------------------------------------------------- // XG Parameter Change SysEx message. class XGParamSysex : public XGSysex { public: // Constructor. XGParamSysex(XGParam *param); }; //------------------------------------------------------------------------- // (QS300) USER VOICE Bulk Dump SysEx message. class XGUserVoiceSysex : public XGSysex { public: // Constructor. XGUserVoiceSysex(unsigned short id); }; #endif // __XGParamSysex_h // end of XGParamSysex.h qxgedit-1.0.1/src/PaxHeaders/qxgeditXGMasterMap.cpp0000644000000000000000000000013214772452451017260 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditXGMasterMap.cpp0000644000175000001440000003612714772452451017261 0ustar00rncbcusers// qxgeditXGMasterMap.cpp // /**************************************************************************** Copyright (C) 2005-2021, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditXGMasterMap.h" #include "qxgeditMidiDevice.h" #include "qxgeditMainForm.h" #include "XGParamSysex.h" #include //---------------------------------------------------------------------------- // qxgeditXGMasterMap::Observer -- XGParam master map observer. // Constructor. qxgeditXGMasterMap::Observer::Observer ( XGParam *pParam ) : XGParamObserver(pParam) { } // View updater (observer callback). void qxgeditXGMasterMap::Observer::reset (void) { } void qxgeditXGMasterMap::Observer::update (void) { qxgeditXGMasterMap *pMasterMap = qxgeditXGMasterMap::getInstance(); if (pMasterMap == nullptr) return; XGParam *pParam = param(); #ifdef CONFIG_DEBUG_0 qDebug("qxgeditXGMasterMap::Observer[%p]::update() [%02x %02x %02x %s %u]", this, pParam->high(), pParam->mid(), pParam->low(), pParam->text().toUtf8().constData(), pParam->value()); #endif if (pParam->high() == 0x11) { // Special USERVOICE bulk dump stuff... unsigned short iUser = pMasterMap->USERVOICE.current_key(); pMasterMap->set_user_dirty(iUser, true); if (pMasterMap->auto_send()) { pMasterMap->send_user(iUser); pMasterMap->set_user_dirty_1(iUser, false); } } else { // Regular XG Parameter change... pMasterMap->send_param(pParam); } // HACK: Flag dirty the main form... qxgeditMainForm *pMainForm = qxgeditMainForm::getInstance(); if (pMainForm) pMainForm->contentsChanged(); } //---------------------------------------------------------------------------- // qxgeditXGMasterMap -- XGParam master map. // // Constructor. qxgeditXGMasterMap::qxgeditXGMasterMap (void) : XGParamMasterMap(), m_auto_send(false) { // Setup local observers... XGParamMasterMap::const_iterator iter = XGParamMasterMap::constBegin(); for (; iter != XGParamMasterMap::constEnd(); ++iter) { XGParam *pParam = iter.value(); m_observers.insert(pParam, new Observer(pParam)); } reset_part_dirty(); reset_user_dirty(); } // Destructor. qxgeditXGMasterMap::~qxgeditXGMasterMap (void) { // Cleanup local observers... // qDeleteAll(m_observers); ObserverMap::const_iterator iter = m_observers.constBegin(); for (; iter != m_observers.constEnd(); ++iter) delete iter.value(); m_observers.clear(); } // Singleton (re)cast. qxgeditXGMasterMap *qxgeditXGMasterMap::getInstance (void) { return static_cast (XGParamMasterMap::getInstance()); } // Direct RPN value receiver. bool qxgeditXGMasterMap::set_rpn_value ( unsigned char /*ch*/, unsigned short /*rpn*/, unsigned short /*val*/, bool /*bNotify*/ ) { // TODO... return false; } // Direct NRPN value receiver. bool qxgeditXGMasterMap::set_nrpn_value ( unsigned char ch, unsigned short nrpn, unsigned short val, bool bNotify ) { // Check which part / drumset... if (nrpn >= 2560) { XGParamSet *pParamSet = MULTIPART.value(0x07, nullptr); if (pParamSet == nullptr) return false; XGParam *pParam = pParamSet->value(ch, nullptr); if (pParam == nullptr) return false; const unsigned short mode = pParam->value(); if (mode == 0 && ch != 9) return false; ch = (mode == 3 ? 1 : 0); } XGParam *pParam = NRPN.value(XGRpnParamKey(ch, nrpn), nullptr); if (pParam == nullptr) return false; unsigned char data[pParam->size()]; pParam->set_data_value(data, val); return set_param_data(pParam, data, bNotify); } // Direct SysEx data receiver. bool qxgeditXGMasterMap::add_sysex_data ( SysexData& sysex_data, unsigned char *data, unsigned short len ) { // SysEx (actually)... if (data[0] != 0xf0 || data[len - 1] != 0xf7) return false; // Yamaha ID... if (data[1] != 0x43) return false; int nsysex = 0; const unsigned char mode = (data[2] & 0x70); // const unsigned char devno = (data[2] & 0x0f); if (data[3] == 0x4c || data[3] == 0x4b) { // XG/QS300 Model ID... if (mode == 0x00) { // Native Bulk Dump... const unsigned short size = (data[4] << 7) + data[5]; unsigned char cksum = 0; for (unsigned short i = 0; i < size + 5; ++i) { cksum += data[4 + i]; cksum &= 0x7f; } if (data[9 + size] == 0x80 - cksum) { // Parameter Change... const unsigned short high = data[6]; const unsigned short mid = data[7]; const unsigned short low = data[8]; const XGParamKey key(high, mid, low); sysex_data.insert(key, QByteArray((const char *) &data[9], size)); ++nsysex; } } else if (mode == 0x10) { // Parameter Change... const unsigned short high = data[4]; const unsigned short mid = data[5]; const unsigned short low = data[6]; const XGParamKey key(high, mid, low); sysex_data.insert(key, QByteArray((const char *) &data[7], len - 7)); ++nsysex; } } return (nsysex > 0); } bool qxgeditXGMasterMap::set_sysex_data ( const SysexData& sysex_data, bool bNotify ) { int nparam = 0; SysexData::const_iterator iter = sysex_data.constBegin(); for (; iter != sysex_data.constEnd(); ++iter) { const XGParamKey& key = iter.key(); const QByteArray& val = iter.value(); unsigned char *data = (unsigned char *) val.data(); for (unsigned short i = 0; i < val.size(); ++i) { // Parameter Change... XGParam *pParam = find_param(key.high(), key.mid(), key.low() + i); if (pParam && set_param_data(pParam, data + i, bNotify)) { const unsigned short n = pParam->size(); if (n > 1) { i += (n - 1); ++nparam; } } } } return (nparam > 0); } // Direct parameter data access. bool qxgeditXGMasterMap::set_param_data ( XGParam *pParam, unsigned char *data, bool bNotify ) { if (!m_observers.contains(pParam)) return false; const unsigned short high = pParam->high(); const unsigned short mid = pParam->mid(); const unsigned short low = pParam->low(); if (high == 0x08 && low >= 0x01 && 0x03 >= low) { set_part_dirty(mid, true); bNotify = false; } else if (high == 0x11) { set_user_dirty(mid, true); bNotify = false; } Observer *pObserver = (bNotify ? nullptr : m_observers.value(pParam)); if (pParam->size() > 4) { XGDataParam *pDataParam = static_cast (pParam); pDataParam->set_data(data, pDataParam->size(), pObserver); } else if (high == 0x08 && low == 0x09) { // DETUNE (2byte, 4bit). pParam->set_value(pParam->data_value2(data), pObserver); } else { pParam->set_value(pParam->data_value(data), pObserver); } #ifdef CONFIG_DEBUG fprintf(stderr, "< %02x %02x %02x", pParam->high(), pParam->mid(), pParam->low()); const char *name = pParam->name(); if (name) { unsigned short c = pParam->value(); const char *s = pParam->gets(c); const char *u = pParam->unit(); fprintf(stderr, " %s", pParam->text().toUtf8().constData()); fprintf(stderr, " %g", pParam->getv(c)); if (s) fprintf(stderr, " %s", s); if (u) fprintf(stderr, " %s", u); } fprintf(stderr, " >\n"); #endif return (pParam->size() > 0); } // All parameter reset (to default) void qxgeditXGMasterMap::reset_all (void) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::reset_all()"); #endif ObserverMap::const_iterator iter = m_observers.constBegin(); for (; iter != m_observers.constEnd(); ++iter) { XGParam *pParam = iter.key(); pParam->reset(iter.value()); } reset_part_dirty(); reset_user_dirty(); } // Part reset (to default) void qxgeditXGMasterMap::reset_part ( unsigned short iPart ) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::reset_part(%u)", iPart); #endif XGParamMap::const_iterator iter = MULTIPART.constBegin(); for (; iter != MULTIPART.constEnd(); ++iter) { XGParamSet *pParamSet = iter.value(); if (pParamSet->contains(iPart)) { XGParam *pParam = pParamSet->value(iPart); if (pParam) pParam->reset(); } } if (part_dirty(iPart)) { send_part(iPart); set_part_dirty(iPart, false); } } // Drums reset (to default) void qxgeditXGMasterMap::reset_drums ( unsigned short iDrumSet ) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::reset_drums(%u)", iDrumSet); #endif unsigned short high = 0x30 + iDrumSet; ObserverMap::const_iterator iter = m_observers.constBegin(); for (; iter != m_observers.constEnd(); ++iter) { XGParam *pParam = iter.key(); if (pParam->high() == high) pParam->reset(iter.value()); } } // user voice reset (to default) void qxgeditXGMasterMap::reset_user ( unsigned short iUser ) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::reset_user(%u)", iUser); #endif // Suspend auto-send temporarily... bool bAuto = auto_send(); set_auto_send(false); XGParamMap::const_iterator iter = USERVOICE.constBegin(); for (; iter != USERVOICE.constEnd(); ++iter) { XGParamSet *pParamSet = iter.value(); if (pParamSet->contains(iUser)) { XGParam *pParam = pParamSet->value(iUser); if (pParam) pParam->reset(); } } if (user_dirty(iUser)) { send_user(iUser); set_user_dirty(iUser, false); } // Restore auto-send. set_auto_send(bAuto); } // Send regular XG Parameter change SysEx message. void qxgeditXGMasterMap::send_param ( XGParam *pParam ) { if (pParam == nullptr) return; qxgeditMidiDevice *pMidiDevice = qxgeditMidiDevice::getInstance(); if (pMidiDevice == nullptr) return; // Build the complete SysEx message... XGParamSysex sysex(pParam); // Send it out... pMidiDevice->sendSysex(sysex.data(), sysex.size()); // HACK: Special reset actions... if (pParam->high() == 0x00 && pParam->mid() == 0x00) { switch (pParam->low()) { case 0x7d: // Drum Setup Reset reset_drums(pParam->value()); break; case 0x7e: // XG System On case 0x7f: // All Parameter Reset reset_all(); break; } } } // Send Multi Part Bank Select/Program Number SysEx messages. void qxgeditXGMasterMap::send_part ( unsigned short iPart ) const { qxgeditMidiDevice *pMidiDevice = qxgeditMidiDevice::getInstance(); if (pMidiDevice == nullptr) return; unsigned short high = 0x08; unsigned short mid = iPart; for (unsigned short low = 0x01; low < 0x04; ++low) { XGParam *pParam = find_param(high, mid, low); if (pParam) { // Build the complete SysEx message... XGParamSysex sysex(pParam); // Send it out... pMidiDevice->sendSysex(sysex.data(), sysex.size()); } } } // Send USER VOICE Bulk Dump SysEx message. void qxgeditXGMasterMap::send_user ( unsigned short iUser ) const { qxgeditMidiDevice *pMidiDevice = qxgeditMidiDevice::getInstance(); if (pMidiDevice == nullptr) return; // Build the complete SysEx message... XGUserVoiceSysex sysex(iUser); // Send it out... pMidiDevice->sendSysex(sysex.data(), sysex.size()); } // MULTIPART dirty slot simple managing. void qxgeditXGMasterMap::reset_part_dirty (void) { for (unsigned short i = 0; i < 16; ++i) m_part_dirty[i] = 0; } void qxgeditXGMasterMap::set_part_dirty ( unsigned short iPart, bool bDirty ) { if (iPart < 16) { if (bDirty) m_part_dirty[iPart] |= 1; else m_part_dirty[iPart] &= ~1; } } bool qxgeditXGMasterMap::part_dirty ( unsigned short iPart ) const { return (iPart < 16) && (m_part_dirty[iPart] != 0); } // (QS300) USERVOICE dirty slot simple managing. void qxgeditXGMasterMap::reset_user_dirty (void) { for (unsigned short i = 0; i < 32; ++i) m_user_dirty[i] = 0; } void qxgeditXGMasterMap::set_user_dirty ( unsigned short iUser, bool bDirty ) { if (iUser < 32) { if (bDirty) m_user_dirty[iUser] |= 7; else m_user_dirty[iUser] &= ~7; } } bool qxgeditXGMasterMap::user_dirty ( unsigned short iUser ) const { return (iUser < 32) && (m_user_dirty[iUser] & 7); } void qxgeditXGMasterMap::set_user_dirty_1 ( unsigned short iUser, bool bDirty ) { if (iUser < 32) { if (bDirty) m_user_dirty[iUser] |= 1; else m_user_dirty[iUser] &= ~1; } } bool qxgeditXGMasterMap::user_dirty_1 ( unsigned short iUser ) const { return (iUser < 32) && (m_user_dirty[iUser] & 1); } void qxgeditXGMasterMap::set_user_dirty_2 ( unsigned short iUser, bool bDirty ) { if (iUser < 32) { if (bDirty) m_user_dirty[iUser] |= 2; else m_user_dirty[iUser] &= ~2; } } bool qxgeditXGMasterMap::user_dirty_2 ( unsigned short iUser ) const { return (iUser < 32) && (m_user_dirty[iUser] & 2); } // (QS300) USERVOICE bulk dump auto-send feature. void qxgeditXGMasterMap::set_auto_send ( bool bAuto ) { m_auto_send = bAuto; } bool qxgeditXGMasterMap::auto_send (void) const { return m_auto_send; } // Part randomize (from value/def) void qxgeditXGMasterMap::randomize_part ( unsigned short iPart, float p ) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::randomize_part(%u, %g)", iPart, p); #endif XGParamMap::const_iterator iter = MULTIPART.constBegin(); for (; iter != MULTIPART.constEnd(); ++iter) { XGParamSet *pParamSet = iter.value(); if (pParamSet->contains(iPart)) { XGParam *pParam = pParamSet->value(iPart); if (pParam && pParam->low() > 0x04) pParam->randomize_value(p); } } if (part_dirty(iPart)) { send_part(iPart); set_part_dirty(iPart, false); } } // Drums randomize (from value/def) void qxgeditXGMasterMap::randomize_drums ( unsigned short iDrumSet, unsigned short iDrumKey, float p ) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::randomize_drums(%u, %u, %g)", iDrumSet, iDrumKey, p); #endif unsigned short key = (unsigned short) (iDrumSet << 7) + iDrumKey; XGParamMap::const_iterator iter = DRUMSETUP.constBegin(); for (; iter != DRUMSETUP.constEnd(); ++iter) { XGParamSet *pParamSet = iter.value(); if (pParamSet->contains(key)) { XGParam *pParam = pParamSet->value(key); if (pParam) pParam->randomize_value(p); } } } // User voice randomize (from value/def) void qxgeditXGMasterMap::randomize_user ( unsigned short iUser, float p ) { #ifdef CONFIG_DEBUG qDebug("qxgeditXGMasterMap::randomize_user(%u, %g)", iUser, p); #endif // Suspend auto-send temporarily... bool bAuto = auto_send(); set_auto_send(false); unsigned short id0 = 0x3d + (USERVOICE.current_element() * 0x50); XGParamMap::const_iterator iter = USERVOICE.constBegin(); for (; iter != USERVOICE.constEnd(); ++iter) { unsigned short id = iter.key(); if (id < 0x3d) continue; if (USERVOICE.elements() > 0 && (id < id0 || id >= id0 + 0x50)) continue; XGParamSet *pParamSet = iter.value(); if (pParamSet->contains(iUser)) { XGParam *pParam = pParamSet->value(iUser); if (pParam) pParam->randomize_value(p); } } if (user_dirty(iUser)) { send_user(iUser); set_user_dirty_1(iUser, false); } // Restore auto-send. set_auto_send(bAuto); } // end of qxgeditXGMasterMap.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditPitch.cpp0000644000000000000000000000013214772452451016177 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPitch.cpp0000644000175000001440000001444314772452451016175 0ustar00rncbcusers// qxgeditPitch.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditPitch.h" #include #include //---------------------------------------------------------------------------- // qxgeditPitch -- Custom widget // Constructor. qxgeditPitch::qxgeditPitch ( QWidget *pParent ) : QFrame(pParent), m_iAttackTime(0), m_iAttackLevel(0), m_iReleaseTime(0), m_iReleaseLevel(0), m_poly(4), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditPitch::~qxgeditPitch (void) { } // Parameter accessors. void qxgeditPitch::setAttackTime ( unsigned short iAttackTime ) { if (m_iAttackTime != iAttackTime) { m_iAttackTime = iAttackTime; update(); emit attackTimeChanged(attackTime()); } } unsigned short qxgeditPitch::attackTime (void) const { return m_iAttackTime; } void qxgeditPitch::setAttackLevel ( unsigned short iAttackLevel ) { if (m_iAttackLevel != iAttackLevel) { m_iAttackLevel = iAttackLevel; update(); emit attackLevelChanged(attackLevel()); } } unsigned short qxgeditPitch::attackLevel (void) const { return m_iAttackLevel; } void qxgeditPitch::setReleaseTime ( unsigned short iReleaseTime ) { if (m_iReleaseTime != iReleaseTime) { m_iReleaseTime = iReleaseTime; update(); emit releaseTimeChanged(releaseTime()); } } unsigned short qxgeditPitch::releaseTime (void) const { return m_iReleaseTime; } void qxgeditPitch::setReleaseLevel ( unsigned short iReleaseLevel ) { if (m_iReleaseLevel != iReleaseLevel) { m_iReleaseLevel = iReleaseLevel; update(); emit releaseLevelChanged(releaseLevel()); } } unsigned short qxgeditPitch::releaseLevel (void) const { return m_iReleaseLevel; } // Draw curve. void qxgeditPitch::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = h >> 1; const int w4 = w >> 2; const int x2 = w / 3; const int x3 = x2 << 1; const int x1 = x2 - int((m_iAttackTime * w4) >> 7); const int y1 = h2 - ((int(m_iAttackLevel) - 64) * (h - 12) >> 7); const int x4 = x3 + int((m_iReleaseTime * w4) >> 7); const int y2 = h2 - ((int(m_iReleaseLevel) - 64) * (h - 12) >> 7); m_poly.putPoints(0, 4, x1, y1, x2, h2, x3, h2, x4, y2); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); painter.drawPolyline(m_poly); painter.setBrush(pal.mid().color()); painter.drawRect(nodeRect(1)); painter.drawRect(nodeRect(2)); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(0)); painter.drawRect(nodeRect(3)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Attack (%1,%2) Release (%3,%4)") .arg(int(attackTime()) - 64) .arg(int(attackLevel()) - 64) .arg(int(releaseTime()) - 64) .arg(int(releaseLevel()) - 64)); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditPitch::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditPitch::nodeIndex ( const QPoint& pos ) const { if (nodeRect(3).contains(pos)) return 3; // Release if (nodeRect(0).contains(pos)) return 0; // Attack return -1; } void qxgeditPitch::dragNode ( const QPoint& pos ) { unsigned short *piTime = nullptr; unsigned short *piLevel = nullptr; switch (m_iDragNode) { case 0: // Attack piLevel = &m_iAttackLevel; piTime = &m_iAttackTime; break; case 3: // Release piLevel = &m_iReleaseLevel; piTime = &m_iReleaseTime; break; } if (piTime && piLevel) { int iTime = int(*piTime) + (m_iDragNode == 0 ? -1 : +1) * ((pos.x() - m_posDrag.x()) << 7) / (width() >> 2); int iLevel = int(*piLevel) + ((m_posDrag.y() - pos.y()) << 7) / height(); if (iTime < 0) iTime = 0; else if (iTime > 127) iTime = 127; if (iLevel < 0) iLevel = 0; else if (iLevel > 127) iLevel = 127; if (*piTime != (unsigned short) iTime || *piLevel != (unsigned short) iLevel) { m_posDrag = pos; switch (m_iDragNode) { case 0: // Attack setAttackTime(iTime); setAttackLevel(iLevel); break; case 3: // Release setReleaseTime(iTime); setReleaseLevel(iLevel); break; } } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditPitch::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(Qt::SizeAllCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditPitch::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditPitch::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditPitch.cpp qxgedit-1.0.1/src/PaxHeaders/images0000644000000000000000000000013214772452451014226 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.474959861 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/0000755000175000001440000000000014772452451014273 5ustar00rncbcusersqxgedit-1.0.1/src/images/PaxHeaders/formAccept.png0000644000000000000000000000013214772452451017074 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/formAccept.png0000644000175000001440000000027314772452451017066 0ustar00rncbcusersPNG  IHDRasRGBuIDAT8 D#u]Ùt&U04J?{ ;/~BLD0@hd l dpspP|𺶁 qי50\u} >EszñX챮mVUU _XXxif|/np px r ߀'} q.p m=X|gggIT3;;KVcii(<O-NK&π[&񕕕LNNJ,I$qhf#2-Ni>]BPARR,|8ڶM__H. zTU\.d888𐍍 LDD* `H$( dO &z\.*;UDd0 OsjܩDV-၁, 3ɤ<\[[3ED⿚D ‘/qu]?Wh4[*[uE@ QӒH$~{{齽yJ`Y nLF u ???FEhPU_pePp03Ig=X['PoIENDB`qxgedit-1.0.1/src/images/PaxHeaders/formCreate.png0000644000000000000000000000013214772452451017100 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/formCreate.png0000644000175000001440000000026714772452451017075 0ustar00rncbcusersPNG  IHDRasRGBqIDAT8R[ 8; } >i̖5!*UTP)TO'"'G(w(۹j(l>I 1w @B惈${IENDB`qxgedit-1.0.1/src/images/PaxHeaders/fileSave.png0000644000000000000000000000013214772452451016547 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/fileSave.png0000644000175000001440000000143314772452451016540 0ustar00rncbcusersPNG  IHDRĴl;sBIT|d pHYs & &Q3tEXtSoftwarewww.inkscape.org<IDAT8JQs37NH֝ E0@6"qӅPP\k [@⢋BDł&3;s0 cM6ewdl=}Yă ; fIe..`A׿5/Q9ld2}I[k%"'''Z7`` |>j5uttd2ZT~ͦTU֍V+}fSR*RRcj1& N"WDD(J̤ `~~TrGcM(F'2D‹sGxxx "D;k-vq]wzR(8 `kkk2xzN^n9jT*'yE<0 ֲtZQq~~6B}1RhZ#"z="|cL^;kz[7Mi}me!RT3|uqfg(\;Rf"Ppo--U6Af{uM,[͚@£E0E|oؤEIENDB`qxgedit-1.0.1/src/images/PaxHeaders/qxgedit.png0000644000000000000000000000013214772452451016456 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/qxgedit.png0000644000175000001440000000251414772452451016450 0ustar00rncbcusersPNG  IHDR szz pHYsyytEXtSoftwarewww.inkscape.org<IDATX[Uek}g|1SQF"0 % ŇA7},*o=J d%I="#уXrftlo}Ι3:΋o:*rmRu橪׹s(UX0aPDxd(ئi}LJya_; sa$-eapxE cYm7Y n߅|:+4hmkSˎ-6DsMzT]s[è1nßERU=i \xN%S+ w!ce='Y6d<|5&N }r=WITPUOD.:X"ug!Q(d3M:پ0 Yhez~.]c"Nj̼iCe@!_t vM T>j ;ahðqP$c qq}?;_li:E䬪n0Ema $ \w#U.MD@-gDU uPsa#)\%A@5oV ߆{\64IIENDB`qxgedit-1.0.1/src/images/PaxHeaders/formSave.png0000644000000000000000000000013214772452451016573 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/formSave.png0000644000175000001440000000111014772452451016554 0ustar00rncbcusersPNG  IHDRasBIT|d pHYsu85tEXtSoftwarewww.inkscape.org<IDAT8ZA}19nCr@$`iHPWRQه̞qoIˬ`Γ,vh` mbѲ,8^ppRh4t/{T*rn3Nz= BRtxpIENDB`qxgedit-1.0.1/src/images/PaxHeaders/itemReset.png0000644000000000000000000000013214772452451016752 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/itemReset.png0000644000175000001440000000110314772452451016735 0ustar00rncbcusersPNG  IHDRasBIT|d pHYsbb8ztEXtSoftwarewww.inkscape.org<IDAT8R`__] NHMP ]ڥCS'(tS7%O24bHi/5{clt{s? D$(M/Lr)˲|i .y'aE1'mq("( ԡ}eYf)q mE1;͒l6re}u=" ѨZUBl[c $۶ziVs !Kv;cEp΁R R4M$~;9?5 s~Z!g~Q20J)AG"H7Bay?m4J1LRT.v$"!`8(ur|V*c}q%N~3υri6MZ.:GixUs IENDB`qxgedit-1.0.1/src/images/PaxHeaders/formReject.png0000644000000000000000000000013214772452451017111 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/formReject.png0000644000175000001440000000033014772452451017075 0ustar00rncbcusersPNG  IHDRasRGBIDAT8RA +|?3gM 3U77u-[@<0X}&+^G-ةTEȟAG[v ,29kw';saE浶Dn7b rs>'`65IENDB`qxgedit-1.0.1/src/images/PaxHeaders/formOpen.png0000644000000000000000000000013214772452451016576 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/images/formOpen.png0000644000175000001440000000105214772452451016564 0ustar00rncbcusersPNG  IHDRasBIT|d pHYsu85tEXtSoftwarewww.inkscape.org<IDAT8?AGW# M!8V%} I!)m *hw,bac"ץHHsn&wy/!3B]Pǀ π@~_0 qxgedit-1.0.1/src/images/PaxHeaders/fileNew.png0000644000000000000000000000013214772452451016402 xustar0030 mtime=1743410473.474959861 30 atime=1743410473.474959861 30 ctime=1743410473.474959861 qxgedit-1.0.1/src/images/fileNew.png0000644000175000001440000000075414772452451016400 0ustar00rncbcusersPNG  IHDRĴl;sBIT|d pHYs & &Q3tEXtSoftwarewww.inkscape.org<iIDAT8=jAgteEX"L&brkOJ<@oa%1X{.Zg Zo|{fؐ \@:f|6Np\jRY_w`$+ baL&[l63J8I* u/ldADHӈzr\m)8R,v CiZ >Drjk-vN#|vRϑ[k16;ϭNSj^X78uNA8[Y+FF.nh0,KRf<# ΀f'`vv߁Vaq SB 8IENDB`qxgedit-1.0.1/src/PaxHeaders/qxgeditVibra.h0000644000000000000000000000013214772452451015640 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditVibra.h0000644000175000001440000000450714772452451015636 0ustar00rncbcusers// qxgeditVibra.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditVibra_h #define __qxgeditVibra_h #include //---------------------------------------------------------------------------- // qxgeditVibra -- Custom widget class qxgeditVibra : public QFrame { Q_OBJECT public: // Constructor. qxgeditVibra(QWidget *pParent = nullptr); // Destructor. ~qxgeditVibra(); // Parameter getters. unsigned short delay() const; unsigned short rate() const; unsigned short depth() const; public slots: // Parameter setters. void setDelay(unsigned short iDelay); void setRate(unsigned short iRate); void setDepth(unsigned short iDepth); signals: // Parameter change signals. void delayChanged(unsigned short iDelay); void rateChanged(unsigned short iRate); void depthChanged(unsigned short iDepth); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iDelay; unsigned short m_iRate; unsigned short m_iDepth; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditVibra_h // end of qxgeditVibra.h qxgedit-1.0.1/src/PaxHeaders/qxgeditMainForm.ui0000644000000000000000000000013214772452451016473 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditMainForm.ui0000644000175000001440000025353314772452451016476 0ustar00rncbcusers rncbc aka Rui Nuno Capela qxgedit - Qt XG Editor. Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. qxgeditMainForm 0 0 640 520 640 480 true :/images/qxgedit.svg 0 System / Effect 0 Master Reset :/images/qxgedit.svg Reset XG System Qt::Horizontal 20 20 Qt::Vertical 20 20 Reverb Reset Reset Reverb Qt::Horizontal 20 20 Qt::Horizontal 20 20 Qt::Vertical 20 20 Chorus Reset Reset Chorus Qt::Horizontal 20 20 Qt::Horizontal 20 20 Qt::Vertical 20 20 Variation Reset Reset Variation Qt::Horizontal 20 20 Qt::Horizontal 20 20 Qt::Vertical 20 20 Multi Part Reset Reset Part Qt::Horizontal 20 20 0 Main Part Voice Mode Control Portamento Note Velocity Effect Qt::Vertical 20 20 Tone Vibrato Qt::Horizontal 60 20 Filter Qt::Horizontal 20 20 Amp EG Qt::Horizontal 60 20 Pitch EG Qt::Horizontal 20 20 Qt::Vertical 20 20 Control Modulation Wheel Pitch Bend Channel After Touch (CAT) Polyphonic After Touch (PAT) Scale Tuning Qt::Vertical 20 20 Options AC1 AC2 Receive Qt::Vertical 20 20 Drum Setup Reset Reset Drums Qt::Horizontal 20 20 Pitch Control Mode Effect Filter Amp EG Receive Qt::Vertical 20 20 Qt::Vertical 20 20 User Voice Reset Reset User voice Qt::Horizontal 20 20 Auto Auto-send SysEx (QS300) on parameter change Send Send SysEx (QS300) 0 Main Common Element LFO Qt::Vertical 20 20 Level Scale Parameters Qt::Vertical 20 20 Qt::Vertical 20 20 Cutoff Scale Frequency Qt::Horizontal 60 20 Qt::Vertical 20 20 Qt::Vertical 20 20 Filter EG EG Parameters Qt::Vertical 20 20 Qt::Vertical 20 20 Pitch EG EG Parameters Qt::Vertical 20 20 Qt::Vertical 20 20 Amp EG EG Parameters Qt::Vertical 20 20 Qt::Vertical 20 20 Qt::Horizontal TopToolBarArea false 0 0 771 28 &File Open &Recent &View &Help :/images/fileNew.png &New New New session New session file Ctrl+N :/images/fileOpen.png &Open... Open Open session Open session from file Ctrl+O :/images/fileSave.png &Save Save Save session Save session to file Ctrl+S Save &As... Save As Save as Save current session with another file name E&xit Exit Exit Exit this application program true &Menubar Menubar Menubar Show/hide the main program window menubar Ctrl+M true &Statusbar Statusbar Statusbar Show/hide the main program window statusbar true &Toolbar Toolbar Toolbar Show/hide main program window file toolbar :/images/formCreate.png &Randomize Randomize Randomize Randomize parameters Ctrl+R &Options... Options Options Change general application program options F12 &About... About About Show information about this application program About &Qt... About Qt About Qt Show information about the Qt toolkit qxgeditDial QLabel
qxgeditDial.h
qxgeditCheck QCheckBox
qxgeditCheck.h
qxgeditCombo QComboBox
qxgeditCombo.h
qxgeditPartEg QFrame
qxgeditPartEg.h
1
qxgeditFilter QFrame
qxgeditFilter.h
1
qxgeditPitch QFrame
qxgeditPitch.h
1
qxgeditVibra QFrame
qxgeditVibra.h
1
qxgeditDrumEg QFrame
qxgeditDrumEg.h
1
qxgeditEdit QLineEdit
qxgeditEdit.h
1
qxgeditScale QFrame
qxgeditScale.h
1
qxgeditUserEg QFrame
qxgeditUserEg.h
1
qxgeditAmpEg QFrame
qxgeditAmpEg.h
1
qxgedit-1.0.1/src/PaxHeaders/qxgeditKnob.cpp0000644000000000000000000000013214772452451016021 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditKnob.cpp0000644000175000001440000001017214772452451016012 0ustar00rncbcusers// qxgeditKnob.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditKnob.h" #include #include #include //------------------------------------------------------------------------- // qxgeditKnob - Instance knob widget class. // // Constructor. qxgeditKnob::qxgeditKnob ( QWidget *pParent ) : QDial(pParent), m_iDefaultValue(-1), m_dialMode(DefaultMode), m_bMousePressed(false), m_fLastDragValue(0.0f) { } // Destructor. qxgeditKnob::~qxgeditKnob (void) { } void qxgeditKnob::setDefaultValue ( int iDefaultValue ) { m_iDefaultValue = iDefaultValue; } void qxgeditKnob::setDialMode ( qxgeditKnob::DialMode dialMode ) { m_dialMode = dialMode; } // Mouse angle determination. float qxgeditKnob::mouseAngle ( const QPoint& pos ) { float dx = pos.x() - (width() / 2); float dy = (height() / 2) - pos.y(); return 180.0f * atan2f(dx, dy) / float(M_PI); } // Alternate mouse behavior event handlers. void qxgeditKnob::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::MiddleButton) { // Reset to default value... if (m_iDefaultValue < minimum() || m_iDefaultValue > maximum()) m_iDefaultValue = (maximum() + minimum()) / 2; setValue(m_iDefaultValue); } else if (m_dialMode == DefaultMode) { QDial::mousePressEvent(pMouseEvent); } else if (pMouseEvent->button() == Qt::LeftButton) { m_bMousePressed = true; m_posMouse = pMouseEvent->pos(); m_fLastDragValue = float(value()); emit sliderPressed(); } } void qxgeditKnob::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { if (m_dialMode == DefaultMode) { QDial::mouseMoveEvent(pMouseEvent); return; } if (!m_bMousePressed) return; const QPoint& pos = pMouseEvent->pos(); int xdelta = pos.x() - m_posMouse.x(); int ydelta = pos.y() - m_posMouse.y(); float fAngleDelta = mouseAngle(pos) - mouseAngle(m_posMouse); int iNewValue = value(); switch (m_dialMode) { case LinearMode: iNewValue = int(m_fLastDragValue) + xdelta - ydelta; break; case AngularMode: default: // Forget about the drag origin to be robust on full rotations if (fAngleDelta > +180.0f) fAngleDelta -= 360.0f; else if (fAngleDelta < -180.0f) fAngleDelta += 360.0f; m_fLastDragValue += float(maximum() - minimum()) * fAngleDelta / 270.0f; if (m_fLastDragValue > float(maximum())) m_fLastDragValue = float(maximum()); else if (m_fLastDragValue < float(minimum())) m_fLastDragValue = float(minimum()); m_posMouse = pos; iNewValue = int(m_fLastDragValue + 0.5f); break; } setValue(iNewValue); update(); emit sliderMoved(value()); } void qxgeditKnob::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { if (m_dialMode == DefaultMode && pMouseEvent->button() != Qt::MiddleButton) { QDial::mouseReleaseEvent(pMouseEvent); } else if (m_bMousePressed) { m_bMousePressed = false; } } void qxgeditKnob::wheelEvent ( QWheelEvent *pWheelEvent ) { if (m_dialMode == DefaultMode) { QDial::wheelEvent(pWheelEvent); } else { int iValue = value(); if (pWheelEvent->angleDelta().y() > 0) iValue -= pageStep(); else iValue += pageStep(); if (iValue > maximum()) iValue = maximum(); else if (iValue < minimum()) iValue = minimum(); setValue(iValue); } } // end of qxgeditKnob.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditEdit.cpp0000644000000000000000000000013214772452451016015 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditEdit.cpp0000644000175000001440000002777214772452451016024 0ustar00rncbcusers// qxgeditEdit.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditEdit.h" #include "qxgeditOptions.h" #include "qxgeditXGMasterMap.h" #include #include #include #include #include #include #include #include //------------------------------------------------------------------------- // qxgeditEdit - Custom edit-box widget. // // Constructor. qxgeditEdit::qxgeditEdit ( QWidget *pParent ) : XGParamWidget (pParent), m_pParam(nullptr) { m_pComboBox = new QComboBox(); m_pOpenButton = new QToolButton(); m_pSaveButton = new QToolButton(); m_pRemoveButton = new QToolButton(); m_pComboBox->setEditable(true); m_pComboBox->setCompleter(nullptr); m_pComboBox->setInsertPolicy(QComboBox::NoInsert); m_pOpenButton->setIcon(QIcon(":/images/formOpen.png")); m_pSaveButton->setIcon(QIcon(":/images/formSave.png")); m_pRemoveButton->setIcon(QIcon(":/images/formRemove.png")); m_pOpenButton->setToolTip(tr("Open Preset")); m_pSaveButton->setToolTip(tr("Save Preset")); m_pRemoveButton->setToolTip(tr("Remove Preset")); QHBoxLayout *pHBoxLayout = new QHBoxLayout(); pHBoxLayout->setContentsMargins(2, 2, 2, 2); pHBoxLayout->setSpacing(4); pHBoxLayout->addWidget(m_pOpenButton); pHBoxLayout->addWidget(m_pComboBox); pHBoxLayout->addWidget(m_pSaveButton); pHBoxLayout->addWidget(m_pRemoveButton); // pHBoxLayout->addSpacing(20); QWidget::setLayout(pHBoxLayout); m_iUpdatePreset = 0; m_iDirtyPreset = 0; // UI signal/slot connections... QObject::connect(m_pComboBox, SIGNAL(editTextChanged(const QString&)), SLOT(changePreset(const QString&))); QObject::connect(m_pOpenButton, SIGNAL(clicked()), SLOT(openPreset())); QObject::connect(m_pSaveButton, SIGNAL(clicked()), SLOT(savePreset())); QObject::connect(m_pRemoveButton, SIGNAL(clicked()), SLOT(removePreset())); } // Destructor. qxgeditEdit::~qxgeditEdit (void) { } // Nominal value accessors. void qxgeditEdit::set_value ( unsigned short /*iValue*/, Observer */*pSender*/ ) { m_iUpdatePreset++; m_pComboBox->setEditText(presetName()); m_iUpdatePreset--; refreshPreset(); stabilizePreset(); } unsigned short qxgeditEdit::value (void) const { return 0; } // Specialty parameter accessors. void qxgeditEdit::set_param ( XGParam *pParam, Observer */*pSender*/ ) { m_pParam = static_cast (pParam); if (m_pParam) { m_pComboBox->lineEdit()->setMaxLength(m_pParam->size()); QWidget::setToolTip(tr("Preset (%1)").arg(m_pParam->text())); set_value(0, observer()); } } XGParam *qxgeditEdit::param (void) const { return static_cast (m_pParam); } // Retrieve current preset name (voice name) QString qxgeditEdit::presetName() const { QString sPreset; if (m_pParam) { sPreset = QString( QByteArray((const char *) m_pParam->data(), m_pParam->size())) .simplified(); } return sPreset; } // Check whether current preset may be reset. bool qxgeditEdit::queryPreset (void) { if (m_pParam == nullptr) return false; const QString& sPreset = presetName(); if (!sPreset.isEmpty()) { qxgeditOptions *pOptions = qxgeditOptions::getInstance(); if (pOptions && pOptions->bConfirmReset) { qxgeditXGMasterMap *pMasterMap = qxgeditXGMasterMap::getInstance(); if (pMasterMap && pMasterMap->user_dirty_2(pMasterMap->USERVOICE.current_key())) { switch (QMessageBox::warning(this, tr("Warning"), tr("Some parameters have been changed:\n\n" "\"%1\".\n\nDo you want to save the changes?") .arg(sPreset), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)) { case QMessageBox::Save: savePreset(sPreset); // Fall thru... case QMessageBox::Discard: break; default: // Cancel... m_iUpdatePreset++; m_pComboBox->setEditText(sPreset); m_iUpdatePreset--; return false; } } } } return true; } // Preset management slots... void qxgeditEdit::changePreset ( const QString& sPreset ) { if (m_iUpdatePreset > 0) return; bool bLoadPreset = (!sPreset.isEmpty() && m_pComboBox->findText(sPreset) >= 0); if (bLoadPreset && !queryPreset()) return; if (m_pParam) { m_pParam->set_data( (unsigned char *) sPreset.toLatin1().data(), sPreset.length(), observer()); m_iDirtyPreset++; } if (bLoadPreset) loadPreset(sPreset); else stabilizePreset(); } void qxgeditEdit::loadPreset ( const QString& sPreset ) { if (m_iUpdatePreset > 0 || sPreset.isEmpty()) return; // We'll need this, sure. qxgeditOptions *pOptions = qxgeditOptions::getInstance(); if (pOptions == nullptr) return; m_iUpdatePreset++; QSettings& settings = pOptions->settings(); settings.beginGroup(presetGroup()); emit loadPresetFile(settings.value(sPreset).toString()); settings.endGroup(); m_iUpdatePreset--; refreshPreset(); stabilizePreset(); } void qxgeditEdit::openPreset (void) { if (m_iUpdatePreset > 0) return; // We'll need this, sure. qxgeditOptions *pOptions = qxgeditOptions::getInstance(); if (pOptions == nullptr) return; // We'll assume that there's an external file... QString sFilename; // Prompt if file does not currently exist... const QString sExt("syx"); const QString& sTitle = tr("Open Preset"); const QString& sFilter = tr("Preset files (*.%1)").arg(sExt); #if 0//QT_VERSION < QT_VERSION_CHECK(4, 4, 0) // Ask for the filename to save... sFilename = QFileDialog::getSaveFileName(parentWidget(), sTitle, pOptions->sPresetDir, sFilter); #else // Construct save-file dialog... QFileDialog fileDialog(parentWidget(), sTitle, pOptions->sPresetDir, sFilter); // Set proper open-file modes... fileDialog.setAcceptMode(QFileDialog::AcceptOpen); fileDialog.setFileMode(QFileDialog::ExistingFile); fileDialog.setDefaultSuffix(sExt); // Stuff sidebar... QList urls(fileDialog.sidebarUrls()); urls.append(QUrl::fromLocalFile(pOptions->sSessionDir)); urls.append(QUrl::fromLocalFile(pOptions->sPresetDir)); fileDialog.setSidebarUrls(urls); // Show dialog... if (fileDialog.exec()) sFilename = fileDialog.selectedFiles().first(); #endif // Have we a filename to load a preset from? if (!sFilename.isEmpty()) { QFileInfo fi(sFilename); if (fi.exists() && queryPreset()) { // Get it loaded alright... m_iUpdatePreset++; emit loadPresetFile(sFilename); m_pComboBox->setEditText(fi.baseName()); pOptions->sPresetDir = fi.absolutePath(); m_iUpdatePreset--; } } refreshPreset(); stabilizePreset(); } void qxgeditEdit::savePreset (void) { savePreset(m_pComboBox->currentText()); } void qxgeditEdit::savePreset ( const QString& sPreset ) { if (sPreset.isEmpty()) return; // We'll need this, sure. qxgeditOptions *pOptions = qxgeditOptions::getInstance(); if (pOptions == nullptr) return; // The current state preset is about to be saved... // this is where we'll make it... QSettings& settings = pOptions->settings(); settings.beginGroup(presetGroup()); // Sure, we'll have something complex enough // to make it save into an external file... const QString sExt("syx"); QFileInfo fi(QDir(pOptions->sPresetDir), sPreset + '.' + sExt); QString sFilename = fi.absoluteFilePath(); // Prompt if file does not currently exist... if (!fi.exists()) { const QString& sTitle = tr("Save Preset"); const QString& sFilter = tr("Preset files (*.%1)").arg(sExt); #if 0//QT_VERSION < QT_VERSION_CHECK(4, 4, 0) // Ask for the filename to save... sFilename = QFileDialog::getSaveFileName(parentWidget(), sTitle, sFilename, sFilter); #else // Construct save-file dialog... QFileDialog fileDialog(parentWidget(), sTitle, sFilename, sFilter); // Set proper open-file modes... fileDialog.setAcceptMode(QFileDialog::AcceptSave); fileDialog.setFileMode(QFileDialog::AnyFile); fileDialog.setDefaultSuffix(sExt); // Stuff sidebar... QList urls(fileDialog.sidebarUrls()); urls.append(QUrl::fromLocalFile(pOptions->sSessionDir)); urls.append(QUrl::fromLocalFile(pOptions->sPresetDir)); fileDialog.setSidebarUrls(urls); // Show dialog... if (fileDialog.exec()) sFilename = fileDialog.selectedFiles().first(); #endif } else if (pOptions->bConfirmRemove) { if (QMessageBox::warning(parentWidget(), tr("Warning"), tr("About to replace preset:\n\n" "\"%1\"\n\n" "Are you sure?") .arg(sPreset), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { sFilename.clear(); } } // We've a filename to save the preset if (!sFilename.isEmpty()) { if (QFileInfo(sFilename).suffix() != sExt) sFilename += '.' + sExt; // Get it saved alright... m_iUpdatePreset++; emit savePresetFile(sFilename); settings.setValue(sPreset, sFilename); pOptions->sPresetDir = QFileInfo(sFilename).absolutePath(); m_iUpdatePreset--; } settings.endGroup(); refreshPreset(); stabilizePreset(); } void qxgeditEdit::removePreset (void) { if (m_iUpdatePreset > 0) return; const QString& sPreset = m_pComboBox->currentText(); if (sPreset.isEmpty()) return; // We'll need this, sure. qxgeditOptions *pOptions = qxgeditOptions::getInstance(); if (pOptions == nullptr) return; // A preset entry is about to be removed; // prompt user if he/she's sure about this... if (pOptions->bConfirmRemove) { if (QMessageBox::warning(parentWidget(), tr("Warning"), tr("About to remove preset:\n\n" "\"%1\"\n\n" "Are you sure?") .arg(sPreset), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } // Go ahead... m_iUpdatePreset++; QSettings& settings = pOptions->settings(); settings.beginGroup(presetGroup()); #ifdef QXGEDIT_REMOVE_PRESET_FILES const QString& sFilename = settings.value(sPreset).toString(); if (QFileInfo(sFilename).exists()) QFile(sFilename).remove(); #endif settings.remove(sPreset); settings.endGroup(); m_iUpdatePreset--; refreshPreset(); stabilizePreset(); } // Widget refreshner-loader. void qxgeditEdit::refreshPreset (void) { if (m_iUpdatePreset > 0) return; m_iUpdatePreset++; const QString sOldPreset = m_pComboBox->currentText(); m_pComboBox->clear(); qxgeditOptions *pOptions = qxgeditOptions::getInstance(); if (pOptions) { pOptions->settings().beginGroup(presetGroup()); m_pComboBox->insertItems(0, pOptions->settings().childKeys()); m_pComboBox->model()->sort(0); pOptions->settings().endGroup(); } int iIndex = m_pComboBox->findText(sOldPreset); if (iIndex >= 0) m_pComboBox->setCurrentIndex(iIndex); else m_pComboBox->setEditText(sOldPreset); m_iDirtyPreset = 0; m_iUpdatePreset--; } // Preset control. void qxgeditEdit::stabilizePreset (void) { const QString& sPreset = m_pComboBox->currentText(); bool bEnabled = (!sPreset.isEmpty()); bool bExists = (m_pComboBox->findText(sPreset) >= 0); bool bDirty = (m_iDirtyPreset > 0); if (!bDirty) { qxgeditXGMasterMap *pMasterMap = qxgeditXGMasterMap::getInstance(); if (pMasterMap) bDirty = pMasterMap->user_dirty_2(pMasterMap->USERVOICE.current_key()); } m_pSaveButton->setEnabled(bEnabled && (!bExists || bDirty)); m_pRemoveButton->setEnabled(bEnabled && bExists); } // Preset group path name. QString qxgeditEdit::presetGroup (void) { return "/Uservoice/Presets/"; } // end of qxgeditEdit.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditDrumEg.cpp0000644000000000000000000000013214772452451016313 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditDrumEg.cpp0000644000175000001440000001323614772452451016310 0ustar00rncbcusers// qxgeditDrumEg.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditDrumEg.h" #include #include #include //---------------------------------------------------------------------------- // qxgeditDrumEg -- Custom widget // Constructor. qxgeditDrumEg::qxgeditDrumEg ( QWidget *pParent ) : QFrame(pParent), m_iAttack(0), m_iDecay1(0), m_iDecay2(0), m_poly(6), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditDrumEg::~qxgeditDrumEg (void) { } // Parameter accessors. void qxgeditDrumEg::setAttack ( unsigned short iAttack ) { if (m_iAttack != iAttack) { m_iAttack = iAttack; update(); emit attackChanged(attack()); } } unsigned short qxgeditDrumEg::attack (void) const { return m_iAttack; } void qxgeditDrumEg::setDecay1 ( unsigned short iDecay1 ) { if (m_iDecay1 != iDecay1) { m_iDecay1 = iDecay1; update(); emit decay1Changed(decay1()); } } unsigned short qxgeditDrumEg::decay1 (void) const { return m_iDecay1; } void qxgeditDrumEg::setDecay2 ( unsigned short iDecay2 ) { if (m_iDecay2 != iDecay2) { m_iDecay2 = iDecay2; update(); emit decay2Changed(decay2()); } } unsigned short qxgeditDrumEg::decay2 (void) const { return m_iDecay2; } // Draw curve. void qxgeditDrumEg::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = h >> 1; const int w3 = (w / 3) - 3; const int x1 = int((m_iAttack * w3) >> 7) + 6; const int x2 = int((m_iDecay1 * w3) >> 7) + x1; const int x3 = int((m_iDecay2 * w3) >> 7) + x2; m_poly.putPoints(0, 6, 0, h, 6, h - 6, x1, 6, x2, h2, x3, h - 6, x3 + 6, h); QPainterPath path; path.addPolygon(m_poly); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); QLinearGradient grad(0, 0, w << 1, h << 1); grad.setColorAt(0.0f, rgbLite); grad.setColorAt(1.0f, Qt::black); painter.setBrush(grad); painter.drawPath(path); painter.setBrush(pal.mid().color()); painter.drawRect(nodeRect(1)); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(2)); painter.drawRect(nodeRect(3)); painter.drawRect(nodeRect(4)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Attack (%1) Decay1 (%2) Decay2 (%3)") .arg(int(attack()) - 64) .arg(int(decay1()) - 64) .arg(int(decay2()) - 64)); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditDrumEg::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditDrumEg::nodeIndex ( const QPoint& pos ) const { if (nodeRect(4).contains(pos)) return 4; // Decay2 if (nodeRect(3).contains(pos)) return 3; // Decay1 if (nodeRect(2).contains(pos)) return 2; // Attack return -1; } void qxgeditDrumEg::dragNode ( const QPoint& pos ) { unsigned short *piValue = nullptr; switch (m_iDragNode) { case 2: // Attack piValue = &m_iAttack; break; case 3: // Decay1 piValue = &m_iDecay1; break; case 4: // Decay2 piValue = &m_iDecay2; break; } if (piValue) { int iValue = int(*piValue) + ((pos.x() - m_posDrag.x()) << 7) / (width() >> 2); if (iValue < 0) iValue = 0; else if (iValue > 127) iValue = 127; if (*piValue != (unsigned short) iValue) { m_posDrag = pos; switch (m_iDragNode) { case 2: // Attack setAttack(iValue); break; case 3: // Decay1 setDecay1(iValue); break; case 4: // Decay2 setDecay2(iValue); break; } } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditDrumEg::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(Qt::SizeHorCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditDrumEg::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditDrumEg::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditDrumEg.cpp qxgedit-1.0.1/src/PaxHeaders/XGParamObserver.cpp0000644000000000000000000000013214772452451016551 xustar0030 mtime=1743410473.474221551 30 atime=1743410473.474221551 30 ctime=1743410473.474221551 qxgedit-1.0.1/src/XGParamObserver.cpp0000644000175000001440000000372714772452451016552 0ustar00rncbcusers// XGParamObserver.cpp // /**************************************************************************** Copyright (C) 2005-2009, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "XGParam.h" //--------------------------------------------------------------------------- // XGParamObserver - Scalar parameter value control/view. // Constructor. XGParamObserver::XGParamObserver ( XGParam *param ) : m_param(param) { if (m_param) m_param->attach(this); } // Virtual destructor. XGParamObserver::~XGParamObserver (void) { if (m_param) m_param->detach(this); } // Subject value accessor. void XGParamObserver::set_param ( XGParam *param ) { if (m_param /* && param */) m_param->detach(this); m_param = param; if (m_param) m_param->attach(this); } XGParam *XGParamObserver::param (void) const { return m_param; } // Indirect value accessors. void XGParamObserver::set_value ( unsigned short u ) { if (m_param) m_param->set_value(u, this); } unsigned short XGParamObserver::value (void) const { return (m_param ? m_param->value() : 0); } // Busy flag predicate. bool XGParamObserver::busy (void) const { return (m_param ? m_param->busy() : true); } // end of XGParamObserver.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditUserEg.cpp0000644000000000000000000000013214772452451016322 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditUserEg.cpp0000644000175000001440000002076214772452451016321 0ustar00rncbcusers// qxgeditUserEg.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditUserEg.h" #include #include //---------------------------------------------------------------------------- // qxgeditUserEg -- Custom widget // Constructor. qxgeditUserEg::qxgeditUserEg ( QWidget *pParent ) : QFrame(pParent), m_iLevel0(0), m_iLevel1(0), m_iLevel2(0), m_iLevel3(0), m_iLevel4(0), m_iRate1(0), m_iRate2(0), m_iRate3(0), m_iRate4(0), m_poly(6), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditUserEg::~qxgeditUserEg (void) { } // Parameter accessors. void qxgeditUserEg::setLevel0 ( unsigned short iLevel0 ) { if (m_iLevel0 != iLevel0) { m_iLevel0 = iLevel0; update(); emit level0Changed(level0()); } } unsigned short qxgeditUserEg::level0 (void) const { return m_iLevel0; } void qxgeditUserEg::setLevel1 ( unsigned short iLevel1 ) { if (m_iLevel1 != iLevel1) { m_iLevel1 = iLevel1; update(); emit level1Changed(level1()); } } unsigned short qxgeditUserEg::level1 (void) const { return m_iLevel1; } void qxgeditUserEg::setLevel2 ( unsigned short iLevel2 ) { if (m_iLevel2 != iLevel2) { m_iLevel2 = iLevel2; update(); emit level2Changed(level2()); } } unsigned short qxgeditUserEg::level2 (void) const { return m_iLevel2; } void qxgeditUserEg::setLevel3 ( unsigned short iLevel3 ) { if (m_iLevel3 != iLevel3) { m_iLevel3 = iLevel3; update(); emit level3Changed(level3()); } } unsigned short qxgeditUserEg::level3 (void) const { return m_iLevel3; } void qxgeditUserEg::setLevel4 ( unsigned short iLevel4 ) { if (m_iLevel4 != iLevel4) { m_iLevel4 = iLevel4; update(); emit level4Changed(level4()); } } unsigned short qxgeditUserEg::level4 (void) const { return m_iLevel4; } void qxgeditUserEg::setRate1 ( unsigned short iRate1 ) { if (m_iRate1 != iRate1) { m_iRate1 = iRate1; update(); emit rate1Changed(rate1()); } } unsigned short qxgeditUserEg::rate1 (void) const { return m_iRate1; } void qxgeditUserEg::setRate2 ( unsigned short iRate2 ) { if (m_iRate2 != iRate2) { m_iRate2 = iRate2; update(); emit rate2Changed(rate2()); } } unsigned short qxgeditUserEg::rate2 (void) const { return m_iRate2; } void qxgeditUserEg::setRate3 ( unsigned short iRate3 ) { if (m_iRate3 != iRate3) { m_iRate3 = iRate3; update(); emit rate3Changed(rate3()); } } unsigned short qxgeditUserEg::rate3 (void) const { return m_iRate3; } void qxgeditUserEg::setRate4 ( unsigned short iRate4 ) { if (m_iRate4 != iRate4) { m_iRate4 = iRate4; update(); emit rate4Changed(rate4()); } } unsigned short qxgeditUserEg::rate4 (void) const { return m_iRate4; } // Draw curve. void qxgeditUserEg::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = (h >> 1); const int w5 = (w - 9) / 5; const int x1 = int(((63 - m_iRate1) * w5) >> 6) + 6; const int x2 = int(((63 - m_iRate2) * w5) >> 6) + x1; const int x3 = int(((63 - m_iRate3) * w5) >> 6) + x2; const int x4 = int(((63 - m_iRate4) * w5) >> 6) + x3 + w5; const int y0 = h - int((m_iLevel0 * (h - 12)) >> 7) - 6; const int y1 = h - int((m_iLevel1 * (h - 12)) >> 7) - 6; const int y2 = h - int((m_iLevel2 * (h - 12)) >> 7) - 6; const int y3 = h - int((m_iLevel3 * (h - 12)) >> 7) - 6; const int y4 = h - int((m_iLevel4 * (h - 12)) >> 7) - 6; m_poly.putPoints(0, 6, 6, y0, x1, y1, x2, y2, x3, y3, x3 + w5, y3, x4, y4); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); const QPen oldpen(painter.pen()); QPen dotpen(oldpen); dotpen.setStyle(Qt::DotLine); painter.setPen(dotpen); painter.drawLine(0, h2, w, h2); painter.setPen(oldpen); painter.drawPolyline(m_poly); painter.setBrush(pal.mid().color()); painter.drawRect(nodeRect(4)); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(0)); painter.drawRect(nodeRect(1)); painter.drawRect(nodeRect(2)); painter.drawRect(nodeRect(3)); painter.drawRect(nodeRect(5)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Level (%1,%2,%3,%4,%5) Rate (0,%6,%7,%8,%9)") .arg(int(level0())) .arg(int(level1())) .arg(int(level2())) .arg(int(level3())) .arg(int(level4())) .arg(int(rate1()) .arg(int(rate2()) .arg(int(rate3()) .arg(int(rate4())); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditUserEg::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditUserEg::nodeIndex ( const QPoint& pos ) const { if (nodeRect(5).contains(pos)) return 5; // Level4/Rate4 if (nodeRect(3).contains(pos)) return 3; // Level3/Rate3 if (nodeRect(2).contains(pos)) return 2; // Level2/Rate2 if (nodeRect(1).contains(pos)) return 1; // Level1/Rate1 if (nodeRect(0).contains(pos)) return 0; // Level0 return -1; } void qxgeditUserEg::dragNode ( const QPoint& pos ) { static unsigned short m_iRate0 = 0; // Dummy! unsigned short *piLevel = nullptr; unsigned short *piRate = nullptr; switch (m_iDragNode) { case 0: // Level0 piLevel = &m_iLevel0; piRate = &m_iRate0; break; case 1: // Level1/Rate1 piLevel = &m_iLevel1; piRate = &m_iRate1; break; case 2: // Level2/Rate2 piLevel = &m_iLevel2; piRate = &m_iRate2; break; case 3: // Level3/Rate3 piLevel = &m_iLevel3; piRate = &m_iRate3; break; case 5: // Level4/Rate4 piLevel = &m_iLevel4; piRate = &m_iRate4; break; } if (piLevel && piRate) { int iLevel = int(*piLevel) + ((m_posDrag.y() - pos.y()) << 7) / height(); int iRate = int(*piRate) - ((pos.x() - m_posDrag.x()) << 6) / (width() >> 2); if (iLevel < 0) iLevel = 0; else if (iLevel > 127) iLevel = 127; if (iRate < 0) iRate = 0; else if (iRate > 63) iRate = 63; if (*piLevel != (unsigned short) iLevel || *piRate != (unsigned short) iRate) { m_posDrag = pos; switch (m_iDragNode) { case 0: // Level0 setLevel0(iLevel); break; case 1: // Level1/Rate1 setLevel1(iLevel); setRate1(iRate); break; case 2: // Level2/Rate2 setLevel2(iLevel); setRate2(iRate); break; case 3: // Level3/Rate3 setLevel3(iLevel); setRate3(iRate); break; case 5: // Level4/Rate4 setLevel4(iLevel); setRate4(iRate); break; } } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditUserEg::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(iDragNode == 0 ? Qt::SizeVerCursor : Qt::SizeAllCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditUserEg::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditUserEg::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditUserEg.cpp qxgedit-1.0.1/src/PaxHeaders/palette0000644000000000000000000000013214772452451014417 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475322864 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/palette/0000755000175000001440000000000014772452451014464 5ustar00rncbcusersqxgedit-1.0.1/src/palette/PaxHeaders/KXStudio.conf0000644000000000000000000000013214772452451017055 xustar0030 mtime=1743410473.475322864 30 atime=1743410473.475322864 30 ctime=1743410473.475322864 qxgedit-1.0.1/src/palette/KXStudio.conf0000644000175000001440000000165514772452451017054 0ustar00rncbcusers[ColorThemes] KXStudio\AlternateBase=#0e0e0e, #0e0e0e, #0c0c0c KXStudio\Base=#070707, #070707, #060606 KXStudio\BrightText=#ffffff, #ffffff, #ffffff KXStudio\Button=#1c1c1c, #1c1c1c, #181818 KXStudio\ButtonText=#f0f0f0, #f0f0f0, #5a5a5a KXStudio\Dark=#818181, #818181, #818181 KXStudio\Highlight=#3c3c3c, #222222, #0e0e0e KXStudio\HighlightedText=#ffffff, #f0f0f0, #535353 KXStudio\Light=#bfbfbf, #bfbfbf, #bfbfbf KXStudio\Link=#6464e6, #6464e6, #22224a KXStudio\LinkVisited=#e664e6, #e664e6, #4a224a KXStudio\Mid=#5e5e5e, #5e5e5e, #5e5e5e KXStudio\Midlight=#9b9b9b, #9b9b9b, #9b9b9b KXStudio\NoRole=#000000, #000000, #000000 KXStudio\PlaceholderText=#000000, #000000, #000000 KXStudio\Shadow=#9b9b9b, #9b9b9b, #9b9b9b KXStudio\Text=#e6e6e6, #e6e6e6, #4a4a4a KXStudio\ToolTipBase=#040404, #040404, #040404 KXStudio\ToolTipText=#e6e6e6, #e6e6e6, #e6e6e6 KXStudio\Window=#111111, #111111, #0e0e0e KXStudio\WindowText=#f0f0f0, #f0f0f0, #535353 qxgedit-1.0.1/src/palette/PaxHeaders/Wonton Soup.conf0000644000000000000000000000013214772452451017536 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475322864 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/palette/Wonton Soup.conf0000644000175000001440000000202614772452451017526 0ustar00rncbcusers[ColorThemes] Wonton%20Soup\AlternateBase=#434750, #434750, #3b3e46 Wonton%20Soup\Base=#3c4048, #3c4048, #34383f Wonton%20Soup\BrightText=#ffffff, #ffffff, #ffffff Wonton%20Soup\Button=#525863, #525863, #484d57 Wonton%20Soup\ButtonText=#d2def0, #d2def0, #6f7682 Wonton%20Soup\Dark=#282b31, #282b31, #23262b Wonton%20Soup\Highlight=#78889c, #515a67, #40444d Wonton%20Soup\HighlightedText=#d1e1f4, #b6c1d0, #616872 Wonton%20Soup\Light=#5f6572, #5f6572, #565c68 Wonton%20Soup\Link=#9cd4ff, #9cd4ff, #526677 Wonton%20Soup\LinkVisited=#4080ff, #4080ff, #364c77 Wonton%20Soup\Mid=#3f444c, #3f444c, #383b43 Wonton%20Soup\Midlight=#545a65, #545a65, #4b515b Wonton%20Soup\NoRole=#000000, #000000, #000000 Wonton%20Soup\PlaceholderText=#000000, #000000, #000000 Wonton%20Soup\Shadow=#1d1f23, #1d1f23, #191b1e Wonton%20Soup\Text=#d2def0, #d2def0, #636973 Wonton%20Soup\ToolTipBase=#b6c1d0, #b6c1d0, #b6c1d0 Wonton%20Soup\ToolTipText=#2a2c30, #2a2c30, #2a2c30 Wonton%20Soup\Window=#494e58, #494e58, #40444d Wonton%20Soup\WindowText=#b6c1d0, #b6c1d0, #616872 qxgedit-1.0.1/src/PaxHeaders/qxgeditSpin.h0000644000000000000000000000013214772452451015506 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditSpin.h0000644000175000001440000000457014772452451015504 0ustar00rncbcusers// qxgeditSpin.h // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditSpin_h #define __qxgeditSpin_h #include // Forward declarations. class XGParam; class XGParamObserver; //------------------------------------------------------------------------- // qxgeditSpin - A custom QSpinBox class qxgeditSpin : public QAbstractSpinBox { Q_OBJECT public: // Constructor. qxgeditSpin(QWidget *pParent = 0); // Destructor. ~qxgeditSpin(); // Specialty parameter accessors. void setParam(XGParam *pParam, XGParamObserver *pSender = nullptr); XGParam *param() const; // Value accessors. void setValue(unsigned short iValue, XGParamObserver *pSender = nullptr); unsigned short value() const; protected slots: // Pseudo-fixup slot. void editingFinishedSlot(); void valueChangedSlot(const QString&); signals: // Common value change notification. void valueChanged(unsigned short); void valueChanged(const QString&); protected: // Mark that we got actual value. void showEvent(QShowEvent *); // Inherited/override methods. QValidator::State validate(QString& sText, int& iPos) const; void fixup(QString& sText) const; void stepBy(int iSteps); StepEnabled stepEnabled() const; // Value/text format converters. unsigned short valueFromText(const QString& sText) const; QString textFromValue(unsigned short iValue) const; private: // Instance variables: // - XG parameter reference. XGParam *m_pParam; }; #endif // __qxgeditSpin_h // end of qxgeditSpin.h qxgedit-1.0.1/src/PaxHeaders/appdata0000644000000000000000000000013214772452451014373 xustar0030 mtime=1743410473.474959861 30 atime=1743410473.474607941 30 ctime=1743410473.474959861 qxgedit-1.0.1/src/appdata/0000755000175000001440000000000014772452451014440 5ustar00rncbcusersqxgedit-1.0.1/src/appdata/PaxHeaders/org.rncbc.qxgedit.metainfo.xml0000644000000000000000000000013214772452451022314 xustar0030 mtime=1743410473.474959861 30 atime=1743410473.474607941 30 ctime=1743410473.474959861 qxgedit-1.0.1/src/appdata/org.rncbc.qxgedit.metainfo.xml0000644000175000001440000000341614772452451022310 0ustar00rncbcusers org.rncbc.qxgedit FSFAP GPL-2.0+ QXGEdit Qt XG Editor Éditeur XG Qt

QXGEdit is a Qt GUI for editing MIDI System Exclusive files for XG devices (eg. Yamaha DB50XG).

QXGedit est une interface Qt pour l'édition des fichiers MIDI Sysex (System Exclusive) pour les périphériques XG (exemple : Yamaha DB50XG).

org.rncbc.qxgedit.desktop qxgedit https://qxgedit.sourceforge.io/image/qxgedit-screenshot2.png The main window showing the application in action Fenêtre principale montrant l'application en action MIDI ALSA DB50XG Editor SYX XG Qt https://qxgedit.sourceforge.io rncbc.org rncbc aka. Rui Nuno Capela rncbc@rncbc.org
qxgedit-1.0.1/src/appdata/PaxHeaders/org.rncbc.qxgedit.desktop0000644000000000000000000000013214772452451021364 xustar0030 mtime=1743410473.474607941 30 atime=1743410473.474607941 30 ctime=1743410473.474607941 qxgedit-1.0.1/src/appdata/org.rncbc.qxgedit.desktop0000644000175000001440000000063514772452451021360 0ustar00rncbcusers[Desktop Entry] Name=QXGEdit Version=1.0 GenericName=XG Editor GenericName[fr]=Éditeur XG Comment=QXGEdit is a Qt GUI XG editor application Comment[fr]=Interface graphique d'édition XG Exec=qxgedit %f Icon=org.rncbc.qxgedit Categories=Audio;AudioVideo;Midi;X-Alsa;Qt; Keywords=MIDI;ALSA;DB50XG;SYX;XG;Editor;Qt; Terminal=false Type=Application StartupWMClass=qxgedit X-Window-Icon=qxgedit X-SuSE-translate=true qxgedit-1.0.1/src/PaxHeaders/qxgeditVibra.cpp0000644000000000000000000000013214772452451016173 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditVibra.cpp0000644000175000001440000001406614772452451016172 0ustar00rncbcusers// qxgeditVibra.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditVibra.h" #include #include #include //---------------------------------------------------------------------------- // qxgeditVibra -- Custom widget // Constructor. qxgeditVibra::qxgeditVibra ( QWidget *pParent ) : QFrame(pParent), m_iDelay(0), m_iRate(0), m_iDepth(0), m_poly(3), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditVibra::~qxgeditVibra (void) { } // Parameter accessors. void qxgeditVibra::setDelay ( unsigned short iDelay ) { if (m_iDelay != iDelay) { m_iDelay = iDelay; update(); emit delayChanged(delay()); } } unsigned short qxgeditVibra::delay (void) const { return m_iDelay; } void qxgeditVibra::setRate ( unsigned short iRate ) { if (m_iRate != iRate) { m_iRate = iRate; update(); emit rateChanged(rate()); } } unsigned short qxgeditVibra::rate (void) const { return m_iRate; } void qxgeditVibra::setDepth ( unsigned short iDepth ) { if (m_iDepth != iDepth) { m_iDepth = iDepth; update(); emit depthChanged(depth()); } } unsigned short qxgeditVibra::depth (void) const { return m_iDepth; } // Draw curve. void qxgeditVibra::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = h >> 1; const int w2 = w >> 1; const int w4 = w >> 2; const int x1 = int((m_iDelay * w2) >> 7) + 6; const int y1 = h2 + (m_iDepth > 64 ? 0 : int((64 - m_iDepth) * (h - 9)) >> 7); int x2 = int(((127 - m_iRate) * w4) >> 7) + x1; int y2 = (m_iDepth < 64 ? 0 : int((m_iDepth - 64) * (h - 9)) >> 7); m_poly.putPoints(0, 3, 0, y1, x1, y1, x2, y1 - y2); QPainterPath path; path.addPolygon(m_poly); const int dx = ((x2 - x1) << 1) + 1; while (x2 < w) { x2 += dx; y2 = -y2; path.lineTo(x2, y1 - y2); } path.lineTo(x2, h); path.lineTo(0, h); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); QLinearGradient grad(0, 0, w << 1, h << 1); grad.setColorAt(0.0f, rgbLite); grad.setColorAt(1.0f, Qt::black); painter.setBrush(grad); painter.drawPath(path); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(1)); painter.drawRect(nodeRect(2)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Delay (%1) Rate (%2) Depth (%3)") .arg(int(delay()) - 64) .arg(int(rate()) - 64) .arg(int(depth()) - 64)); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditVibra::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditVibra::nodeIndex ( const QPoint& pos ) const { if (nodeRect(2).contains(pos)) return 2; // Rate/Depth if (nodeRect(1).contains(pos)) return 1; // Delay return -1; } void qxgeditVibra::dragNode ( const QPoint& pos ) { if (m_iDragNode == 2) { // Rate/Depth int iRate = int(m_iRate) - ((pos.x() - m_posDrag.x()) << 7) / (width() >> 1); int iDepth = int(m_iDepth) - ((pos.y() - m_posDrag.y()) << 7) / (height() >> 1); if (iRate < 0) iRate = 0; else if (iRate > 127) iRate = 127; if (iDepth < 0) iDepth = 0; else if (iDepth > 127) iDepth = 127; if (m_iRate != (unsigned short) iRate || m_iDepth != (unsigned short) iDepth) { m_posDrag = pos; setRate(iRate); setDepth(iDepth); } } else if (m_iDragNode == 1) { // Delay... int iDelay = int(m_iDelay) + ((pos.x() - m_posDrag.x()) << 7) / (width() >> 1); int iDepth = int(m_iDepth) - ((pos.y() - m_posDrag.y()) << 7) / (height() >> 1); if (iDelay < 0) iDelay = 0; else if (iDelay > 127) iDelay = 127; if (iDepth < 0) iDepth = 0; else if (iDepth > 127) iDepth = 127; if (m_iDelay != (unsigned short) iDelay || m_iDepth != (unsigned short) iDepth) { m_posDrag = pos; setDelay(iDelay); setDepth(iDepth); } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditVibra::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(iDragNode > 1 ? Qt::SizeAllCursor : Qt::SizeHorCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditVibra::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditVibra::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditVibra.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditCombo.cpp0000644000000000000000000000013214772452451016167 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditCombo.cpp0000644000175000001440000000656314772452451016171 0ustar00rncbcusers// qxgeditCombo.cpp // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditCombo.h" //------------------------------------------------------------------------- // qxgeditCombo - Custom combo-box widget. // // Constructor. qxgeditCombo::qxgeditCombo ( QWidget *pParent ) : XGParamWidget (pParent), m_pParam(nullptr) { QComboBox::setMinimumWidth(140); QComboBox::setMaximumHeight(QFontMetrics(font()).lineSpacing() + 2); QComboBox::setMaxVisibleItems(16); QObject::connect(this, SIGNAL(activated(int)), SLOT(comboActivated(int))); } // Destructor. qxgeditCombo::~qxgeditCombo (void) { } // Nominal value accessors. void qxgeditCombo::set_value ( unsigned short iValue, Observer *pSender ) { if (m_pParam == nullptr) return; if (iValue < m_pParam->min()) iValue = m_pParam->min(); if (iValue > m_pParam->max() && m_pParam->max() > m_pParam->min()) iValue = m_pParam->max(); bool bValueChanged = (iValue != m_pParam->value()); m_pParam->set_value(iValue, pSender); int iCombo = QComboBox::findData(iValue); if (iCombo >= 0) QComboBox::setCurrentIndex(iCombo); QPalette pal; if (QComboBox::isEnabled() && iValue != m_pParam->def()) { const QColor& rgbBase = (pal.window().color().value() < 0x7f ? QColor(Qt::darkYellow).darker() : QColor(Qt::yellow).lighter()); pal.setColor(QPalette::Base, rgbBase); // pal.setColor(QPalette::Text, Qt::black); } QComboBox::setPalette(pal); if (bValueChanged) emit valueChanged(iValue); } unsigned short qxgeditCombo::value (void) const { return (m_pParam ? m_pParam->value() : 0); } // Specialty parameter accessors. void qxgeditCombo::set_param ( XGParam *pParam, Observer */*pSender*/ ) { m_pParam = pParam; QComboBox::clear(); QComboBox::setPalette(QPalette()); XGParamMap *pParamMap = param_map(); if (pParamMap) { const XGParamMap::Keys& keys = pParamMap->keys(); XGParamMap::Keys::const_iterator iter = keys.constBegin(); for (; iter != keys.constEnd(); ++iter) QComboBox::addItem(iter.value(), iter.key()); } if (m_pParam) { int iCombo = QComboBox::findData(m_pParam->value()); if (iCombo >= 0) QComboBox::setCurrentIndex(iCombo); QComboBox::setToolTip(m_pParam->text()); } } XGParam *qxgeditCombo::param (void) const { return m_pParam; } // Internal widget slots. void qxgeditCombo::comboActivated ( int iCombo ) { set_value((unsigned short) QComboBox::itemData(iCombo).toUInt(), observer()); emit valueChanged(value()); } // end of qxgeditCombo.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditPartEg.cpp0000644000000000000000000000013214772452451016312 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPartEg.cpp0000644000175000001440000001333214772452451016304 0ustar00rncbcusers// qxgeditPartEg.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditPartEg.h" #include #include #include //---------------------------------------------------------------------------- // qxgeditPartEg -- Custom widget // Constructor. qxgeditPartEg::qxgeditPartEg ( QWidget *pParent ) : QFrame(pParent), m_iAttack(0), m_iDecay(0), m_iRelease(0), m_poly(7), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditPartEg::~qxgeditPartEg (void) { } // Parameter accessors. void qxgeditPartEg::setAttack ( unsigned short iAttack ) { if (m_iAttack != iAttack) { m_iAttack = iAttack; update(); emit attackChanged(attack()); } } unsigned short qxgeditPartEg::attack (void) const { return m_iAttack; } void qxgeditPartEg::setDecay ( unsigned short iDecay ) { if (m_iDecay != iDecay) { m_iDecay = iDecay; update(); emit decayChanged(decay()); } } unsigned short qxgeditPartEg::decay (void) const { return m_iDecay; } void qxgeditPartEg::setRelease ( unsigned short iRelease ) { if (m_iRelease != iRelease) { m_iRelease = iRelease; update(); emit releaseChanged(release()); } } unsigned short qxgeditPartEg::release (void) const { return m_iRelease; } // Draw curve. void qxgeditPartEg::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = h >> 1; const int w4 = w >> 2; const int x1 = int((m_iAttack * w4) >> 7); const int x2 = int((m_iDecay * w4) >> 7) + x1; const int x3 = int((m_iRelease * w4) >> 7) + x2 + w4; m_poly.putPoints(0, 7, 0, h, 6, h - 6, x1 + 6, 6, x2 + 6, h2, x2 + w4 - 6, h2, x3 - 6, h - 6, x3, h); QPainterPath path; path.addPolygon(m_poly); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); QLinearGradient grad(0, 0, w << 1, h << 1); grad.setColorAt(0.0f, rgbLite); grad.setColorAt(1.0f, Qt::black); painter.setBrush(grad); painter.drawPath(path); painter.setBrush(pal.mid().color()); painter.drawRect(nodeRect(1)); painter.drawRect(nodeRect(4)); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(2)); painter.drawRect(nodeRect(3)); painter.drawRect(nodeRect(5)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Attack (%1) Decay (%2) Release (%3)") .arg(int(attack()) - 64) .arg(int(decay()) - 64) .arg(int(release()) - 64)); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditPartEg::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditPartEg::nodeIndex ( const QPoint& pos ) const { if (nodeRect(5).contains(pos)) return 5; // Release if (nodeRect(3).contains(pos)) return 3; // Decay if (nodeRect(2).contains(pos)) return 2; // Attack return -1; } void qxgeditPartEg::dragNode ( const QPoint& pos ) { unsigned short *piValue = nullptr; switch (m_iDragNode) { case 2: // Attack piValue = &m_iAttack; break; case 3: // Decay piValue = &m_iDecay; break; case 5: // Release piValue = &m_iRelease; break; } if (piValue) { int iValue = int(*piValue) + ((pos.x() - m_posDrag.x()) << 7) / (width() >> 2); if (iValue < 0) iValue = 0; else if (iValue > 127) iValue = 127; if (*piValue != (unsigned short) iValue) { m_posDrag = pos; switch (m_iDragNode) { case 2: // Attack setAttack(iValue); break; case 3: // Decay setDecay(iValue); break; case 5: // Release setRelease(iValue); break; } } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditPartEg::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(Qt::SizeHorCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditPartEg::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditPartEg::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditPartEg.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditMidiDevice.cpp0000644000000000000000000000013214772452451017132 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditMidiDevice.cpp0000644000175000001440000005165114772452451017132 0ustar00rncbcusers// qxgeditMidiDevice.cpp // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditMidiDevice.h" #include "qxgeditMidiRpn.h" #include #include #ifdef CONFIG_ALSA_MIDI #include #endif #ifdef CONFIG_RTMIDI #include #endif #include //---------------------------------------------------------------------------- // qxgeditMidiDevice::Impl -- MIDI Device interface object. class qxgeditMidiDevice::Impl { public: // Constructor. Impl(qxgeditMidiDevice *pMidiDevice, const QString& sClientName); // Destructor. ~Impl(); #ifdef CONFIG_ALSA_MIDI // ALSA client descriptor accessor. snd_seq_t *alsaSeq() const; // MIDI event capture method. void capture(snd_seq_event_t *pEv); #endif #ifdef CONFIG_RTMIDI // RtMidi descriptor accessors. RtMidiIn *midiIn() const; RtMidiOut *midiOut() const; // MIDI event capture method. void capture(const QByteArray& midi); #endif // MIDI SysEx sender. void sendSysex(const QByteArray& sysex) const; void sendSysex(unsigned char *pSysex, unsigned short iSysex) const; // MIDI Input(readable) / Output(writable) device list QStringList inputs() const { return deviceList(true); } QStringList outputs() const { return deviceList(false); } // MIDI Input(readable) / Output(writable) connects. bool connectInputs(const QStringList& inputs) const { return connectDeviceList(true, inputs); } bool connectOutputs(const QStringList& outputs) const { return connectDeviceList(false, outputs); } protected: // MIDI device listing. QStringList deviceList(bool bReadable) const; // MIDI device connects. bool connectDeviceList(bool bReadable, const QStringList& list) const; private: // Instance variables. qxgeditMidiDevice *m_pMidiDevice; #ifdef CONFIG_ALSA_MIDI snd_seq_t *m_pAlsaSeq; int m_iAlsaClient; int m_iAlsaInPort; int m_iAlsaOutPort; // Name says it all. class InputRpn; class InputThread; InputThread *m_pInputThread; #endif #ifdef CONFIG_RTMIDI RtMidiIn *m_pMidiIn; RtMidiOut *m_pMidiOut; qxgeditMidiRpn m_xrpn; #endif }; #ifdef CONFIG_ALSA_MIDI //---------------------------------------------------------------------- // class qxgeditMidiDevice::InputRpn -- MIDI RPN/NRPN input parser // class qxgeditMidiDevice::Impl::InputRpn : public qxgeditMidiRpn { public: // Constructor. InputRpn() : qxgeditMidiRpn() {} // Encoder. bool process ( const snd_seq_event_t *ev ) { if (ev->type != SND_SEQ_EVENT_CONTROLLER) { qxgeditMidiRpn::flush(); return false; } qxgeditMidiRpn::Event event; event.time = ev->time.tick; event.port = ev->dest.port; event.status = qxgeditMidiRpn::CC | (ev->data.control.channel & 0x0f); event.param = ev->data.control.param; event.value = ev->data.control.value; return qxgeditMidiRpn::process(event); } // Decoder. bool dequeue ( snd_seq_event_t *ev ) { qxgeditMidiRpn::Event event; if (!qxgeditMidiRpn::dequeue(event)) return false; snd_seq_ev_clear(ev); snd_seq_ev_schedule_tick(ev, 0, 0, event.time); snd_seq_ev_set_dest(ev, 0, event.port); snd_seq_ev_set_fixed(ev); switch (qxgeditMidiRpn::Type(event.status & 0x70)) { case qxgeditMidiRpn::CC: // 0x10 ev->type = SND_SEQ_EVENT_CONTROLLER; break; case qxgeditMidiRpn::RPN: // 0x20 ev->type = SND_SEQ_EVENT_REGPARAM; break; case qxgeditMidiRpn::NRPN: // 0x30 ev->type = SND_SEQ_EVENT_NONREGPARAM; break; case qxgeditMidiRpn::CC14: // 0x40 ev->type = SND_SEQ_EVENT_CONTROL14; break; default: return false; } ev->data.control.channel = event.status & 0x0f; ev->data.control.param = event.param; ev->data.control.value = event.value; return true; } }; //---------------------------------------------------------------------- // class qxgeditMidiDevice::Impl::InputThread -- MIDI input thread (singleton). // class qxgeditMidiDevice::Impl::InputThread : public QThread { public: // Constructor. InputThread(Impl *pImpl) : QThread(), m_pImpl(pImpl), m_bRunState(false) {} // Run-state accessors. void setRunState(bool bRunState) { m_bRunState = bRunState; } bool runState() const { return m_bRunState; } protected: // The main thread executive. void run() { snd_seq_t *pAlsaSeq = m_pImpl->alsaSeq(); if (pAlsaSeq == nullptr) return; int nfds; struct pollfd *pfds; nfds = snd_seq_poll_descriptors_count(pAlsaSeq, POLLIN); pfds = (struct pollfd *) alloca(nfds * sizeof(struct pollfd)); snd_seq_poll_descriptors(pAlsaSeq, pfds, nfds, POLLIN); InputRpn xrpn; m_bRunState = true; int iPoll = 0; while (m_bRunState && iPoll >= 0) { // Wait for events... iPoll = poll(pfds, nfds, 200); // Timeout? if (iPoll == 0) xrpn.flush(); while (iPoll > 0) { snd_seq_event_t *pEv = nullptr; snd_seq_event_input(pAlsaSeq, &pEv); // Process input event - ... // - enqueue to input track mapping; if (!xrpn.process(pEv)) m_pImpl->capture(pEv); // snd_seq_free_event(pEv); iPoll = snd_seq_event_input_pending(pAlsaSeq, 0); } // Process pending events... while (xrpn.isPending()) { snd_seq_event_t ev; if (xrpn.dequeue(&ev)) m_pImpl->capture(&ev); } } } private: // The thread launcher engine. qxgeditMidiDevice::Impl *m_pImpl; // Whether the thread is logically running. bool m_bRunState; }; #endif // CONFIG_ALSA_MIDI //---------------------------------------------------------------------------- // qxgeditMidiDevice::Impl -- MIDI Device interface object. #ifdef CONFIG_RTMIDI static void qxgeditMidiDevice_midiIn_callback ( double delta_time, std::vector *message, void *user_data ) { qxgeditMidiDevice::Impl *pImpl = static_cast (user_data); if (pImpl) { QByteArray midi; const unsigned int nsize = message->size(); for (unsigned int i = 0; i < nsize; ++i) { const unsigned char ch = message->at(i); midi.append(ch); const int status = (ch & 0xf0); if (status == 0xf0) continue; if (status == 0xf7) { pImpl->capture(midi); midi.clear(); continue; } if (++i >= nsize) break; midi.append(message->at(i)); if (status == 0xc0 || status == 0xd0) { pImpl->capture(midi); midi.clear(); continue; } if (++i >= nsize) break; midi.append(message->at(i)); pImpl->capture(midi); midi.clear(); } } } #endif // CONFIG_RTMIDI // Constructor. qxgeditMidiDevice::Impl::Impl ( qxgeditMidiDevice *pMidiDevice, const QString& sClientName ) { m_pMidiDevice = pMidiDevice; #ifdef CONFIG_ALSA_MIDI m_pAlsaSeq = nullptr; m_iAlsaClient = -1; m_iAlsaInPort = -1; m_iAlsaOutPort = -1; m_pInputThread = nullptr; // Open new ALSA sequencer client... if (snd_seq_open(&m_pAlsaSeq, "hw", SND_SEQ_OPEN_DUPLEX, 0) >= 0) { // Set client identification... snd_seq_set_client_name(m_pAlsaSeq, sClientName.toLatin1().constData()); m_iAlsaClient = snd_seq_client_id(m_pAlsaSeq); // Create in/out ports... m_iAlsaInPort = snd_seq_create_simple_port(m_pAlsaSeq, "in", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); m_iAlsaOutPort = snd_seq_create_simple_port(m_pAlsaSeq, "out", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); // Create and start our own MIDI input queue thread... m_pInputThread = new InputThread(this); m_pInputThread->start(QThread::TimeCriticalPriority); } #endif // CONFIG_ALSA_MIDI #ifdef CONFIG_RTMIDI const std::string clientName = sClientName.toStdString(); try { m_pMidiIn = new RtMidiIn(RtMidi::UNSPECIFIED, clientName); } catch (RtMidiError &err) { err.printMessage(); m_pMidiIn = nullptr; } try { m_pMidiOut = new RtMidiOut(RtMidi::UNSPECIFIED, clientName); } catch (RtMidiError &err) { err.printMessage(); m_pMidiOut = nullptr; } if (m_pMidiIn) { // Don't ignore sysex, but timing and active sensing messages... m_pMidiIn->ignoreTypes(false); m_pMidiIn->setCallback(qxgeditMidiDevice_midiIn_callback, this); } #endif // CONFIG_RTMIDI } qxgeditMidiDevice::Impl::~Impl (void) { // Reset pseudo-singleton reference. m_pMidiDevice = nullptr; #ifdef CONFIG_ALSA_MIDI // Last but not least, delete input thread... if (m_pInputThread) { // Try to terminate executive thread, // but give it a bit of time to cleanup... if (m_pInputThread->isRunning()) { m_pInputThread->setRunState(false); // m_pInputThread->terminate(); m_pInputThread->wait(); } delete m_pInputThread; m_pInputThread = nullptr; } if (m_pAlsaSeq) { snd_seq_delete_simple_port(m_pAlsaSeq, m_iAlsaInPort); m_iAlsaInPort = -1; snd_seq_delete_simple_port(m_pAlsaSeq, m_iAlsaOutPort); m_iAlsaOutPort = -1; snd_seq_close(m_pAlsaSeq); m_iAlsaClient = -1; m_pAlsaSeq = nullptr; } #endif // CONFIG_ALSA_MIDI #ifdef CONFIG_RTMIDI delete m_pMidiOut; delete m_pMidiIn; #endif // CONFIG_RTMIDI } #ifdef CONFIG_ALSA_MIDI // ALSA sequencer client descriptor accessor. snd_seq_t *qxgeditMidiDevice::Impl::alsaSeq (void) const { return m_pAlsaSeq; } // MIDI event capture method. void qxgeditMidiDevice::Impl::capture ( snd_seq_event_t *pEv ) { // Must be to ourselves... if (pEv->dest.port != m_iAlsaInPort) return; #ifdef CONFIG_DEBUG // - show event for debug purposes... ::fprintf(stderr, "MIDI In 0x%02x", pEv->type); if (pEv->type == SND_SEQ_EVENT_SYSEX) { ::fprintf(stderr, " sysex {"); unsigned char *data = (unsigned char *) pEv->data.ext.ptr; for (unsigned int i = 0; i < pEv->data.ext.len; ++i) ::fprintf(stderr, " %02x", data[i]); ::fprintf(stderr, " }\n"); } else { for (unsigned int i = 0; i < sizeof(pEv->data.raw8.d); ++i) ::fprintf(stderr, " %3d", pEv->data.raw8.d[i]); ::fprintf(stderr, "\n"); } #endif switch (pEv->type) { case SND_SEQ_EVENT_REGPARAM: // Post RPN event... m_pMidiDevice->emitReceiveRpn( pEv->data.control.channel, pEv->data.control.param, pEv->data.control.value); break; case SND_SEQ_EVENT_NONREGPARAM: // Post NRPN event... m_pMidiDevice->emitReceiveNrpn( pEv->data.control.channel, pEv->data.control.param, pEv->data.control.value); break; case SND_SEQ_EVENT_SYSEX: // Post SysEx event... m_pMidiDevice->emitReceiveSysex( QByteArray( (const char *) pEv->data.ext.ptr, (int) pEv->data.ext.len)); // Fall thru... default: break; } } #endif // CONFIG_ALSA_MIDI #ifdef CONFIG_RTMIDI // ALSA sequencer client descriptor accessor. RtMidiIn *qxgeditMidiDevice::Impl::midiIn (void) const { return m_pMidiIn; } RtMidiOut *qxgeditMidiDevice::Impl::midiOut (void) const { return m_pMidiOut; } // MIDI event capture method. void qxgeditMidiDevice::Impl::capture ( const QByteArray& midi ) { if (midi.size() < 3) return; const int status = (midi.at(0) & 0xf0); #ifdef CONFIG_DEBUG // - show event for debug purposes... ::fprintf(stderr, "MIDI In 0x%02x", status); if (status == 0xf0) { ::fprintf(stderr, " sysex {"); for (unsigned int i = 0; i < midi.size() - 1; ++i) ::fprintf(stderr, " %02x", midi.at(i)); ::fprintf(stderr, " }\n"); } else { ::fprintf(stderr, " %2d", midi.at(0) & 0x0f); for (unsigned int i = 1; i < midi.size(); ++i) ::fprintf(stderr, " %3d", midi.at(i) & 0x7f); ::fprintf(stderr, "\n"); } #endif // Post SysEx event... if (status == 0xf0) { m_pMidiDevice->emitReceiveSysex(midi); m_xrpn.flush(); } else { qxgeditMidiRpn::Event event; if (status == 0xb0) { event.time = 0; event.port = 0; event.status = qxgeditMidiRpn::CC | (midi.at(0) & 0x0f); event.param = midi.at(1) & 0x7f; event.value = midi.at(2) & 0x7f; m_xrpn.process(event); } else while (m_xrpn.dequeue(event)) { const unsigned char channel = (event.status & 0xf0); switch (qxgeditMidiRpn::Type(event.status & 0x70)) { case qxgeditMidiRpn::RPN: m_pMidiDevice->emitReceiveRpn(channel, event.param, event.value); break; case qxgeditMidiRpn::NRPN: m_pMidiDevice->emitReceiveNrpn(channel, event.param, event.value); break; case qxgeditMidiRpn::CC: case qxgeditMidiRpn::CC14: default: break; } } } } #endif // CONFIG_RTMIDI void qxgeditMidiDevice::Impl::sendSysex ( const QByteArray& sysex ) const { sendSysex((unsigned char *) sysex.data(), (unsigned short) sysex.length()); } void qxgeditMidiDevice::Impl::sendSysex ( unsigned char *pSysex, unsigned short iSysex ) const { #ifdef CONFIG_DEBUG fprintf(stderr, "qxgeditMidiDevice::sendSysex(%p, %u)", pSysex, iSysex); fprintf(stderr, " sysex {"); for (unsigned short i = 0; i < iSysex; ++i) fprintf(stderr, " %02x", pSysex[i]); fprintf(stderr, " }\n"); #endif #ifdef CONFIG_ALSA_MIDI // Don't do anything else if engine // has not been activated... if (m_pAlsaSeq == nullptr) return; // Initialize sequencer event... snd_seq_event_t ev; snd_seq_ev_clear(&ev); // Addressing... snd_seq_ev_set_source(&ev, m_iAlsaOutPort); snd_seq_ev_set_subs(&ev); // The event will be direct... snd_seq_ev_set_direct(&ev); // Just set SYSEX stuff and send it out.. ev.type = SND_SEQ_EVENT_SYSEX; snd_seq_ev_set_sysex(&ev, iSysex, pSysex); snd_seq_event_output_direct(m_pAlsaSeq, &ev); #endif // CONFIG_ALSA_MIDI #ifdef CONFIG_RTMIDI if (m_pMidiOut && m_pMidiOut->isPortOpen()) m_pMidiOut->sendMessage(pSysex, iSysex); #endif // CONFIG_RTMIDI } // MIDI Input(readable) / Output(writable) device list. static const char *c_pszItemSep = " / "; QStringList qxgeditMidiDevice::Impl::deviceList ( bool bReadable ) const { QStringList list; #ifdef CONFIG_ALSA_MIDI if (m_pAlsaSeq == nullptr) return list; unsigned int uiPortFlags; if (bReadable) uiPortFlags = SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; else uiPortFlags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; snd_seq_client_info_t *pClientInfo; snd_seq_port_info_t *pPortInfo; snd_seq_client_info_alloca(&pClientInfo); snd_seq_port_info_alloca(&pPortInfo); snd_seq_client_info_set_client(pClientInfo, -1); while (snd_seq_query_next_client(m_pAlsaSeq, pClientInfo) >= 0) { int iAlsaClient = snd_seq_client_info_get_client(pClientInfo); if (iAlsaClient > 0 && iAlsaClient != m_iAlsaClient) { snd_seq_port_info_set_client(pPortInfo, iAlsaClient); snd_seq_port_info_set_port(pPortInfo, -1); while (snd_seq_query_next_port(m_pAlsaSeq, pPortInfo) >= 0) { unsigned int uiPortCapability = snd_seq_port_info_get_capability(pPortInfo); if (((uiPortCapability & uiPortFlags) == uiPortFlags) && ((uiPortCapability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0)) { int iAlsaPort = snd_seq_port_info_get_port(pPortInfo); QString sItem = QString::number(iAlsaClient) + ':'; sItem += snd_seq_client_info_get_name(pClientInfo); sItem += c_pszItemSep; sItem += QString::number(iAlsaPort) + ':'; sItem += snd_seq_port_info_get_name(pPortInfo); list.append(sItem); } } } } #endif // CONFIG_ALSA_MIDI #ifdef CONFIG_RTMIDI if (bReadable) { const unsigned int nports = (m_pMidiIn ? m_pMidiIn->getPortCount() : 0); for (unsigned int i = 0; i < nports; ++i) { list.append(QString::fromStdString(m_pMidiIn->getPortName(i))); } } else { const unsigned int nports = (m_pMidiOut ? m_pMidiOut->getPortCount() : 0); for (unsigned int i = 0; i < nports; ++i) { list.append(QString::fromStdString(m_pMidiOut->getPortName(i))); } } #endif // CONFIG_RTMIDI return list; } // MIDI Input(readable) / Output(writable) device connects. bool qxgeditMidiDevice::Impl::connectDeviceList ( bool bReadable, const QStringList& list ) const { if (list.isEmpty()) return false; int iConnects = 0; #ifdef CONFIG_ALSA_MIDI if (m_pAlsaSeq == nullptr) return false; snd_seq_addr_t seq_addr; snd_seq_port_subscribe_t *pPortSubs; snd_seq_port_subscribe_alloca(&pPortSubs); snd_seq_client_info_t *pClientInfo; snd_seq_port_info_t *pPortInfo; snd_seq_client_info_alloca(&pClientInfo); snd_seq_port_info_alloca(&pPortInfo); unsigned int uiPortFlags; if (bReadable) uiPortFlags = SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; else uiPortFlags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; while (snd_seq_query_next_client(m_pAlsaSeq, pClientInfo) >= 0) { int iAlsaClient = snd_seq_client_info_get_client(pClientInfo); if (iAlsaClient > 0 && iAlsaClient != m_iAlsaClient) { QString sClientName = snd_seq_client_info_get_name(pClientInfo); snd_seq_port_info_set_client(pPortInfo, iAlsaClient); snd_seq_port_info_set_port(pPortInfo, -1); while (snd_seq_query_next_port(m_pAlsaSeq, pPortInfo) >= 0) { unsigned int uiPortCapability = snd_seq_port_info_get_capability(pPortInfo); if (((uiPortCapability & uiPortFlags) == uiPortFlags) && ((uiPortCapability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0)) { int iAlsaPort = snd_seq_port_info_get_port(pPortInfo); QString sPortName = snd_seq_port_info_get_name(pPortInfo); QStringListIterator iter(list); while (iter.hasNext()) { const QString& sItem = iter.next(); const QString& sClientItem = sItem.section(c_pszItemSep, 0, 0); const QString& sPortItem = sItem.section(c_pszItemSep, 1, 1); if (sClientName != sClientItem.section(':', 1, 1)) continue; if (sPortName != sPortItem.section(':', 1, 1)) continue; if (bReadable) { seq_addr.client = iAlsaClient; seq_addr.port = iAlsaPort; snd_seq_port_subscribe_set_sender(pPortSubs, &seq_addr); seq_addr.client = m_iAlsaClient; seq_addr.port = m_iAlsaInPort; snd_seq_port_subscribe_set_dest(pPortSubs, &seq_addr); } else { seq_addr.client = m_iAlsaClient; seq_addr.port = m_iAlsaOutPort; snd_seq_port_subscribe_set_sender(pPortSubs, &seq_addr); seq_addr.client = iAlsaClient; seq_addr.port = iAlsaPort; snd_seq_port_subscribe_set_dest(pPortSubs, &seq_addr); } if (snd_seq_subscribe_port(m_pAlsaSeq, pPortSubs) == 0) iConnects++; } } } } } #endif // CONFIG_ALSA_MIDI #ifdef CONFIG_RTMIDI const std::string portName = list.first().toStdString(); if (bReadable) { if (m_pMidiIn) m_pMidiIn->closePort(); const unsigned int nports = (m_pMidiIn ? m_pMidiIn->getPortCount() : 0); for (unsigned int i = 0; i < nports; ++i) { if (m_pMidiIn->getPortName(i) == portName) { m_pMidiIn->openPort(i, "in"); ++iConnects; break; } } } else { if (m_pMidiOut) m_pMidiOut->closePort(); const unsigned int nports = (m_pMidiOut ? m_pMidiOut->getPortCount() : 0); for (unsigned int i = 0; i < nports; ++i) { if (m_pMidiOut->getPortName(i) == portName) { m_pMidiOut->openPort(i, "out"); ++iConnects; break; } } } #endif // CONFIG_RTMIDI return (iConnects > 0); } //---------------------------------------------------------------------------- // qxgeditMidiDevice -- MIDI Device interface object. // Pseudo-singleton reference. qxgeditMidiDevice *qxgeditMidiDevice::g_pMidiDevice = nullptr; // Constructor. qxgeditMidiDevice::qxgeditMidiDevice ( const QString& sClientName ) : QObject(nullptr), m_pImpl(new Impl(this, sClientName)) { // Set pseudo-singleton reference. g_pMidiDevice = this; } qxgeditMidiDevice::~qxgeditMidiDevice (void) { // Reset pseudo-singleton reference. g_pMidiDevice = nullptr; delete m_pImpl; } // Pseudo-singleton reference (static). qxgeditMidiDevice *qxgeditMidiDevice::getInstance (void) { return g_pMidiDevice; } void qxgeditMidiDevice::sendSysex ( const QByteArray& sysex ) const { m_pImpl->sendSysex(sysex); } void qxgeditMidiDevice::sendSysex ( unsigned char *pSysex, unsigned short iSysex ) const { m_pImpl->sendSysex(pSysex, iSysex); } // MIDI Input(readable) / Output(writable) device list QStringList qxgeditMidiDevice::inputs (void) const { return m_pImpl->inputs(); } QStringList qxgeditMidiDevice::outputs (void) const { return m_pImpl->outputs(); } // MIDI Input(readable) / Output(writable) connects. bool qxgeditMidiDevice::connectInputs ( const QStringList& inputs ) const { return m_pImpl->connectInputs(inputs); } bool qxgeditMidiDevice::connectOutputs ( const QStringList& outputs ) const { return m_pImpl->connectOutputs(outputs); } // end of qxgeditMidiDevice.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditPaletteForm.cpp0000644000000000000000000000013214772452451017352 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPaletteForm.cpp0000644000175000001440000010072114772452451017343 0ustar00rncbcusers// qxgeditPaletteForm.cpp // /**************************************************************************** Copyright (C) 2005-2024, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditPaletteForm.h" #include "ui_qxgeditPaletteForm.h" #include #include #include #include #include #include #include #include #include #include #include // Local static consts. static const char *ColorThemesGroup = "/ColorThemes/"; static const char *PaletteEditorGroup = "/PaletteEditor/"; static const char *DefaultDirKey = "DefaultDir"; static const char *ShowDetailsKey = "ShowDetails"; static const char *DefaultSuffix = "conf"; static struct { const char *key; QPalette::ColorRole value; } g_colorRoles[] = { { "Window", QPalette::Window }, { "WindowText", QPalette::WindowText }, { "Button", QPalette::Button }, { "ButtonText", QPalette::ButtonText }, { "Light", QPalette::Light }, { "Midlight", QPalette::Midlight }, { "Dark", QPalette::Dark }, { "Mid", QPalette::Mid }, { "Text", QPalette::Text }, { "BrightText", QPalette::BrightText }, { "Base", QPalette::Base }, { "AlternateBase", QPalette::AlternateBase }, { "Shadow", QPalette::Shadow }, { "Highlight", QPalette::Highlight }, { "HighlightedText", QPalette::HighlightedText }, { "Link", QPalette::Link }, { "LinkVisited", QPalette::LinkVisited }, { "ToolTipBase", QPalette::ToolTipBase }, { "ToolTipText", QPalette::ToolTipText }, #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) { "PlaceholderText", QPalette::PlaceholderText }, #endif { "NoRole", QPalette::NoRole }, { nullptr, QPalette::NoRole } }; //------------------------------------------------------------------------- // qxgeditPaletteForm qxgeditPaletteForm::qxgeditPaletteForm ( QWidget *parent, const QPalette& pal ) : QDialog(parent), p_ui(new Ui::qxgeditPaletteForm), m_ui(*p_ui) { m_ui.setupUi(this); m_settings = nullptr; m_owner = false; m_modelUpdated = false; m_paletteUpdated = false; m_dirtyCount = 0; m_dirtyTotal = 0; updateGenerateButton(); m_paletteModel = new PaletteModel(this); m_ui.paletteView->setModel(m_paletteModel); ColorDelegate *delegate = new ColorDelegate(this); m_ui.paletteView->setItemDelegate(delegate); m_ui.paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers); // m_ui.paletteView->setAlternatingRowColors(true); m_ui.paletteView->setSelectionBehavior(QAbstractItemView::SelectRows); m_ui.paletteView->setDragEnabled(true); m_ui.paletteView->setDropIndicatorShown(true); m_ui.paletteView->setRootIsDecorated(false); m_ui.paletteView->setColumnHidden(2, true); m_ui.paletteView->setColumnHidden(3, true); QObject::connect(m_ui.nameCombo, SIGNAL(editTextChanged(const QString&)), SLOT(nameComboChanged(const QString&))); QObject::connect(m_ui.saveButton, SIGNAL(clicked()), SLOT(saveButtonClicked())); QObject::connect(m_ui.deleteButton, SIGNAL(clicked()), SLOT(deleteButtonClicked())); QObject::connect(m_ui.generateButton, SIGNAL(changed()), SLOT(generateButtonChanged())); QObject::connect(m_ui.resetButton, SIGNAL(clicked()), SLOT(resetButtonClicked())); QObject::connect(m_ui.detailsCheck, SIGNAL(clicked()), SLOT(detailsCheckClicked())); QObject::connect(m_ui.importButton, SIGNAL(clicked()), SLOT(importButtonClicked())); QObject::connect(m_ui.exportButton, SIGNAL(clicked()), SLOT(exportButtonClicked())); QObject::connect(m_paletteModel, SIGNAL(paletteChanged(const QPalette&)), SLOT(paletteChanged(const QPalette&))); QObject::connect(m_ui.dialogButtons, SIGNAL(accepted()), SLOT(accept())); QObject::connect(m_ui.dialogButtons, SIGNAL(rejected()), SLOT(reject())); setPalette(pal, pal); QDialog::adjustSize(); } qxgeditPaletteForm::~qxgeditPaletteForm (void) { setSettings(nullptr); } void qxgeditPaletteForm::setPalette ( const QPalette& pal ) { m_palette = pal; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const uint mask = pal.resolveMask(); #else const uint mask = pal.resolve(); #endif for (int i = 0; g_colorRoles[i].key; ++i) { if ((mask & (1 << i)) == 0) { const QPalette::ColorRole cr = g_colorRoles[i].value; m_palette.setBrush(QPalette::Active, cr, m_parentPalette.brush(QPalette::Active, cr)); m_palette.setBrush(QPalette::Inactive, cr, m_parentPalette.brush(QPalette::Inactive, cr)); m_palette.setBrush(QPalette::Disabled, cr, m_parentPalette.brush(QPalette::Disabled, cr)); } } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) m_palette.setResolveMask(mask); #else m_palette.resolve(mask); #endif updateGenerateButton(); m_paletteUpdated = true; if (!m_modelUpdated) m_paletteModel->setPalette(m_palette, m_parentPalette); m_paletteUpdated = false; } void qxgeditPaletteForm::setPalette ( const QPalette& pal, const QPalette& parentPal ) { m_parentPalette = parentPal; setPalette(pal); } const QPalette& qxgeditPaletteForm::palette (void) const { return m_palette; } void qxgeditPaletteForm::setSettings ( QSettings *settings, bool owner ) { if (m_settings && m_owner) delete m_settings; m_settings = settings; m_owner = owner; m_ui.detailsCheck->setChecked(isShowDetails()); updateNamedPaletteList(); updateDialogButtons(); } QSettings *qxgeditPaletteForm::settings (void) const { return m_settings; } void qxgeditPaletteForm::nameComboChanged ( const QString& name ) { if (m_dirtyCount > 0 && m_ui.nameCombo->findText(name) < 0) { updateDialogButtons(); } else { resetButtonClicked(); setPaletteName(name); ++m_dirtyTotal; } } void qxgeditPaletteForm::saveButtonClicked (void) { const QString& name = m_ui.nameCombo->currentText(); if (name.isEmpty()) return; QString filename = namedPaletteConf(name); if (filename.isEmpty() || !QFileInfo(filename).isWritable()) { const QString& title = tr("Save Palette - %1").arg(QDialog::windowTitle()); QStringList filters; filters.append(tr("Palette files (*.%1)").arg(DefaultSuffix)); filters.append(tr("All files (*.*)")); QString dirname = defaultDir(); if (!dirname.isEmpty()) dirname.append(QDir::separator()); dirname.append(paletteName() + '.' + DefaultSuffix); filename = QFileDialog::getSaveFileName(this, title, dirname, filters.join(";;")); } if (!filename.isEmpty() && saveNamedPaletteConf(name, filename, m_palette)) { addNamedPaletteConf(name, filename); setPalette(m_palette, m_palette); updateNamedPaletteList(); resetButtonClicked(); } } void qxgeditPaletteForm::deleteButtonClicked (void) { const QString& name = m_ui.nameCombo->currentText(); if (m_ui.nameCombo->findText(name) >= 0) { deleteNamedPaletteConf(name); updateNamedPaletteList(); updateDialogButtons(); } } void qxgeditPaletteForm::generateButtonChanged (void) { const QColor& color = m_ui.generateButton->brush().color(); const QPalette& pal = QPalette(color); setPalette(pal); ++m_dirtyCount; updateDialogButtons(); } void qxgeditPaletteForm::resetButtonClicked (void) { const bool blocked = blockSignals(true); for (int i = 0; g_colorRoles[i].key; ++i) { const QPalette::ColorRole cr = g_colorRoles[i].value; const QModelIndex& index = m_paletteModel->index(cr, 0); m_paletteModel->setData(index, false, Qt::EditRole); } m_dirtyCount = 0; updateDialogButtons(); blockSignals(blocked); } void qxgeditPaletteForm::detailsCheckClicked (void) { const int cw = (m_ui.paletteView->viewport()->width() >> 2); QHeaderView *header = m_ui.paletteView->header(); header->resizeSection(0, cw); if (m_ui.detailsCheck->isChecked()) { m_ui.paletteView->setColumnHidden(2, false); m_ui.paletteView->setColumnHidden(3, false); header->resizeSection(1, cw); header->resizeSection(2, cw); header->resizeSection(3, cw); m_paletteModel->setGenerate(false); } else { m_ui.paletteView->setColumnHidden(2, true); m_ui.paletteView->setColumnHidden(3, true); header->resizeSection(1, cw * 3); m_paletteModel->setGenerate(true); } } void qxgeditPaletteForm::importButtonClicked (void) { const QString& title = tr("Import File - %1").arg(QDialog::windowTitle()); QStringList filters; filters.append(tr("Palette files (*.%1)").arg(DefaultSuffix)); filters.append(tr("All files (*.*)")); const QString& filename = QFileDialog::getOpenFileName(this, title, defaultDir(), filters.join(";;")); if (filename.isEmpty()) return; QSettings conf(filename, QSettings::IniFormat); conf.beginGroup(ColorThemesGroup); const QStringList names = conf.childGroups(); conf.endGroup(); int imported = 0; QStringListIterator name_iter(names); while (name_iter.hasNext()) { const QString& name = name_iter.next(); if (!name.isEmpty()) { addNamedPaletteConf(name, filename); setPaletteName(name); ++imported; } } if (imported > 0) { updateNamedPaletteList(); resetButtonClicked(); setDefaultDir(QFileInfo(filename).absolutePath()); } else { QMessageBox::warning(this, tr("Warning - %1").arg(QDialog::windowTitle()), tr("Could not import from file:\n\n" "%1\n\nSorry.").arg(filename)); } } void qxgeditPaletteForm::exportButtonClicked (void) { const QString& title = tr("Export File - %1").arg(QDialog::windowTitle()); QStringList filters; filters.append(tr("Palette files (*.%1)").arg(DefaultSuffix)); filters.append(tr("All files (*.*)")); QString dirname = defaultDir(); if (!dirname.isEmpty()) dirname.append(QDir::separator()); dirname.append(paletteName() + '.' + DefaultSuffix); const QString& filename = QFileDialog::getSaveFileName(this, title, dirname, filters.join(";;")); if (filename.isEmpty()) return; const QFileInfo fi(filename); const QString& name = fi.baseName(); if (saveNamedPaletteConf(name, filename, m_palette)) { // addNamedPaletteConf(name, filename); setDefaultDir(fi.absolutePath()); } } void qxgeditPaletteForm::paletteChanged ( const QPalette& pal ) { m_modelUpdated = true; if (!m_paletteUpdated) setPalette(pal); m_modelUpdated = false; ++m_dirtyCount; updateDialogButtons(); } void qxgeditPaletteForm::setPaletteName ( const QString& name ) { const bool blocked = m_ui.nameCombo->blockSignals(true); m_ui.nameCombo->setEditText(name); QPalette pal; if (namedPalette(m_settings, name, pal, true)) setPalette(pal, pal); m_dirtyCount = 0; updateDialogButtons(); m_ui.nameCombo->blockSignals(blocked); } QString qxgeditPaletteForm::paletteName (void) const { return m_ui.nameCombo->currentText(); } void qxgeditPaletteForm::updateNamedPaletteList (void) { const bool blocked = m_ui.nameCombo->blockSignals(true); const QString old_name = m_ui.nameCombo->currentText(); m_ui.nameCombo->clear(); m_ui.nameCombo->insertItems(0, namedPaletteList()); // m_ui.nameCombo->model()->sort(0); const int i = m_ui.nameCombo->findText(old_name); if (i >= 0) m_ui.nameCombo->setCurrentIndex(i); else m_ui.nameCombo->setEditText(old_name); m_ui.nameCombo->blockSignals(blocked); } void qxgeditPaletteForm::updateGenerateButton (void) { m_ui.generateButton->setBrush( m_palette.brush(QPalette::Active, QPalette::Button)); } void qxgeditPaletteForm::updateDialogButtons (void) { const QString& name = m_ui.nameCombo->currentText(); const QString& filename = namedPaletteConf(name); const int i = m_ui.nameCombo->findText(name); m_ui.saveButton->setEnabled(!name.isEmpty() && (m_dirtyCount > 0 || i < 0)); m_ui.deleteButton->setEnabled(i >= 0); m_ui.resetButton->setEnabled(m_dirtyCount > 0); m_ui.exportButton->setEnabled(!name.isEmpty() || i >= 0); m_ui.dialogButtons->button(QDialogButtonBox::Ok)->setEnabled(i >= 0); } bool qxgeditPaletteForm::namedPalette ( const QString& name, QPalette& pal ) const { return namedPalette(m_settings, name, pal); } bool qxgeditPaletteForm::namedPalette ( QSettings *settings, const QString& name, QPalette& pal, bool fixup ) { int result = 0; if (!name.isEmpty() && loadNamedPalette(settings, name, pal)) { ++result; } else { const QString& filename = namedPaletteConf(settings, name); if (!filename.isEmpty() && QFileInfo(filename).isReadable() && loadNamedPaletteConf(name, filename, pal)) { ++result; } } // Dark themes grayed/disabled color group fix... if (!fixup && pal.base().color().value() < 0x7f) { const QColor& color = pal.window().color(); const int groups = int(QPalette::Active | QPalette::Inactive) + 1; for (int i = 0; i < groups; ++i) { const QPalette::ColorGroup cg = QPalette::ColorGroup(i); pal.setBrush(cg, QPalette::Light, color.lighter(140)); pal.setBrush(cg, QPalette::Midlight, color.lighter(100)); pal.setBrush(cg, QPalette::Mid, color.lighter(90)); pal.setBrush(cg, QPalette::Dark, color.darker(160)); pal.setBrush(cg, QPalette::Shadow, color.darker(180)); } pal.setColorGroup(QPalette::Disabled, pal.windowText().color().darker(), pal.button(), pal.light(), pal.dark(), pal.mid(), pal.text().color().darker(), pal.text().color().lighter(), pal.base(), pal.window()); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) pal.setColor(QPalette::Disabled, QPalette::Highlight, pal.mid().color()); pal.setColor(QPalette::Disabled, QPalette::ButtonText, pal.mid().color()); #endif ++result; } return (result > 0); } QStringList qxgeditPaletteForm::namedPaletteList (void) const { return namedPaletteList(m_settings); } QStringList qxgeditPaletteForm::namedPaletteList ( QSettings *settings ) { QStringList list; if (settings) { settings->beginGroup(ColorThemesGroup); list.append(settings->childKeys()); list.append(settings->childGroups()); // legacy... settings->endGroup(); } return list; } QString qxgeditPaletteForm::namedPaletteConf ( const QString& name ) const { return namedPaletteConf(m_settings, name); } QString qxgeditPaletteForm::namedPaletteConf ( QSettings *settings, const QString& name ) { QString ret; if (settings && !name.isEmpty()) { settings->beginGroup(ColorThemesGroup); ret = settings->value(name).toString(); settings->endGroup(); } return ret; } void qxgeditPaletteForm::addNamedPaletteConf ( const QString& name, const QString& filename ) { addNamedPaletteConf(m_settings, name, filename); ++m_dirtyTotal; } void qxgeditPaletteForm::addNamedPaletteConf ( QSettings *settings, const QString& name, const QString& filename ) { if (settings) { settings->beginGroup(ColorThemesGroup); settings->remove(name); // remove legacy keys! settings->setValue(name, filename); settings->endGroup(); } } void qxgeditPaletteForm::deleteNamedPaletteConf ( const QString& name ) { if (m_settings) { m_settings->beginGroup(ColorThemesGroup); m_settings->remove(name); m_settings->endGroup(); ++m_dirtyTotal; } } bool qxgeditPaletteForm::loadNamedPaletteConf ( const QString& name, const QString& filename, QPalette& pal ) { QSettings conf(filename, QSettings::IniFormat); return loadNamedPalette(&conf, name, pal); } bool qxgeditPaletteForm::saveNamedPaletteConf ( const QString& name, const QString& filename, const QPalette& pal ) { QSettings conf(filename, QSettings::IniFormat); return saveNamedPalette(&conf, name, pal); } bool qxgeditPaletteForm::loadNamedPalette ( QSettings *settings, const QString& name, QPalette& pal ) { if (settings == nullptr) return false; int result = 0; settings->beginGroup(ColorThemesGroup); QStringListIterator name_iter(settings->childGroups()); while (name_iter.hasNext() && !result) { const QString& name2 = name_iter.next(); if (name2 == name) { #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) uint mask = pal.resolve(); #endif settings->beginGroup(name + '/'); QStringListIterator iter(settings->childKeys()); while (iter.hasNext()) { const QString& key = iter.next(); const QPalette::ColorRole cr = qxgeditPaletteForm::colorRole(key); const QStringList& clist = settings->value(key).toStringList(); if (clist.count() == 3) { pal.setColor(QPalette::Active, cr, QColor(clist.at(0))); pal.setColor(QPalette::Inactive, cr, QColor(clist.at(1))); pal.setColor(QPalette::Disabled, cr, QColor(clist.at(2))); #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) mask &= ~(1 << int(cr)); #endif ++result; } } #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) pal.resolve(mask); #endif settings->endGroup(); } } settings->endGroup(); return (result > 0); } bool qxgeditPaletteForm::saveNamedPalette ( QSettings *settings, const QString& name, const QPalette& pal ) { if (settings == nullptr) return false; settings->beginGroup(ColorThemesGroup); settings->beginGroup(name + '/'); for (int i = 0; g_colorRoles[i].key; ++i) { const QString& key = QString::fromLatin1(g_colorRoles[i].key); const QPalette::ColorRole cr = g_colorRoles[i].value; QStringList clist; clist.append(pal.color(QPalette::Active, cr).name()); clist.append(pal.color(QPalette::Inactive, cr).name()); clist.append(pal.color(QPalette::Disabled, cr).name()); settings->setValue(key, clist); } settings->endGroup(); settings->endGroup(); return true; } QPalette::ColorRole qxgeditPaletteForm::colorRole ( const QString& name ) { static QHash s_colorRoles; if (s_colorRoles.isEmpty()) { for (int i = 0; g_colorRoles[i].key; ++i) { const QString& key = QString::fromLatin1(g_colorRoles[i].key); const QPalette::ColorRole value = g_colorRoles[i].value; s_colorRoles.insert(key, value); } } return s_colorRoles.value(name, QPalette::NoRole); } bool qxgeditPaletteForm::isDirty (void) const { return (m_dirtyTotal > 0); } void qxgeditPaletteForm::accept (void) { setShowDetails(m_ui.detailsCheck->isChecked()); if (m_dirtyCount > 0) saveButtonClicked(); QDialog::accept(); } void qxgeditPaletteForm::reject (void) { if (m_dirtyCount > 0) { const QString& name = paletteName(); if (name.isEmpty()) { if (QMessageBox::warning(this, tr("Warning - %1").arg(QDialog::windowTitle()), tr("Some settings have been changed.\n\n" "Do you want to discard the changes?"), QMessageBox::Discard | QMessageBox::Cancel) == QMessageBox::Cancel) return; } else { switch (QMessageBox::warning(this, tr("Warning - %1").arg(QDialog::windowTitle()), tr("Some settings have been changed:\n\n" "\"%1\".\n\nDo you want to save the changes?") .arg(name), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)) { case QMessageBox::Save: saveButtonClicked(); // Fall thru... case QMessageBox::Discard: break; default: // Cancel... return; } } } QDialog::reject(); } void qxgeditPaletteForm::setDefaultDir ( const QString& dir ) { if (m_settings) { m_settings->beginGroup(PaletteEditorGroup); m_settings->setValue(DefaultDirKey, dir); m_settings->endGroup(); } } QString qxgeditPaletteForm::defaultDir (void) const { QString dir; if (m_settings) { m_settings->beginGroup(PaletteEditorGroup); dir = m_settings->value(DefaultDirKey).toString(); m_settings->endGroup(); } return dir; } void qxgeditPaletteForm::setShowDetails ( bool on ) { if (m_settings) { m_settings->beginGroup(PaletteEditorGroup); m_settings->setValue(ShowDetailsKey, on); m_settings->endGroup(); } } bool qxgeditPaletteForm::isShowDetails (void) const { bool on = false; if (m_settings) { m_settings->beginGroup(PaletteEditorGroup); on = m_settings->value(ShowDetailsKey).toBool(); m_settings->endGroup(); } return on; } void qxgeditPaletteForm::showEvent ( QShowEvent *event ) { QDialog::showEvent(event); detailsCheckClicked(); } void qxgeditPaletteForm::resizeEvent ( QResizeEvent *event ) { QDialog::resizeEvent(event); detailsCheckClicked(); } //------------------------------------------------------------------------- // qxgeditPaletteForm::PaletteModel qxgeditPaletteForm::PaletteModel::PaletteModel ( QObject *parent ) : QAbstractTableModel(parent) { for (m_nrows = 0; g_colorRoles[m_nrows].key; ++m_nrows) { const QPalette::ColorRole value = g_colorRoles[m_nrows].value; const QString& key = QString::fromLatin1(g_colorRoles[m_nrows].key); m_roleNames.insert(value, key); } m_generate = true; } int qxgeditPaletteForm::PaletteModel::rowCount ( const QModelIndex& ) const { return m_nrows; } int qxgeditPaletteForm::PaletteModel::columnCount ( const QModelIndex& ) const { return 4; } QVariant qxgeditPaletteForm::PaletteModel::data ( const QModelIndex& index, int role ) const { if (!index.isValid()) return QVariant(); if (index.row() < 0 || index.row() >= m_nrows) return QVariant(); if (index.column() < 0 || index.column() >= 4) return QVariant(); if (index.column() == 0) { if (role == Qt::DisplayRole) return m_roleNames.value(QPalette::ColorRole(index.row())); if (role == Qt::EditRole) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const uint mask = m_palette.resolveMask(); #else const uint mask = m_palette.resolve(); #endif return bool(mask & (1 << index.row())); } } else if (role == Qt::BackgroundRole) { return m_palette.color( columnToGroup(index.column()), QPalette::ColorRole(index.row())); } return QVariant(); } bool qxgeditPaletteForm::PaletteModel::setData ( const QModelIndex& index, const QVariant& value, int role ) { if (!index.isValid()) return false; if (index.column() != 0 && role == Qt::BackgroundRole) { const QColor& color = value.value(); const QPalette::ColorRole cr = QPalette::ColorRole(index.row()); const QPalette::ColorGroup cg = columnToGroup(index.column()); m_palette.setBrush(cg, cr, color); QModelIndex index_begin = PaletteModel::index(cr, 0); QModelIndex index_end = PaletteModel::index(cr, 3); if (m_generate) { m_palette.setBrush(QPalette::Inactive, cr, color); switch (cr) { case QPalette::WindowText: case QPalette::Text: case QPalette::ButtonText: case QPalette::Base: break; case QPalette::Dark: m_palette.setBrush(QPalette::Disabled, QPalette::WindowText, color); m_palette.setBrush(QPalette::Disabled, QPalette::Dark, color); m_palette.setBrush(QPalette::Disabled, QPalette::Text, color); m_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, color); index_begin = PaletteModel::index(0, 0); index_end = PaletteModel::index(m_nrows - 1, 3); break; case QPalette::Window: m_palette.setBrush(QPalette::Disabled, QPalette::Base, color); m_palette.setBrush(QPalette::Disabled, QPalette::Window, color); index_begin = PaletteModel::index(QPalette::Base, 0); break; case QPalette::Highlight: m_palette.setBrush(QPalette::Disabled, QPalette::Highlight, color.darker(120)); break; default: m_palette.setBrush(QPalette::Disabled, cr, color); break; } } emit paletteChanged(m_palette); emit dataChanged(index_begin, index_end); return true; } if (index.column() == 0 && role == Qt::EditRole) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) uint mask = m_palette.resolveMask(); #else uint mask = m_palette.resolve(); #endif const bool masked = value.value(); const int i = index.row(); if (masked) { mask |= (1 << i); } else { const QPalette::ColorRole cr = QPalette::ColorRole(i); m_palette.setBrush(QPalette::Active, cr, m_parentPalette.brush(QPalette::Active, cr)); m_palette.setBrush(QPalette::Inactive, cr, m_parentPalette.brush(QPalette::Inactive, cr)); m_palette.setBrush(QPalette::Disabled, cr, m_parentPalette.brush(QPalette::Disabled, cr)); mask &= ~(1 << i); } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) m_palette.setResolveMask(mask); #else m_palette.resolve(mask); #endif emit paletteChanged(m_palette); const QModelIndex& index_end = PaletteModel::index(i, 3); emit dataChanged(index, index_end); return true; } return false; } Qt::ItemFlags qxgeditPaletteForm::PaletteModel::flags ( const QModelIndex& index ) const { if (!index.isValid()) return Qt::ItemIsEnabled; else return Qt::ItemIsEditable | Qt::ItemIsEnabled; } QVariant qxgeditPaletteForm::PaletteModel::headerData ( int section, Qt::Orientation orientation, int role ) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { if (section == 0) return tr("Color Role"); else if (section == groupToColumn(QPalette::Active)) return tr("Active"); else if (section == groupToColumn(QPalette::Inactive)) return tr("Inactive"); else if (section == groupToColumn(QPalette::Disabled)) return tr("Disabled"); } return QVariant(); } const QPalette& qxgeditPaletteForm::PaletteModel::palette(void) const { return m_palette; } void qxgeditPaletteForm::PaletteModel::setPalette ( const QPalette& palette, const QPalette& parentPalette ) { m_palette = palette; m_parentPalette = parentPalette; const QModelIndex& index_begin = index(0, 0); const QModelIndex& index_end = index(m_nrows - 1, 3); emit dataChanged(index_begin, index_end); } QPalette::ColorGroup qxgeditPaletteForm::PaletteModel::columnToGroup ( int index ) const { if (index == 1) return QPalette::Active; else if (index == 2) return QPalette::Inactive; return QPalette::Disabled; } int qxgeditPaletteForm::PaletteModel::groupToColumn ( QPalette::ColorGroup group ) const { if (group == QPalette::Active) return 1; else if (group == QPalette::Inactive) return 2; return 3; } //------------------------------------------------------------------------- // qxgeditPaletteForm::ColorDelegate QWidget *qxgeditPaletteForm::ColorDelegate::createEditor ( QWidget *parent, const QStyleOptionViewItem&, const QModelIndex& index ) const { QWidget *editor = nullptr; if (index.column() == 0) { RoleEditor *ed = new RoleEditor(parent); QObject::connect(ed, SIGNAL(changed(QWidget *)), SIGNAL(commitData(QWidget *))); // ed->setFocusPolicy(Qt::NoFocus); // ed->installEventFilter(const_cast(this)); editor = ed; } else { ColorEditor *ed = new ColorEditor(parent); QObject::connect(ed, SIGNAL(changed(QWidget *)), SIGNAL(commitData(QWidget *))); ed->setFocusPolicy(Qt::NoFocus); ed->installEventFilter(const_cast(this)); editor = ed; } return editor; } void qxgeditPaletteForm::ColorDelegate::setEditorData ( QWidget *editor, const QModelIndex& index ) const { if (index.column() == 0) { const bool masked = index.model()->data(index, Qt::EditRole).value(); RoleEditor *ed = static_cast(editor); ed->setEdited(masked); const QString& colorName = index.model()->data(index, Qt::DisplayRole).value(); ed->setLabel(colorName); } else { const QColor& color = index.model()->data(index, Qt::BackgroundRole).value(); ColorEditor *ed = static_cast(editor); ed->setColor(color); } } void qxgeditPaletteForm::ColorDelegate::setModelData ( QWidget *editor, QAbstractItemModel *model, const QModelIndex& index ) const { if (index.column() == 0) { RoleEditor *ed = static_cast(editor); const bool masked = ed->edited(); model->setData(index, masked, Qt::EditRole); } else { ColorEditor *ed = static_cast(editor); if (ed->changed()) { const QColor& color = ed->color(); model->setData(index, color, Qt::BackgroundRole); } } } void qxgeditPaletteForm::ColorDelegate::updateEditorGeometry ( QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QItemDelegate::updateEditorGeometry(editor, option, index); editor->setGeometry(editor->geometry().adjusted(0, 0, -1, -1)); } void qxgeditPaletteForm::ColorDelegate::paint ( QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QStyleOptionViewItem opt = option; const bool masked = index.model()->data(index, Qt::EditRole).value(); if (index.column() == 0 && masked) opt.font.setBold(true); QItemDelegate::paint(painter, opt, index); // painter->setPen(opt.palette.midlight().color()); painter->setPen(Qt::darkGray); painter->drawLine(opt.rect.right(), opt.rect.y(), opt.rect.right(), opt.rect.bottom()); painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); } QSize qxgeditPaletteForm::ColorDelegate::sizeHint ( const QStyleOptionViewItem& option, const QModelIndex &index) const { return QItemDelegate::sizeHint(option, index) + QSize(4, 4); } //------------------------------------------------------------------------- // qxgeditPaletteForm::ColorButton qxgeditPaletteForm::ColorButton::ColorButton ( QWidget *parent ) : QPushButton(parent), m_brush(Qt::darkGray) { QPushButton::setMinimumWidth(48); QObject::connect(this, SIGNAL(clicked()), SLOT(chooseColor())); } const QBrush& qxgeditPaletteForm::ColorButton::brush (void) const { return m_brush; } void qxgeditPaletteForm::ColorButton::setBrush ( const QBrush& brush ) { m_brush = brush; update(); } void qxgeditPaletteForm::ColorButton::paintEvent ( QPaintEvent *event ) { QPushButton::paintEvent(event); QStyleOptionButton opt; opt.initFrom(this); const QRect& rect = style()->subElementRect(QStyle::SE_PushButtonContents, &opt, this); QPainter paint(this); paint.setBrush(QBrush(m_brush.color())); paint.drawRect(rect.adjusted(+1, +1, -2, -2)); } void qxgeditPaletteForm::ColorButton::chooseColor (void) { const QColor color = QColorDialog::getColor(m_brush.color(), this); if (color.isValid()) { m_brush.setColor(color); emit changed(); } } //------------------------------------------------------------------------- // qxgeditPaletteForm::ColorEditor qxgeditPaletteForm::ColorEditor::ColorEditor ( QWidget *parent ) : QWidget(parent) { QLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); m_button = new qxgeditPaletteForm::ColorButton(this); layout->addWidget(m_button); QObject::connect(m_button, SIGNAL(changed()), SLOT(colorChanged())); setFocusProxy(m_button); m_changed = false; } void qxgeditPaletteForm::ColorEditor::setColor ( const QColor& color ) { m_button->setBrush(color); m_changed = false; } QColor qxgeditPaletteForm::ColorEditor::color (void) const { return m_button->brush().color(); } void qxgeditPaletteForm::ColorEditor::colorChanged (void) { m_changed = true; emit changed(this); } bool qxgeditPaletteForm::ColorEditor::changed (void) const { return m_changed; } //------------------------------------------------------------------------- // qxgeditPaletteForm::RoleEditor qxgeditPaletteForm::RoleEditor::RoleEditor ( QWidget *parent ) : QWidget(parent) { m_edited = false; QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); m_label = new QLabel(this); layout->addWidget(m_label); m_label->setAutoFillBackground(true); m_label->setIndent(3); // HACK: it should have the same value of textMargin in QItemDelegate setFocusProxy(m_label); m_button = new QToolButton(this); m_button->setToolButtonStyle(Qt::ToolButtonIconOnly); m_button->setIcon(QPixmap(":/images/itemReset.png")); m_button->setIconSize(QSize(8, 8)); m_button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding)); layout->addWidget(m_button); QObject::connect(m_button, SIGNAL(clicked()), SLOT(resetProperty())); } void qxgeditPaletteForm::RoleEditor::setLabel ( const QString& label ) { m_label->setText(label); } void qxgeditPaletteForm::RoleEditor::setEdited ( bool on ) { QFont font; if (on) font.setBold(on); m_label->setFont(font); m_button->setEnabled(on); m_edited = on; } bool qxgeditPaletteForm::RoleEditor::edited (void) const { return m_edited; } void qxgeditPaletteForm::RoleEditor::resetProperty (void) { setEdited(false); emit changed(this); } // end of qxgeditPaletteForm.cpp qxgedit-1.0.1/src/PaxHeaders/qxgedit.cpp0000644000000000000000000000013214772452451015207 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgedit.cpp0000644000175000001440000003716314772452451015211 0ustar00rncbcusers// qxgedit.cpp // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgedit.h" #include "qxgeditOptions.h" #include "qxgeditMainForm.h" #include "qxgeditPaletteForm.h" #include #include #include #include #include #ifndef CONFIG_PREFIX #define CONFIG_PREFIX "/usr/local" #endif #ifndef CONFIG_BINDIR #define CONFIG_BINDIR CONFIG_PREFIX "/bin" #endif #ifndef CONFIG_DATADIR #define CONFIG_DATADIR CONFIG_PREFIX "/share" #endif #ifndef CONFIG_LIBDIR #if defined(__x86_64__) #define CONFIG_LIBDIR CONFIG_PREFIX "/lib64" #else #define CONFIG_LIBDIR CONFIG_PREFIX "/lib" #endif #endif #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt4/plugins" #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt5/plugins" #else #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt6/plugins" #endif //------------------------------------------------------------------------- // Singleton application instance stuff (Qt/X11 only atm.) // #ifdef CONFIG_XUNIQUE #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_X11 #define QXGEDIT_XUNIQUE "qxgeditApplication" #include /* for gethostname() */ #include #include #endif // CONFIG_X11 #else #include #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) #include #endif #include #include #include #endif #endif // CONFIG_XUNIQUE // Constructor. qxgeditApplication::qxgeditApplication ( int& argc, char **argv ) : QApplication(argc, argv), m_pQtTranslator(nullptr), m_pMyTranslator(nullptr), m_pWidget(nullptr) #ifdef CONFIG_XUNIQUE #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_X11 , m_pDisplay(nullptr) , m_aUnique(0) , m_wOwner(0) #endif // CONFIG_X11 #else , m_pMemory(nullptr) , m_pServer(nullptr) #endif #endif // CONFIG_XUNIQUE { #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) QApplication::setApplicationName(QXGEDIT_TITLE); QApplication::setApplicationDisplayName(QXGEDIT_TITLE); // QXGEDIT_TITLE " - " + QObject::tr(QXGEDIT_SUBTITLE)); #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) QApplication::setDesktopFileName( QString("org.rncbc.%1").arg(PROJECT_NAME)); #endif QApplication::setApplicationVersion(PROJECT_VERSION); #endif // Load translation support. QLocale loc; if (loc.language() != QLocale::C) { // Try own Qt translation... m_pQtTranslator = new QTranslator(this); QString sLocName = "qt_" + loc.name(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QString sLocPath = QLibraryInfo::path(QLibraryInfo::TranslationsPath); #else QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath); #endif if (m_pQtTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pQtTranslator); } else { delete m_pQtTranslator; m_pQtTranslator = nullptr; #ifdef CONFIG_DEBUG qWarning("Warning: no translation found for '%s' locale: %s/%s.qm", loc.name().toUtf8().constData(), sLocPath.toUtf8().constData(), sLocName.toUtf8().constData()); #endif } // Try own application translation... m_pMyTranslator = new QTranslator(this); sLocName = "qxgedit_" + loc.name(); if (m_pMyTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pMyTranslator); } else { sLocPath = QApplication::applicationDirPath(); sLocPath.remove(CONFIG_BINDIR); sLocPath.append(CONFIG_DATADIR "/qxgedit/translations"); if (m_pMyTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pMyTranslator); } else { delete m_pMyTranslator; m_pMyTranslator = nullptr; #ifdef CONFIG_DEBUG qWarning("Warning: no translation found for '%s' locale: %s/%s.qm", loc.name().toUtf8().constData(), sLocPath.toUtf8().constData(), sLocName.toUtf8().constData()); #endif } } } } // Destructor. qxgeditApplication::~qxgeditApplication (void) { #ifdef CONFIG_XUNIQUE #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) clearServer(); #endif #endif // CONFIG_XUNIQUE if (m_pMyTranslator) delete m_pMyTranslator; if (m_pQtTranslator) delete m_pQtTranslator; } // Main application widget accessors. void qxgeditApplication::setMainWidget ( QWidget *pWidget ) { m_pWidget = pWidget; #ifdef CONFIG_XUNIQUE #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_X11 m_wOwner = m_pWidget->winId(); if (m_pDisplay && m_wOwner) { XGrabServer(m_pDisplay); XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime); XUngrabServer(m_pDisplay); } #endif // CONFIG_X11 #endif #endif // CONFIG_XUNIQUE } // Check if another instance is running, // and raise its proper main widget... bool qxgeditApplication::setup (void) { #ifdef CONFIG_XUNIQUE #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_X11 m_pDisplay = QX11Info::display(); if (m_pDisplay) { QString sUnique = QXGEDIT_XUNIQUE; QString sUserName = QString::fromUtf8(::getenv("USER")); if (sUserName.isEmpty()) sUserName = QString::fromUtf8(::getenv("USERNAME")); if (!sUserName.isEmpty()) { sUnique += ':'; sUnique += sUserName; } char szHostName[255]; if (::gethostname(szHostName, sizeof(szHostName)) == 0) { sUnique += '@'; sUnique += QString::fromUtf8(szHostName); } m_aUnique = XInternAtom(m_pDisplay, sUnique.toUtf8().constData(), false); XGrabServer(m_pDisplay); m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique); XUngrabServer(m_pDisplay); if (m_wOwner != None) { // First, notify any freedesktop.org WM // that we're about to show the main widget... Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay); int iScreen = XScreenNumberOfScreen(pScreen); XEvent ev; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.display = m_pDisplay; ev.xclient.window = m_wOwner; ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false); ev.xclient.format = 32; ev.xclient.data.l[0] = 0; // Source indication. ev.xclient.data.l[1] = 0; // Timestamp. ev.xclient.data.l[2] = 0; // Requestor's currently active window (none) ev.xclient.data.l[3] = 0; ev.xclient.data.l[4] = 0; XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask); XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false, (SubstructureNotifyMask | SubstructureRedirectMask), &ev); XSync(m_pDisplay, false); XRaiseWindow(m_pDisplay, m_wOwner); // And then, let it get caught on destination // by QApplication::native/x11EventFilter... const QByteArray value = QSAMPLER_XUNIQUE; XChangeProperty( m_pDisplay, m_wOwner, m_aUnique, m_aUnique, 8, PropModeReplace, (unsigned char *) value.data(), value.length()); // Done. return true; } } #endif // CONFIG_X11 return false; #else return setupServer(); #endif #else return false; #endif // !CONFIG_XUNIQUE } #ifdef CONFIG_XUNIQUE #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_X11 void qxgeditApplication::x11PropertyNotify ( Window w ) { if (m_pDisplay && m_pWidget && m_wOwner == w) { // Always check whether our property-flag is still around... Atom aType; int iFormat = 0; unsigned long iItems = 0; unsigned long iAfter = 0; unsigned char *pData = 0; if (XGetWindowProperty( m_pDisplay, m_wOwner, m_aUnique, 0, 1024, false, m_aUnique, &aType, &iFormat, &iItems, &iAfter, &pData) == Success && aType == m_aUnique && iItems > 0 && iAfter == 0) { // Avoid repeating it-self... XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique); // Just make it always shows up fine... m_pWidget->showNormal(); m_pWidget->raise(); m_pWidget->activateWindow(); // FIXME: Do our best speciality, although it should be // done iif configuration says so, we'll do it anyway! qxgeditMainForm *pMainForm = qxgeditMainForm::getInstance(); if (pMainForm) pMainForm->startAllEngines(); } // Free any left-overs... if (iItems > 0 && pData) XFree(pData); } } bool qxgeditApplication::x11EventFilter ( XEvent *pEv ) { if (pEv->type == PropertyNotify && pEv->xproperty.state == PropertyNewValue) x11PropertyNotify(pEv->xproperty.window); return QApplication::x11EventFilter(pEv); } #endif // CONFIG_X11 #else // Local server/shmem setup. bool qxgeditApplication::setupServer (void) { clearServer(); m_sUnique = QCoreApplication::applicationName(); QString sUserName = QString::fromUtf8(::getenv("USER")); if (sUserName.isEmpty()) sUserName = QString::fromUtf8(::getenv("USERNAME")); if (!sUserName.isEmpty()) { m_sUnique += ':'; m_sUnique += sUserName; } m_sUnique += '@'; m_sUnique += QHostInfo::localHostName(); #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) const QNativeIpcKey nativeKey = QSharedMemory::legacyNativeKey(m_sUnique); #if defined(Q_OS_UNIX) m_pMemory = new QSharedMemory(nativeKey); m_pMemory->attach(); delete m_pMemory; #endif m_pMemory = new QSharedMemory(nativeKey); #else #if defined(Q_OS_UNIX) m_pMemory = new QSharedMemory(m_sUnique); m_pMemory->attach(); delete m_pMemory; #endif m_pMemory = new QSharedMemory(m_sUnique); #endif bool bServer = false; const qint64 pid = QCoreApplication::applicationPid(); struct Data { qint64 pid; }; if (m_pMemory->create(sizeof(Data))) { m_pMemory->lock(); Data *pData = static_cast (m_pMemory->data()); if (pData) { pData->pid = pid; bServer = true; } m_pMemory->unlock(); } else if (m_pMemory->attach()) { m_pMemory->lock(); // maybe not necessary? Data *pData = static_cast (m_pMemory->data()); if (pData) bServer = (pData->pid == pid); m_pMemory->unlock(); } if (bServer) { QLocalServer::removeServer(m_sUnique); m_pServer = new QLocalServer(); m_pServer->setSocketOptions(QLocalServer::UserAccessOption); m_pServer->listen(m_sUnique); QObject::connect(m_pServer, SIGNAL(newConnection()), SLOT(newConnectionSlot())); } else { QLocalSocket socket; socket.connectToServer(m_sUnique); if (socket.state() == QLocalSocket::ConnectingState) socket.waitForConnected(200); if (socket.state() == QLocalSocket::ConnectedState) { socket.write(QCoreApplication::arguments().join(' ').toUtf8()); socket.flush(); socket.waitForBytesWritten(200); } } return !bServer; } // Local server/shmem cleanup. void qxgeditApplication::clearServer (void) { if (m_pServer) { m_pServer->close(); delete m_pServer; m_pServer = nullptr; } if (m_pMemory) { delete m_pMemory; m_pMemory = nullptr; } m_sUnique.clear(); } // Local server conection slot. void qxgeditApplication::newConnectionSlot (void) { QLocalSocket *pSocket = m_pServer->nextPendingConnection(); QObject::connect(pSocket, SIGNAL(readyRead()), SLOT(readyReadSlot())); } // Local server data-ready slot. void qxgeditApplication::readyReadSlot (void) { QLocalSocket *pSocket = qobject_cast (sender()); if (pSocket) { const qint64 nread = pSocket->bytesAvailable(); if (nread > 0) { const QByteArray data = pSocket->read(nread); // Just make it always shows up fine... if (m_pWidget) { m_pWidget->showNormal(); m_pWidget->raise(); m_pWidget->activateWindow(); } // Reset the server... setupServer(); } } } #endif #endif // CONFIG_XUNIQUE //------------------------------------------------------------------------- // stacktrace - Signal crash handler. // #ifdef CONFIG_STACKTRACE #if defined(__GNUC__) && defined(Q_OS_LINUX) #include #include #include #include #include void stacktrace ( int signo ) { pid_t pid; int rc; int status = 0; char cmd[80]; // Reinstall default handler; prevent race conditions... ::signal(signo, SIG_DFL); static const char *shell = "/bin/sh"; static const char *format = "gdb -q --batch --pid=%d" " --eval-command='thread apply all bt'"; snprintf(cmd, sizeof(cmd), format, (int) getpid()); pid = fork(); // Fork failure! if (pid < 0) return; // Fork child... if (pid == 0) { execl(shell, shell, "-c", cmd, nullptr); _exit(1); return; } // Parent here: wait for child to terminate... do { rc = waitpid(pid, &status, 0); } while ((rc < 0) && (errno == EINTR)); // Dispatch any logging, if any... QApplication::processEvents(QEventLoop::AllEvents, 3000); // Make sure everyone terminates... kill(pid, SIGTERM); _exit(1); } #endif #endif //------------------------------------------------------------------------- // main - The main program trunk. // int main ( int argc, char **argv ) { Q_INIT_RESOURCE(qxgedit); #ifdef CONFIG_STACKTRACE #if defined(__GNUC__) && defined(Q_OS_LINUX) ::signal(SIGILL, stacktrace); ::signal(SIGFPE, stacktrace); ::signal(SIGSEGV, stacktrace); ::signal(SIGABRT, stacktrace); ::signal(SIGBUS, stacktrace); #endif #endif #if defined(Q_OS_LINUX) && !defined(CONFIG_WAYLAND) ::setenv("QT_QPA_PLATFORM", "xcb", 0); #endif #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif #endif qxgeditApplication app(argc, argv); // Construct default settings; override with command line arguments. qxgeditOptions options; if (!options.parse_args(app.arguments())) { app.quit(); return 1; } // Have another instance running? if (app.setup()) { app.quit(); return 2; } // Set default base font... if (options.iBaseFontSize > 0) app.setFont(QFont(app.font().family(), options.iBaseFontSize)); // Special styles... QString sPluginsPath = QApplication::applicationDirPath(); sPluginsPath.remove(CONFIG_BINDIR); sPluginsPath.append(CONFIG_PLUGINSDIR); if (QDir(sPluginsPath).exists()) app.addLibraryPath(sPluginsPath); if (!options.sStyleTheme.isEmpty()) app.setStyle(QStyleFactory::create(options.sStyleTheme)); // Custom color theme (eg. "KXStudio")... const QChar sep = QDir::separator(); QString sPalettePath = QApplication::applicationDirPath(); sPalettePath.remove(CONFIG_BINDIR); sPalettePath.append(CONFIG_DATADIR); sPalettePath.append(sep); sPalettePath.append(PROJECT_NAME); sPalettePath.append(sep); sPalettePath.append("palette"); if (QDir(sPalettePath).exists()) { QStringList names; names.append("KXStudio"); names.append("Wonton Soup"); QStringListIterator name_iter(names); while (name_iter.hasNext()) { const QString& name = name_iter.next(); const QFileInfo fi(sPalettePath, name + ".conf"); if (fi.isReadable()) { qxgeditPaletteForm::addNamedPaletteConf( &options.settings(), name, fi.absoluteFilePath()); } } } QPalette pal(app.palette()); if (qxgeditPaletteForm::namedPalette( &options.settings(), options.sColorTheme, pal)) app.setPalette(pal); // Construct, setup and show the main form (a pseudo-singleton). qxgeditMainForm w; w.setup(&options); w.show(); // Settle this one as application main widget... app.setMainWidget(&w); return app.exec(); } // end of qxgedit.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditCheck.cpp0000644000000000000000000000013214772452451016145 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditCheck.cpp0000644000175000001440000000570614772452451016145 0ustar00rncbcusers// qxgeditCheck.cpp // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditCheck.h" //------------------------------------------------------------------------- // qxgeditCheck - Custom check-box widget. // // Constructor. qxgeditCheck::qxgeditCheck ( QWidget *pParent ) : XGParamWidget (pParent), m_pParam(nullptr) { QObject::connect(this, SIGNAL(toggled(bool)), SLOT(checkToggled(bool))); } // Destructor. qxgeditCheck::~qxgeditCheck (void) { } // Nominal value accessors. void qxgeditCheck::set_value ( unsigned short iValue, Observer *pSender ) { if (m_pParam == nullptr) return; if (iValue < m_pParam->min()) iValue = m_pParam->min(); if (iValue > m_pParam->max() && m_pParam->max() > m_pParam->min()) iValue = m_pParam->max(); bool bValueChanged = (iValue != m_pParam->value()); m_pParam->set_value(iValue, pSender); QCheckBox::setChecked(iValue > 0); QPalette pal; if (QCheckBox::isEnabled() && iValue != m_pParam->def()) { const QColor& rgbBase = (pal.window().color().value() < 0x7f ? QColor(Qt::darkYellow).darker() : QColor(Qt::yellow).lighter()); pal.setColor(QPalette::Base, rgbBase); // pal.setColor(QPalette::Text, Qt::black); } QCheckBox::setPalette(pal); if (bValueChanged) emit valueChanged(iValue); } unsigned short qxgeditCheck::value (void) const { return (m_pParam ? m_pParam->value() : 0); } // Specialty parameter accessors. void qxgeditCheck::set_param ( XGParam *pParam, Observer */*pSender*/ ) { m_pParam = pParam; QCheckBox::setPalette(QPalette()); if (m_pParam) { QCheckBox::setText(m_pParam->label()); QCheckBox::setChecked(m_pParam->value() > 0); QCheckBox::setToolTip(m_pParam->text()); } } XGParam *qxgeditCheck::param (void) const { return m_pParam; } // Value settler public slot. void qxgeditCheck::setValue ( unsigned short iValue ) { set_value(iValue, observer()); } // Internal widget slots. void qxgeditCheck::checkToggled ( bool bCheck ) { set_value((bCheck ? 127 : 0), observer()); emit valueChanged(value()); } // end of qxgeditCheck.cpp qxgedit-1.0.1/src/PaxHeaders/XGParamWidget.h0000644000000000000000000000013214772452451015652 xustar0030 mtime=1743410473.474607941 30 atime=1743410473.474607941 30 ctime=1743410473.474607941 qxgedit-1.0.1/src/XGParamWidget.h0000644000175000001440000001427414772452451015652 0ustar00rncbcusers// XGParamWidget.h // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __XGParamWidget_h #define __XGParamWidget_h #include "XGParam.h" // Forward decl. class QWidget; #ifdef XGPARAM_WIDGET_MAP //------------------------------------------------------------------------- // class XGParamInst - XGParam/Widget hash key instance. // class XGParamInst { public: // Constructor. XGParamInst(XGParamMap *map = nullptr, unsigned short id = 0) : m_map(map), m_id(id) {} XGParamInst(const XGParamInst& inst) : m_map(inst.m_map), m_id(inst.m_id) {} // Accessors. XGParamMap *map() const { return m_map; } unsigned short id() const { return m_id; } // Hash key comparator. bool operator== ( const XGParamInst& inst ) const { return (inst.map() == m_map) && (inst.id() == m_id); } // XG parameter indirection. XGParam *param() const { return m_map->find_param(m_id); } private: // Member variables. XGParamMap *m_map; unsigned short m_id; }; // XGParam/QWidget hash key function. inline uint qHash ( const XGParamInst& inst ) { return qHash(inst.map()) ^ qHash(inst.id()); } //------------------------------------------------------------------------- // class XGParamWidgetMap - XGParam/Widget cross-map. // class XGParamWidgetMap { public: // Constructor. XGParamWidgetMap(); // Destructor. ~XGParamWidgetMap(); // Pseudo-singleton accessor. static XGParamWidgetMap *getInstance(); // Add widget to map. void add_widget(QWidget *widget, XGParamMap *map, unsigned short id); void add_widget(QWidget *widget, XGParam *param); void add_widget(QWidget *widget, const XGParamKey& key); // State parameter lookup. XGParam *find_param(QWidget *widget) const; // Widget lookup. QWidget *find_widget(XGParamMap *map, unsigned id) const; QWidget *find_widget(XGParam *param) const; QWidget *find_widget(const XGParamKey& key) const; private: // Instance parameters. QHash m_widget_map; QHash m_params_map; // Pseudo-singleton accessor. static XGParamWidgetMap *g_pParamWidgetMap; }; #endif // XGPARAM_WIDGET_MAP //---------------------------------------------------------------------- // class XGParamWidget -- Template widget observer/visitor. // template class XGParamWidget : public W { public: // Local observer. class Observer : public XGParamObserver { public: // Constructor. Observer(XGParam *param, XGParamWidget *widget) : XGParamObserver(param), m_widget(widget) {} protected: // Observer resetter. void reset() { if (m_widget->param() != param()) m_widget->set_param(param(), this); } // Observer updater. void update() { if (m_widget->param() == param()) m_widget->set_value(value(), this); } private: // Members. XGParamWidget *m_widget; }; // Constructor. XGParamWidget(QWidget *parent = nullptr) : W(parent), m_param_map(nullptr), m_param_id(0) {} // Virtual destructor. virtual ~XGParamWidget() { clear_observers(); } // Pure virtual methods. virtual void set_param(XGParam *param, Observer *sender) = 0; virtual XGParam *param() const = 0; virtual void set_value(unsigned short u, Observer *sender) = 0; virtual unsigned short value() const = 0; // Setup. void set_param_map(XGParamMap *map, unsigned short id) { clear_observers(); m_param_map = map; m_param_id = id; XGParamSet *paramset = add_paramset(m_param_id); if (paramset == nullptr) return; #ifdef XGPARAM_WIDGET_MAP XGParamWidgetMap *pParamWidgetMap = XGParamWidgetMap::getInstance(); if (pParamWidgetMap) pParamWidgetMap->add_widget(this, m_param_map, m_param_id); #endif unsigned short key = m_param_map->current_key(); if (paramset->contains(key)) { XGParam *param = paramset->value(key); if (param) param->notify_reset(); } else if (m_param_map->key_param()) { XGParam *param = m_param_map->key_param(); m_observers.insert(0, new Observer(param, this)); param->notify_reset(); } for (unsigned short i = 1; i < m_param_map->elements(); ++i) { if (m_param_id >= 0x3d) add_paramset(m_param_id + (i * 0x50)); } } XGParamMap *param_map() const { return m_param_map; } unsigned short param_id() const { return m_param_id; } // Observer accessor. Observer *observer() const { if (m_param_map == nullptr) return nullptr; unsigned short key = m_param_map->current_key(); if (!m_observers.contains(key)) return nullptr; return static_cast (m_observers.value(key)); } protected: // Paramset observers. XGParamSet *add_paramset(unsigned short id) { if (m_param_map == nullptr) return nullptr; XGParamSet *paramset = m_param_map->find_paramset(id); if (paramset == nullptr) return nullptr; XGParamSet::const_iterator iter = paramset->constBegin(); for (; iter != paramset->constEnd(); ++iter) m_observers.insert(iter.key(), new Observer(iter.value(), this)); return paramset; } // Observers cleaner. void clear_observers() { QHash::const_iterator iter = m_observers.constBegin(); for (; iter != m_observers.constEnd(); ++iter) delete iter.value(); m_observers.clear(); } private: // Members. XGParamMap *m_param_map; unsigned short m_param_id; QHash m_observers; }; #endif // __XGParamWidget_h // end of XGParamWidget.h qxgedit-1.0.1/src/PaxHeaders/qxgeditMidiRpn.cpp0000644000000000000000000000013214772452451016472 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.475607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditMidiRpn.cpp0000644000175000001440000003730714772452451016474 0ustar00rncbcusers// qxgeditMidiRpn.cpp // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditMidiRpn.h" #include #define RPN_MSB 0x65 #define RPN_LSB 0x64 #define NRPN_MSB 0x63 #define NRPN_LSB 0x62 #define DATA_MSB 0x06 #define DATA_LSB 0x26 #define CC14_MSB_MIN 0x00 #define CC14_MSB_MAX 0x20 #define CC14_LSB_MIN CC14_MSB_MAX #define CC14_LSB_MAX (CC14_MSB_MAX << 1) //--------------------------------------------------------------------- // xrpn_data14 - decl. // class xrpn_data14 { public: xrpn_data14() : m_msb(0), m_lsb(0) {} xrpn_data14 ( const xrpn_data14& data ) : m_msb(data.m_msb), m_lsb(data.m_lsb) {} void clear() { m_msb = m_lsb = 0; } bool is_msb () const { return (m_msb & 0x80); } void set_msb ( unsigned char msb ) { m_msb = (msb & 0x7f) | 0x80; } unsigned msb() const { return (m_msb & 0x7f); } bool is_lsb () const { return (m_lsb & 0x80); } void set_lsb ( unsigned char lsb ) { m_lsb = (lsb & 0x7f) | 0x80; } unsigned lsb() const { return (m_lsb & 0x7f); } unsigned short data() const { unsigned short val = 0; if (is_lsb()) { val += (m_lsb & 0x7f); if (is_msb()) val += (m_msb & 0x7f) << 7; } else if (is_msb()) val += (m_msb & 0x7f); return val; } bool is_any() const { return is_msb() || is_lsb(); } bool is_7bit() const { return is_any() && !is_14bit(); } bool is_14bit() const { return is_msb() && is_lsb(); } private: unsigned char m_msb; unsigned char m_lsb; }; //--------------------------------------------------------------------- // xrpn_item - decl. // class xrpn_item { public: xrpn_item() : m_time(0), m_port(0), m_status(0) {} xrpn_item ( const xrpn_item& item ) : m_time(item.m_time), m_port(item.m_port), m_status(item.m_status), m_param(item.m_param), m_value(item.m_value) {} void clear() { m_time = 0; m_port = 0; m_status = 0; m_param.clear(); m_value.clear(); } void set_time(unsigned long time) { m_time = time; } unsigned long time() const { return m_time; } void set_port(int port) { m_port = port; } int port() const { return m_port; } bool is_status () const { return (m_status & 0x80) && (m_status & 0x70); } void set_status(unsigned char status) { m_status = (status & 0x7f) | 0x80; } unsigned char status() const { return (m_status & 0x7f); } qxgeditMidiRpn::Type type() const { return qxgeditMidiRpn::Type(status() & 0x70); } unsigned short channel() const { return (status() & 0x0f); } bool is_param_msb() const { return m_param.is_msb(); } bool is_param_lsb() const { return m_param.is_lsb(); } void set_param_msb(unsigned char msb) { m_param.set_msb(msb); } void set_param_lsb(unsigned char lsb) { m_param.set_lsb(lsb); } unsigned char param_msb() const { return m_param.msb(); } unsigned char param_lsb() const { return m_param.lsb(); } unsigned short param() const { return m_param.data(); } bool is_value_msb() const { return m_value.is_msb(); } bool is_value_lsb() const { return m_value.is_lsb(); } void set_value_msb(unsigned char msb) { m_value.set_msb(msb); } void set_value_lsb(unsigned char lsb) { m_value.set_lsb(lsb); } unsigned char value_msb() const { return m_value.msb(); } unsigned char value_lsb() const { return m_value.lsb(); } unsigned short value() const { return m_value.data(); } bool is_any() const { return m_param.is_any() || m_value.is_any(); } bool is_ready() const { return m_param.is_any() && m_value.is_any(); } bool is_7bit() const { return m_param.is_any() && m_value.is_7bit(); } bool is_14bit() const { return m_param.is_any() && m_value.is_14bit(); } void clear_value() { m_status &= 0x7f; m_value.clear(); } private: unsigned long m_time; int m_port; unsigned char m_status; xrpn_data14 m_param; xrpn_data14 m_value; }; typedef QHash xrpn_cache; //--------------------------------------------------------------------- // xrpn_queue - decl. // class xrpn_queue { public: xrpn_queue ( unsigned int size = 0 ) : m_size(0), m_mask(0), m_read(0), m_write(0), m_events(0) { resize(size); } ~xrpn_queue () { if (m_events) delete [] m_events; } void resize ( unsigned int size ) { unsigned int new_size = 4; // must be a power-of-2... while (new_size < size) new_size <<= 1; if (new_size > m_size) { const unsigned int old_size = m_size; qxgeditMidiRpn::Event *new_events = new qxgeditMidiRpn::Event [new_size]; qxgeditMidiRpn::Event *old_events = m_events; if (old_events) { if (m_write > m_read) { ::memcpy(new_events + m_read, old_events + m_read, (m_write - m_read) * sizeof(qxgeditMidiRpn::Event)); } else if (m_write < m_read) { ::memcpy(new_events + m_read, old_events + m_read, (old_size - m_read) * sizeof(qxgeditMidiRpn::Event)); if (m_write > 0) { ::memcpy(new_events + old_size, old_events, m_write * sizeof(qxgeditMidiRpn::Event)); } m_write += old_size; } } m_size = new_size; m_mask = new_size - 1; m_events = new_events; if (old_events) delete [] old_events; } } void clear() { m_read = m_write = 0; } bool push ( unsigned long time, int port, unsigned char status, unsigned short param, unsigned short value ) { qxgeditMidiRpn::Event event; event.time = time; event.port = port; event.status = status; event.param = param; event.value = value; return push(event); } bool push ( const qxgeditMidiRpn::Event& event ) { if (count() >= m_mask) resize(m_size + 4); const unsigned int w = (m_write + 1) & m_mask; if (w == m_read) return false; m_events[m_write] = event; m_write = w; return true; } bool pop ( qxgeditMidiRpn::Event& event ) { const unsigned int r = m_read; if (r == m_write) return false; event = m_events[r]; m_read = (r + 1) & m_mask; return true; } bool is_pending () const { return (m_read != m_write); } unsigned int count() const { if (m_write < m_read) return (m_write + m_size - m_read) & m_mask; else return (m_write - m_read); } private: unsigned int m_size; unsigned int m_mask; unsigned int m_read; unsigned int m_write; qxgeditMidiRpn::Event *m_events; }; //--------------------------------------------------------------------- // qxgeditMidiRpn::Impl - decl. // class qxgeditMidiRpn::Impl { public: Impl() : m_count(0) {} bool is_pending () const { return m_queue.is_pending(); } bool dequeue ( qxgeditMidiRpn::Event& event ) { return m_queue.pop(event); } void flush() { if (m_count > 0) { xrpn_cache::Iterator iter = m_cache.begin(); const xrpn_cache::Iterator& iter_end = m_cache.end(); for ( ; iter != iter_end; ++iter) enqueue(iter.value()); m_cache.clear(); // m_count = 0; } } bool process ( const qxgeditMidiRpn::Event& event ) { const unsigned short channel = (event.status & 0x0f); if (event.param == RPN_MSB) { xrpn_item& item = get_item(event.port, channel); if (item.is_any() && item.type() != qxgeditMidiRpn::RPN) enqueue(item); if (item.is_status() // RPN nullptr [MSB] && item.type() == qxgeditMidiRpn::RPN && item.is_param_lsb() && item.param_lsb() == 0x7f && event.value == 0x7f) { item.clear(); --m_count; return true; } if (item.type() == qxgeditMidiRpn::NRPN) { item.clear(); item.set_status(qxgeditMidiRpn::RPN | channel); } else if (!item.is_status()) { item.set_status(qxgeditMidiRpn::RPN | channel); ++m_count; } if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_param_msb(event.value); return true; } else if (event.param == RPN_LSB) { xrpn_item& item = get_item(event.port, channel); if (item.is_any() && item.type() != qxgeditMidiRpn::RPN) enqueue(item); if (item.is_status() // RPN nullptr [LSB] && item.type() == qxgeditMidiRpn::RPN && item.is_param_msb() && item.param_msb() == 0x7f && event.value == 0x7f) { item.clear(); --m_count; return true; } if (item.type() == qxgeditMidiRpn::NRPN) { item.clear(); item.set_status(qxgeditMidiRpn::RPN | channel); } else if (!item.is_status()) { item.set_status(qxgeditMidiRpn::RPN | channel); ++m_count; } if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_param_lsb(event.value); return true; } else if (event.param == NRPN_MSB) { xrpn_item& item = get_item(event.port, channel); if (item.is_any() && item.type() != qxgeditMidiRpn::NRPN) enqueue(item); if (item.type() == qxgeditMidiRpn::RPN) { item.clear(); item.set_status(qxgeditMidiRpn::NRPN | channel); } else if (!item.is_status()) { item.set_status(qxgeditMidiRpn::NRPN | channel); ++m_count; } if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_param_msb(event.value); return true; } else if (event.param == NRPN_LSB) { xrpn_item& item = get_item(event.port, channel); if (item.is_any() && item.type() != qxgeditMidiRpn::NRPN) enqueue(item); if (item.type() == qxgeditMidiRpn::RPN) { item.clear(); item.set_status(qxgeditMidiRpn::NRPN | channel); } else if (!item.is_status()) { item.set_status(qxgeditMidiRpn::NRPN | channel); ++m_count; } if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_param_lsb(event.value); return true; } else if (event.param == DATA_MSB) { xrpn_item& item = get_item(event.port, channel); if (item.type() != qxgeditMidiRpn::RPN && item.type() != qxgeditMidiRpn::NRPN) { enqueue(item); return false; } if (!item.is_status()) item.set_status(item.type() | channel); if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_value_msb(event.value); if (item.is_14bit()) enqueue(item); return true; } else if (event.param == DATA_LSB) { xrpn_item& item = get_item(event.port, channel); if (item.type() != qxgeditMidiRpn::RPN && item.type() != qxgeditMidiRpn::NRPN) { enqueue(item); return false; } if (!item.is_status()) item.set_status(item.type() | channel); if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_value_lsb(event.value); if (item.is_14bit()) enqueue(item); return true; } else if (event.param > CC14_MSB_MIN && event.param < CC14_MSB_MAX) { xrpn_item& item = get_item(event.port, channel); if (item.is_any() && item.type() != qxgeditMidiRpn::CC14) { enqueue(item); item.clear(); --m_count; } else if ((item.is_param_msb() && item.is_value_msb()) || (item.type() == qxgeditMidiRpn::CC14 && item.is_param_lsb() && item.param_lsb() != event.param + CC14_LSB_MIN)) enqueue(item); if (!item.is_status()) { item.set_status(qxgeditMidiRpn::CC14 | channel); ++m_count; } if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_param_lsb(event.param + CC14_LSB_MIN); item.set_param_msb(event.param); item.set_value_msb(event.value); if (item.is_14bit()) enqueue(item); return true; } else if (event.param > CC14_LSB_MIN && event.param < CC14_LSB_MAX) { xrpn_item& item = get_item(event.port, channel); if (item.is_any() && item.type() != qxgeditMidiRpn::CC14) { enqueue(item); item.clear(); --m_count; } else if ((item.is_param_lsb() && item.is_value_lsb()) || (item.type() == qxgeditMidiRpn::CC14 && item.is_param_msb() && item.param_msb() != event.param - CC14_LSB_MIN)) enqueue(item); if (!item.is_status()) { item.set_status(qxgeditMidiRpn::CC14 | channel); ++m_count; } if (item.time() < event.time) item.set_time(event.time); if (item.port() != event.port) item.set_port(event.port); item.set_param_msb(event.param - CC14_LSB_MIN); item.set_param_lsb(event.param); item.set_value_lsb(event.value); if (item.is_14bit()) enqueue(item); return true; } return false; } protected: xrpn_item& get_item ( int port, unsigned short channel ) { return m_cache[(port << 4) | channel]; } void enqueue ( xrpn_item& item ) { if (!item.is_status()) return; const unsigned long time = item.time(); const int port = item.port(); if (item.type() == qxgeditMidiRpn::CC14) { if (item.is_14bit()) { m_queue.push(time, port, item.status(), item.param_msb(), item.value()); const unsigned char value_msb = item.value_msb(); item.clear_value(); item.set_value_msb(value_msb); item.set_time(0); // --m_count; } else { const unsigned char status = qxgeditMidiRpn::CC | item.channel(); if (item.is_param_msb() && item.is_value_msb()) m_queue.push(time, port, status, item.param_msb(), item.value_msb()); if (item.is_param_lsb() && item.is_value_lsb()) m_queue.push(time, port, status, item.param_lsb(), item.value_lsb()); item.clear(); --m_count; } } else if (item.is_14bit()) { m_queue.push(time, port, item.status(), item.param(), item.value()); item.clear_value(); item.set_time(0); // --m_count; } else { const unsigned char status = qxgeditMidiRpn::CC | item.channel(); if (item.type() == qxgeditMidiRpn::RPN) { if (item.is_param_msb()) m_queue.push(time, port, status, RPN_MSB, item.param_msb()); if (item.is_param_lsb()) m_queue.push(time, port, status, RPN_LSB, item.param_lsb()); } else if (item.type() == qxgeditMidiRpn::NRPN) { if (item.is_param_msb()) m_queue.push(time, port, status, NRPN_MSB, item.param_msb()); if (item.is_param_lsb()) m_queue.push(time, port, status, NRPN_LSB, item.param_lsb()); } if (item.is_value_msb()) m_queue.push(time, port, status, DATA_MSB, item.value_msb()); if (item.is_value_lsb()) m_queue.push(time, port, status, DATA_LSB, item.value_lsb()); item.clear(); --m_count; } } private: unsigned int m_count; xrpn_cache m_cache; xrpn_queue m_queue; }; //--------------------------------------------------------------------- // qxgeditMidiRpn - impl. // qxgeditMidiRpn::qxgeditMidiRpn (void) { m_pImpl = new qxgeditMidiRpn::Impl(); } qxgeditMidiRpn::~qxgeditMidiRpn (void) { delete m_pImpl; } bool qxgeditMidiRpn::isPending (void) const { return m_pImpl->is_pending(); } bool qxgeditMidiRpn::process ( const qxgeditMidiRpn::Event& event ) { return m_pImpl->process(event); } bool qxgeditMidiRpn::dequeue ( qxgeditMidiRpn::Event& event ) { return m_pImpl->dequeue(event); } void qxgeditMidiRpn::flush (void) { m_pImpl->flush(); } // end of qxgeditMidiRpn.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditOptions.h0000644000000000000000000000013214772452451016230 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditOptions.h0000644000175000001440000000534514772452451016227 0ustar00rncbcusers// qxgeditOptions.h // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditOptions_h #define __qxgeditOptions_h #include #include class QWidget; //------------------------------------------------------------------------- // qxgeditOptions - Prototype settings class (singleton). // class qxgeditOptions { public: // Constructor. qxgeditOptions(); // Default destructor. ~qxgeditOptions(); // The settings object accessor. QSettings& settings(); // Explicit I/O methods. void loadOptions(); void saveOptions(); // Command line arguments parser. bool parse_args(const QStringList& args); #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) void show_error(const QString& msg); #else // Command line usage helper. void print_usage(const QString& arg0); #endif // Startup supplied session file(s). QStringList sessionFiles; // Display options... bool bConfirmReset; bool bConfirmRemove; bool bCompletePath; float fRandomizePercent; int iBaseFontSize; QString sStyleTheme; QString sColorTheme; // View options... bool bMenubar; bool bStatusbar; bool bToolbar; // Default options... QString sSessionDir; QString sPresetDir; // Recent file list. int iMaxRecentFiles; QStringList recentFiles; // MIDI specific options. QStringList midiInputs; QStringList midiOutputs; // (QS300) USER VOICE Specific options. bool bUservoiceAutoSend; // Widget geometry persistence helper prototypes. void saveWidgetGeometry(QWidget *pWidget, bool bVisible = false); void loadWidgetGeometry(QWidget *pWidget, bool bVisible = false); // Singleton instance accessor. static qxgeditOptions *getInstance(); private: // Settings member variables. QSettings m_settings; // The singleton instance. static qxgeditOptions *g_pOptions; }; #endif // __qxgeditOptions_h // end of qxgeditOptions.h qxgedit-1.0.1/src/PaxHeaders/qxgeditPartEg.h0000644000000000000000000000013214772452451015757 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPartEg.h0000644000175000001440000000455014772452451015753 0ustar00rncbcusers// qxgeditPartEg.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditPartEg_h #define __qxgeditPartEg_h #include //---------------------------------------------------------------------------- // qxgeditPartEg -- Custom widget class qxgeditPartEg : public QFrame { Q_OBJECT public: // Constructor. qxgeditPartEg(QWidget *pParent = nullptr); // Destructor. ~qxgeditPartEg(); // Parameter getters. unsigned short attack() const; unsigned short decay() const; unsigned short release() const; public slots: // Parameter setters. void setAttack(unsigned short iAttack); void setDecay(unsigned short iDecay); void setRelease(unsigned short iRelease); signals: // Parameter change signals. void attackChanged(unsigned short iAttack); void decayChanged(unsigned short iDecay); void releaseChanged(unsigned short iRelease); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iAttack; unsigned short m_iDecay; unsigned short m_iRelease; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditPartEg_h // end of qxgeditPartEg.h qxgedit-1.0.1/src/PaxHeaders/qxgeditUserEg.h0000644000000000000000000000013214772452451015767 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditUserEg.h0000644000175000001440000000627214772452451015766 0ustar00rncbcusers// qxgeditUserEg.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditUserEg_h #define __qxgeditUserEg_h #include //---------------------------------------------------------------------------- // qxgeditUserEg -- Custom widget class qxgeditUserEg : public QFrame { Q_OBJECT public: // Constructor. qxgeditUserEg(QWidget *pParent = nullptr); // Destructor. ~qxgeditUserEg(); // Parameter getters. unsigned short level0() const; unsigned short level1() const; unsigned short level2() const; unsigned short level3() const; unsigned short level4() const; unsigned short rate1() const; unsigned short rate2() const; unsigned short rate3() const; unsigned short rate4() const; public slots: // Parameter setters. void setLevel0(unsigned short iLevel0); void setLevel1(unsigned short iLevel1); void setLevel2(unsigned short iLevel2); void setLevel3(unsigned short iLevel3); void setLevel4(unsigned short iLevel4); void setRate1(unsigned short iRate1); void setRate2(unsigned short iRate2); void setRate3(unsigned short iRate3); void setRate4(unsigned short iRate4); signals: // Parameter change signals. void level0Changed(unsigned short iLevel0); void level1Changed(unsigned short iLevel1); void level2Changed(unsigned short iLevel2); void level3Changed(unsigned short iLevel3); void level4Changed(unsigned short iLevel4); void rate1Changed(unsigned short iRate1); void rate2Changed(unsigned short iRate2); void rate3Changed(unsigned short iRate3); void rate4Changed(unsigned short iRate4); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iLevel0; unsigned short m_iLevel1; unsigned short m_iLevel2; unsigned short m_iLevel3; unsigned short m_iLevel4; unsigned short m_iRate1; unsigned short m_iRate2; unsigned short m_iRate3; unsigned short m_iRate4; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditUserEg_h // end of qxgeditUserEg.h qxgedit-1.0.1/src/PaxHeaders/qxgeditAmpEg.h0000644000000000000000000000013214772452451015566 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditAmpEg.h0000644000175000001440000000543014772452451015560 0ustar00rncbcusers// qxgeditAmpEg.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditAmpEg_h #define __qxgeditAmpEg_h #include //---------------------------------------------------------------------------- // qxgeditAmpEg -- Custom widget class qxgeditAmpEg : public QFrame { Q_OBJECT public: // Constructor. qxgeditAmpEg(QWidget *pParent = nullptr); // Destructor. ~qxgeditAmpEg(); // Parameter getters. unsigned short attack() const; unsigned short release() const; unsigned short decay1() const; unsigned short decay2() const; unsigned short level1() const; unsigned short level2() const; public slots: // Parameter setters. void setAttack(unsigned short iAttack); void setRelease(unsigned short iRelease); void setDecay1(unsigned short iDecay1); void setDecay2(unsigned short iDecay2); void setLevel1(unsigned short iLevel1); void setLevel2(unsigned short iLevel2); signals: // Parameter change signals. void attackChanged(unsigned short iAttack); void releaseChanged(unsigned short iRelease); void decay1Changed(unsigned short iDecay1); void decay2Changed(unsigned short iDecay2); void level1Changed(unsigned short iLevel1); void level2Changed(unsigned short iLevel2); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iAttack; unsigned short m_iRelease; unsigned short m_iDecay1; unsigned short m_iDecay2; unsigned short m_iLevel1; unsigned short m_iLevel2; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditAmpEg_h // end of qxgeditAmpEg.h qxgedit-1.0.1/src/PaxHeaders/qxgeditMainForm.h0000644000000000000000000000013214772452451016305 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditMainForm.h0000644000175000001440000001067114772452451016302 0ustar00rncbcusers// qxgeditMainForm.h // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditMainForm_h #define __qxgeditMainForm_h #include "ui_qxgeditMainForm.h" // Forward declarations... class qxgeditOptions; class qxgeditMidiDevice; class qxgeditXGMasterMap; class QSocketNotifier; class QTreeWidget; class QLabel; //---------------------------------------------------------------------------- // qxgeditMainForm -- UI wrapper form. class qxgeditMainForm : public QMainWindow { Q_OBJECT public: // Constructor. qxgeditMainForm(QWidget *pParent = nullptr); // Destructor. ~qxgeditMainForm(); static qxgeditMainForm *getInstance(); void setup(qxgeditOptions *pOptions); QString sessionName(const QString& sFilename); void showMessage(const QString& s); void showMessageError(const QString& s); public slots: void contentsChanged(); protected slots: void fileNew(); void fileOpen(); void fileOpenRecent(); void fileSave(); void fileSaveAs(); void fileExit(); void viewMenubar(bool bOn); void viewStatusbar(bool bOn); void viewToolbar(bool bOn); void viewRandomize(); void viewOptions(); void helpAbout(); void helpAboutQt(); void stabilizeForm(); void updateRecentFilesMenu(); void masterResetButtonClicked(); void reverbResetButtonClicked(); void chorusResetButtonClicked(); void variationResetButtonClicked(); void multipartResetButtonClicked(); void multipartComboActivated(int); void multipartVoiceComboActivated(int); void multipartVoiceChanged(); void multipartPartModeChanged(unsigned short); void drumsetupResetButtonClicked(); void drumsetupComboActivated(int); void drumsetupVoiceComboActivated(int); void drumsetupNoteComboActivated(int); void uservoiceResetButtonClicked(); void uservoiceComboActivated(int); void uservoiceElementComboActivated(int); void uservoiceSendButtonClicked(); void uservoiceAutoSendCheckToggled(bool); void uservoiceElementChanged(unsigned short); void uservoiceLoadPresetFile(const QString&); void uservoiceSavePresetFile(const QString&); void rpnReceived(unsigned char, unsigned short, unsigned short); void nrpnReceived(unsigned char, unsigned short, unsigned short); void sysexReceived(const QByteArray&); void handle_sigusr1(); void handle_sigterm(); protected: void closeEvent(QCloseEvent *pCloseEvent); void dragEnterEvent(QDragEnterEvent *pDragEnterEvent); void dropEvent(QDropEvent *pDropEvent); bool queryClose(); bool newSession(); bool openSession(); bool saveSession(bool bPrompt); bool closeSession(); bool loadSessionFile(const QString& sFilename); bool saveSessionFile(const QString& sFilename); void updateRecentFiles(const QString& sFilename); void masterReset(); bool isRandomizable() const; private: // The Qt-designer UI struct... Ui::qxgeditMainForm m_ui; // Instance variables... qxgeditOptions *m_pOptions; qxgeditMidiDevice *m_pMidiDevice; qxgeditXGMasterMap *m_pMasterMap; QSocketNotifier *m_pSigusr1Notifier; QSocketNotifier *m_pSigtermNotifier; QString m_sFilename; int m_iUntitled; int m_iDirtyCount; // Status bar item indexes enum { StatusName = 0, // Active session track caption. StatusMod = 1, // Current session modification state. StatusItems = 2 // Number of status items. }; QLabel *m_statusItems[StatusItems]; // Instrument/Normal Voice combo-box view soft-mutex. int m_iMultipartVoiceUpdate; // Uservoice element combo-box soft-mutex. int m_iUservoiceElementUpdate; // Kind-of singleton reference. static qxgeditMainForm *g_pMainForm; }; #endif // __qxgeditMainForm_h // end of qxgeditMainForm.h qxgedit-1.0.1/src/PaxHeaders/qxgeditPaletteForm.h0000644000000000000000000000013214772452451017017 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPaletteForm.h0000644000175000001440000001700314772452451017010 0ustar00rncbcusers// qxgeditPaletteForm.h // /**************************************************************************** Copyright (C) 2005-2024, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditPaletteForm_h #define __qxgeditPaletteForm_h #include #include #include #include #include #include // Forward decls. class QListView; class QLabel; class QToolButton; //------------------------------------------------------------------------- // qxgeditPaletteForm namespace Ui { class qxgeditPaletteForm; } class qxgeditPaletteForm: public QDialog { Q_OBJECT public: qxgeditPaletteForm(QWidget *parent = nullptr, const QPalette& pal = QPalette()); virtual ~qxgeditPaletteForm(); void setPalette(const QPalette& pal); const QPalette& palette() const; void setSettings(QSettings *settings, bool owner = false); QSettings *settings() const; void setPaletteName(const QString& name); QString paletteName() const; bool isDirty() const; static bool namedPalette(QSettings *settings, const QString& name, QPalette& pal, bool fixup = false); static QStringList namedPaletteList(QSettings *settings); static QString namedPaletteConf( QSettings *settings, const QString& name); static void addNamedPaletteConf( QSettings *settings, const QString& name, const QString& filename); static QPalette::ColorRole colorRole(const QString& name); class PaletteModel; class ColorDelegate; class ColorButton; class ColorEditor; class RoleEditor; protected slots: void nameComboChanged(const QString& name); void saveButtonClicked(); void deleteButtonClicked(); void generateButtonChanged(); void resetButtonClicked(); void detailsCheckClicked(); void importButtonClicked(); void exportButtonClicked(); void paletteChanged(const QPalette& pal); void accept(); void reject(); protected: void setPalette(const QPalette& pal, const QPalette& parentPal); bool namedPalette(const QString& name, QPalette& pal) const; QStringList namedPaletteList() const; QString namedPaletteConf(const QString& name) const; void addNamedPaletteConf(const QString& name, const QString& filename); void deleteNamedPaletteConf(const QString& name); static bool loadNamedPaletteConf( const QString& name, const QString& filename, QPalette& pal); static bool saveNamedPaletteConf( const QString& name, const QString& filename, const QPalette& pal); static bool loadNamedPalette( QSettings *settings, const QString& name, QPalette& pal); static bool saveNamedPalette( QSettings *settings, const QString& name, const QPalette& pal); void updateNamedPaletteList(); void updateGenerateButton(); void updateDialogButtons(); void setDefaultDir(const QString& dir); QString defaultDir() const; void setShowDetails(bool on); bool isShowDetails() const; void showEvent(QShowEvent *event); void resizeEvent(QResizeEvent *event); private: Ui::qxgeditPaletteForm *p_ui; Ui::qxgeditPaletteForm& m_ui; QSettings *m_settings; bool m_owner; QPalette m_palette; QPalette m_parentPalette; PaletteModel *m_paletteModel; bool m_modelUpdated; bool m_paletteUpdated; int m_dirtyCount; int m_dirtyTotal; }; //------------------------------------------------------------------------- // qxgeditPaletteForm::PaletteModel class qxgeditPaletteForm::PaletteModel : public QAbstractTableModel { Q_OBJECT Q_PROPERTY(QPalette::ColorRole colorRole READ colorRole) public: PaletteModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; void setPalette(const QPalette &palette, const QPalette &parentPalette); const QPalette& palette() const; void setGenerate(bool on) { m_generate = on; } QPalette::ColorRole colorRole() const { return QPalette::NoRole; } signals: void paletteChanged(const QPalette &palette); protected: QPalette::ColorGroup columnToGroup(int index) const; int groupToColumn(QPalette::ColorGroup group) const; private: QPalette m_palette; QPalette m_parentPalette; QMap m_roleNames; int m_nrows; bool m_generate; }; //------------------------------------------------------------------------- // qxgeditPaletteForm::ColorDelegate class qxgeditPaletteForm::ColorDelegate : public QItemDelegate { public: ColorDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {} QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; void setEditorData(QWidget *editor, const QModelIndex& index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex &index) const; virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; }; //------------------------------------------------------------------------- // qxgeditPaletteForm::ColorButton class qxgeditPaletteForm::ColorButton : public QPushButton { Q_OBJECT Q_PROPERTY(QBrush brush READ brush WRITE setBrush) public: ColorButton (QWidget *parent = nullptr); const QBrush& brush() const; void setBrush(const QBrush& b); signals: void changed(); protected slots: void chooseColor(); protected: void paintEvent(QPaintEvent *event); private: QBrush m_brush; }; //------------------------------------------------------------------------- // PaleteEditor::ColorEditor class qxgeditPaletteForm::ColorEditor : public QWidget { Q_OBJECT public: ColorEditor(QWidget *parent = nullptr); void setColor(const QColor &color); QColor color() const; bool changed() const; signals: void changed(QWidget *widget); protected slots: void colorChanged(); private: qxgeditPaletteForm::ColorButton *m_button; bool m_changed; }; //------------------------------------------------------------------------- // PaleteEditor::RoleEditor class qxgeditPaletteForm::RoleEditor : public QWidget { Q_OBJECT public: RoleEditor(QWidget *parent = nullptr); void setLabel(const QString &label); void setEdited(bool on); bool edited() const; signals: void changed(QWidget *widget); protected slots: void resetProperty(); private: QLabel *m_label; QToolButton *m_button; bool m_edited; }; #endif // __qxgeditPaletteForm_h // end of qxgeditPaletteForm.h qxgedit-1.0.1/src/PaxHeaders/qxgedit.qrc0000644000000000000000000000013214772452451015212 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgedit.qrc0000644000175000001440000000074014772452451015203 0ustar00rncbcusers images/qxgedit.png images/qxgedit.svg images/fileNew.png images/fileOpen.png images/fileSave.png images/formAccept.png images/formCreate.png images/formOpen.png images/formReject.png images/formRemove.png images/formSave.png images/itemReset.png qxgedit-1.0.1/src/PaxHeaders/qxgedit.h0000644000000000000000000000013214772452451014654 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgedit.h0000644000175000001440000000565114772452451014653 0ustar00rncbcusers// qxgedit.h // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgedit_h #define __qxgedit_h #include "qxgeditAbout.h" #include #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #if defined(Q_WS_X11) #define CONFIG_X11 #endif #endif // Forward decls. class QWidget; class QTranslator; #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_XUNIQUE #ifdef CONFIG_X11 #include typedef unsigned long Window; typedef unsigned long Atom; #endif // CONFIG_X11 #endif // CONFIG_XUNIQUE #else #ifdef CONFIG_XUNIQUE class QSharedMemory; class QLocalServer; #endif // CONFIG_XUNIQUE #endif //------------------------------------------------------------------------- // Singleton application instance stuff (Qt/X11 only atm.) // class qxgeditApplication : public QApplication { Q_OBJECT public: // Constructor. qxgeditApplication(int& argc, char **argv); // Destructor. ~qxgeditApplication(); // Main application widget accessors. void setMainWidget(QWidget *pWidget); QWidget *mainWidget() const { return m_pWidget; } // Check if another instance is running, // and raise its proper main widget... bool setup(); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_XUNIQUE #ifdef CONFIG_X11 void x11PropertyNotify(Window w); bool x11EventFilter(XEvent *pEv) #endif // CONFIG_X11 #endif // CONFIG_XUNIQUE #else #ifdef CONFIG_XUNIQUE protected slots: // Local server slots. void newConnectionSlot(); void readyReadSlot(); protected: // Local server/shmem setup/cleanup. bool setupServer(); void clearServer(); #endif // CONFIG_XUNIQUE #endif private: // Translation support. QTranslator *m_pQtTranslator; QTranslator *m_pMyTranslator; // Instance variables. QWidget *m_pWidget; #ifdef CONFIG_XUNIQUE #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifdef CONFIG_X11 Display *m_pDisplay; Atom m_aUnique; Window m_wOwner; #endif // CONFIG_X11 #else QString m_sUnique; QSharedMemory *m_pMemory; QLocalServer *m_pServer; #endif #endif // CONFIG_XUNIQUE }; #endif // __qxgedit_h // end of qxgedit.h qxgedit-1.0.1/src/PaxHeaders/XGParam.cpp0000644000000000000000000000013214772452451015041 xustar0030 mtime=1743410473.474221551 30 atime=1743410473.473607941 30 ctime=1743410473.474221551 qxgedit-1.0.1/src/XGParam.cpp0000644000175000001440000050315614772452451015043 0ustar00rncbcusers// XGParam.cpp // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "XGParam.h" #include #include #include #include // Table (2D-array) size in elements. #define TSIZE(tab) (sizeof(tab) / sizeof(tab[0])) //------------------------------------------------------------------------- // XG Effect Data Value Assign Tables // //------------------------------------------------------------------------- // Table#1 - LFO frequency (Hz) static float ftab1[] = { 0.00f, 0.08f, 0.08f, 0.16f, 0.16f, 0.25f, 0.25f, 0.33f, 0.33f, 0.42f, 0.42f, 0.50f, 0.50f, 0.58f, 0.58f, 0.67f, 0.67f, 0.75f, 0.75f, 0.84f, 0.84f, 0.92f, 0.92f, 1.00f, 1.00f, 1.09f, 1.09f, 1.17f, 1.17f, 1.26f, 1.26f, 1.34f, 1.34f, 1.43f, 1.43f, 1.51f, 1.51f, 1.59f, 1.59f, 1.68f, 1.68f, 1.76f, 1.76f, 1.85f, 1.85f, 1.93f, 1.93f, 2.01f, 2.01f, 2.10f, 2.10f, 2.18f, 2.18f, 2.27f, 2.27f, 2.35f, 2.35f, 2.43f, 2.43f, 2.52f, 2.52f, 2.60f, 2.60f, 2.69f, 2.69f, 2.77f, 2.86f, 2.94f, 3.02f, 3.11f, 3.19f, 3.28f, 3.36f, 3.44f, 3.53f, 3.61f, 3.70f, 3.86f, 4.03f, 4.20f, 4.37f, 4.54f, 4.71f, 4.87f, 5.04f, 5.21f, 5.38f, 5.55f, 5.72f, 6.05f, 6.39f, 6.72f, 7.06f, 7.40f, 7.73f, 8.07f, 8.41f, 8.74f, 9.08f, 9.42f, 9.75f, 10.00f, 10.70f, 11.40f, 12.10f, 12.70f, 13.40f, 14.10f, 14.80f, 15.40f, 16.10f, 16.80f, 17.40f, 18.10f, 19.50f, 20.80f, 22.20f, 23.50f, 24.80f, 26.20f, 27.50f, 28.90f, 30.20f, 31.60f, 32.90f, 34.30f, 37.00f, 39.70f }; static float getvtab1 ( unsigned short c ) { return ftab1[c]; } static unsigned short getutab1 ( float v ) { unsigned short c; for (c = TSIZE(ftab1) - 1; c > 0; --c) { if (v >= ftab1[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#2 - Modulation Delay Offset (ms) static float ftab2[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f, 3.6f, 3.7f, 3.8f, 3.9f, 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f, 4.6f, 4.7f, 4.8f, 4.9f, 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f, 5.6f, 5.7f, 5.8f, 5.9f, 6.0f, 6.1f, 6.2f, 6.3f, 6.4f, 6.5f, 6.6f, 6.7f, 6.8f, 6.9f, 7.0f, 7.1f, 7.2f, 7.3f, 7.4f, 7.5f, 7.6f, 7.7f, 7.8f, 7.9f, 8.0f, 8.1f, 8.2f, 8.3f, 8.4f, 8.5f, 8.6f, 8.7f, 8.8f, 8.9f, 9.0f, 9.1f, 9.2f, 9.3f, 9.4f, 9.5f, 9.6f, 9.7f, 9.8f, 9.9f, 10.0f, 11.1f, 12.2f, 13.3f, 14.4f, 15.5f, 17.1f, 18.6f, 20.2f, 21.8f, 23.3f, 24.9f, 26.5f, 28.0f, 29.6f, 31.2f, 32.8f, 34.3f, 35.9f, 37.5f, 39.0f, 40.6f, 42.2f, 43.7f, 45.3f, 46.9f, 48.4f, 50.0f }; static float getvtab2 ( unsigned short c ) { return ftab2[c]; } static unsigned short getutab2 ( float v ) { unsigned short c; for (c = TSIZE(ftab2) - 1; c > 0; --c) { if (v >= ftab2[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#3 - EQ Frequency (Hz) static float ftab3[] = { 20.0f, 22.0f, 25.0f, 28.0f, 32.0f, 36.0f, 40.0f, 45.0f, 50.0f, 56.0f, 63.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f, 125.0f, 140.0f, 160.0f, 180.0f, 200.0f, 225.0f, 250.0f, 280.0f, 315.0f, 355.0f, 400.0f, 450.0f, 500.0f, 560.0f, 630.0f, 700.0f, 800.0f, 900.0f, 1000.0f, 1100.0f, 1200.0f, 1400.0f, 1600.0f, 1800.0f, 2000.0f, 2200.0f, 2500.0f, 2800.0f, 3200.0f, 3600.0f, 4000.0f, 4500.0f, 5000.0f, 5600.0f, 6300.0f, 7000.0f, 8000.0f, 9000.0f, 10000.0f,11000.0f,12000.0f,14000.0f,16000.0f,18000.0f, 20000.0f }; static float getvtab3 ( unsigned short c ) { return ftab3[c]; } static unsigned short getutab3 ( float v ) { unsigned short c; for (c = TSIZE(ftab3) - 1; c > 0; --c) { if (v >= ftab3[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#4 - Reverb Time (ms) static float ftab4[] = { 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f, 3.6f, 3.7f, 3.8f, 3.9f, 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f, 4.6f, 4.7f, 4.8f, 4.9f, 5.0f, 5.5f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 8.5f, 9.0f, 9.5f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 25.0f, 30.0f }; static float getvtab4 ( unsigned short c ) { return ftab4[c]; } static unsigned short getutab4 ( float v ) { unsigned short c; for (c = TSIZE(ftab4) - 1; c > 0; --c) { if (v >= ftab4[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#5 - Delay Time (ms) static float ftab5[] = { 0.1f, 1.7f, 3.2f, 4.8f, 6.4f, 8.0f, 9.5f, 11.1f, 12.7f, 14.3f, 15.8f, 17.4f, 19.0f, 20.6f, 22.1f, 23.7f, 25.3f, 26.9f, 28.4f, 30.0f, 31.6f, 33.2f, 34.7f, 36.3f, 37.9f, 39.5f, 41.0f, 42.6f, 44.2f, 45.7f, 47.3f, 48.9f, 50.5f, 52.0f, 53.6f, 55.2f, 56.8f, 58.3f, 59.9f, 61.5f, 63.1f, 64.6f, 66.2f, 67.8f, 69.4f, 70.9f, 72.5f, 74.1f, 75.7f, 77.2f, 78.8f, 80.4f, 81.9f, 83.5f, 85.1f, 86.7f, 88.2f, 89.8f, 91.4f, 93.0f, 94.5f, 96.1f, 97.7f, 99.3f, 100.8f, 102.4f, 104.0f, 105.6f, 107.1f, 108.7f, 110.3f, 111.9f, 113.4f, 115.0f, 116.6f, 118.2f, 119.7f, 121.3f, 122.9f, 124.4f, 126.0f, 127.6f, 129.2f, 130.7f, 132.3f, 133.9f, 135.5f, 137.0f, 138.6f, 140.2f, 141.8f, 143.3f, 144.9f, 146.5f, 148.1f, 149.6f, 151.2f, 152.8f, 154.4f, 155.9f, 157.5f, 159.1f, 160.6f, 162.2f, 163.8f, 165.4f, 166.9f, 168.5f, 170.1f, 171.7f, 173.2f, 174.8f, 176.4f, 178.0f, 179.5f, 181.1f, 182.7f, 184.3f, 185.8f, 187.4f, 189.0f, 190.6f, 192.1f, 193.7f, 195.3f, 196.9f, 198.4f, 200.0f }; static float getvtab5 ( unsigned short c ) { return ftab5[c]; } static unsigned short getutab5 ( float v ) { unsigned short c; for (c = TSIZE(ftab5) - 1; c > 0; --c) { if (v >= ftab5[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#6 - Room Size (m) static float ftab6[] = { 0.1f, 0.3f, 0.4f, 0.6f, 0.7f, 0.9f, 1.0f, 1.2f, 1.4f, 1.5f, 1.7f, 1.8f, 2.0f, 2.1f, 2.3f, 2.5f, 2.6f, 2.8f, 2.9f, 3.1f, 3.2f, 3.4f, 3.5f, 3.7f, 3.9f, 4.0f, 4.2f, 4.3f, 4.5f, 4.6f, 4.8f, 5.0f, 5.1f, 5.3f, 5.4f, 5.6f, 5.7f, 5.9f, 6.1f, 6.2f, 6.4f, 6.5f, 6.7f, 6.8f, 7.0f }; static float getvtab6 ( unsigned short c ) { return ftab6[c]; } static unsigned short getutab6 ( float v ) { unsigned short c; for (c = TSIZE(ftab6) - 1; c > 0; --c) { if (v >= ftab6[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#7 - Delay Time (ms) static float ftab7[] = { 0.1f, 3.2f, 6.4f, 9.5f, 12.7f, 15.8f, 19.0f, 22.1f, 25.3f, 28.4f, 31.6f, 34.7f, 37.9f, 41.0f, 44.2f, 47.3f, 50.5f, 53.6f, 56.8f, 59.9f, 63.1f, 66.2f, 69.4f, 72.5f, 75.7f, 78.8f, 82.0f, 85.1f, 88.3f, 91.4f, 94.6f, 97.7f, 100.9f, 104.0f, 107.2f, 110.3f, 113.5f, 116.6f, 119.8f, 122.9f, 126.1f, 129.2f, 132.4f, 135.5f, 138.6f, 141.8f, 144.9f, 148.1f, 151.2f, 154.4f, 157.5f, 160.7f, 163.8f, 167.0f, 170.1f, 173.3f, 176.4f, 179.6f, 182.7f, 185.9f, 189.0f, 192.2f, 195.3f, 198.5f, 201.6f, 204.8f, 207.9f, 211.1f, 214.2f, 217.4f, 220.5f, 223.7f, 226.8f, 230.0f, 233.1f, 236.3f, 239.4f, 242.6f, 245.7f, 248.9f, 252.0f, 255.2f, 258.3f, 261.5f, 264.6f, 267.7f, 270.9f, 274.0f, 277.2f, 280.3f, 283.5f, 286.6f, 289.8f, 292.9f, 296.1f, 299.2f, 302.4f, 305.5f, 308.7f, 311.8f, 315.0f, 318.1f, 321.3f, 324.4f, 327.6f, 330.7f, 333.9f, 337.0f, 340.2f, 343.3f, 346.5f, 349.6f, 352.8f, 355.9f, 359.1f, 362.2f, 365.4f, 368.5f, 371.7f, 374.8f, 378.0f, 381.1f, 384.3f, 387.4f, 390.6f, 393.7f, 396.9f, 400.0f }; static float getvtab7 ( unsigned short c ) { return ftab7[c]; } static unsigned short getutab7 ( float v ) { unsigned short c; for (c = TSIZE(ftab7) - 1; c > 0; --c) { if (v >= ftab7[c]) return c; } return 0; } //------------------------------------------------------------------------- // Table#8 - Reverb Width; Depth; Height (m) static float ftab8[] = { 0.5f, 0.8f, 1.0f, 1.3f, 1.5f, 1.8f, 2.0f, 2.3f, 2.6f, 2.8f, 3.1f, 3.3f, 3.6f, 3.9f, 4.1f, 4.4f, 4.6f, 4.9f, 5.2f, 5.4f, 5.7f, 5.9f, 6.2f, 6.5f, 6.7f, 7.0f, 7.2f, 7.5f, 7.8f, 8.0f, 8.3f, 8.6f, 8.8f, 9.1f, 9.4f, 9.6f, 9.9f, 10.2f, 10.4f, 10.7f, 11.0f, 11.2f, 11.5f, 11.8f, 12.1f, 12.3f, 12.6f, 12.9f, 13.1f, 13.4f, 13.7f, 14.0f, 14.2f, 14.5f, 14.8f, 15.1f, 15.4f, 15.6f, 15.9f, 16.2f, 16.5f, 16.8f, 17.1f, 17.3f, 17.6f, 17.9f, 18.2f, 18.5f, 18.8f, 19.1f, 19.4f, 19.7f, 20.0f, 20.2f, 20.5f, 20.8f, 21.1f, 21.4f, 21.7f, 22.0f, 22.4f, 22.7f, 23.0f, 23.3f, 23.6f, 23.9f, 24.2f, 24.5f, 24.9f, 25.2f, 25.5f, 25.8f, 26.1f, 26.5f, 26.8f, 27.1f, 27.5f, 27.8f, 28.1f, 28.5f, 28.8f, 29.2f, 29.5f, 29.9f, 30.2f }; static float getvtab8 ( unsigned short c ) { return ftab8[c]; } static unsigned short getutab8 ( float v ) { unsigned short c; for (c = TSIZE(ftab8) - 1; c > 0; --c) { if (v >= ftab8[c]) return c; } return 0; } //------------------------------------------------------------------------- // static float getv0x40 ( unsigned short c ) { return (float) (c - 64); } static unsigned short getu0x40 ( float v ) { return (unsigned short) (v + 64.0f); } //------------------------------------------------------------------------- // static float getv0x80 ( unsigned short c ) { return (float) (c - 128); } static unsigned short getu0x80 ( float v ) { return (unsigned short) (v + 128.0f); } //------------------------------------------------------------------------- // static float getv_180 ( unsigned short c ) { return 3.0f * getv0x40(c); } static unsigned short getu_180 ( float v ) { return getu0x40(v / 3.0f); } //------------------------------------------------------------------------- // static float getv0_10 ( unsigned short c ) { return 0.1f * (float) (c); } static unsigned short getu0_10 ( float v ) { return (unsigned short) (10.0f * v); } //------------------------------------------------------------------------- // static float getv_100 ( unsigned short c ) { return getv0x40(c) / 0.63f; } static unsigned short getu_100 ( float v ) { return getu0x40(v * 0.63f); } //------------------------------------------------------------------------- // static float getv94_5 ( unsigned short c ) { return 94.5f * getv0x40(c) / 0.63f; } static unsigned short getu94_5 ( float v ) { return getu0x40(0.63f * v / 94.5f); } //------------------------------------------------------------------------- // static float getv12_7 ( unsigned short c ) { return 0.1f * getv0x80(c); } static unsigned short getu12_7 ( float v ) { return getu0x80(10.0f * v); } //------------------------------------------------------------------------- // static float getv1024 ( unsigned short c ) { return 0.1f * (float) (c - 1024); } static unsigned short getu1024 ( float v ) { return (unsigned short) (1024.0f + 10.0f * v); } //------------------------------------------------------------------------- // static float getvprog ( unsigned short c ) { return (float) (c + 1); } static unsigned short getuprog ( float v ) { return (unsigned short) (v - 1.0f); } //------------------------------------------------------------------------- // static const char *getsimod ( unsigned short c ) { static const char *tabimod[] = { "Mono", "Stereo" }; return tabimod[c]; } static const char *getsisel ( unsigned short c ) { static const char *tabisel[] = { "L", "R", "L&R" }; return tabisel[c]; } static const char *getsreft ( unsigned short c ) { static const char *tabreft[] = { "S-H", "L-H", "Rdm", "Rvs", "Plt", "Spr" }; return tabreft[c]; } static const char *getsrevt ( unsigned short c ) { static const char *tabrevt[] = { "Type A", "Type B" }; return tabrevt[c]; } static const char *getspand ( unsigned short c ) { static const char *tabpand[] = { "L<->R", "L->R", "L<-R", "Lturn", "Rturn", "L/R" }; return tabpand[c]; } static const char *getsampt ( unsigned short c ) { static const char *tabampt[] = { "Off", "Stack", "Combo", "Tube" }; return tabampt[c]; } static const char *getsonff ( unsigned short c ) { static const char *tabonff[] = { "Off", "On" }; return tabonff[c]; } static const char *getskeya ( unsigned short c ) { static const char *tabkeya[] = { "Single", "Multi", "Instr" }; return tabkeya[c]; } static const char *getsmmod ( unsigned short c ) { static const char *tabmmod[] = { "Mono", "Poly" }; return tabmmod[c]; } static const char *getspmod ( unsigned short c ) { static const char *tabpmod[] = { "Normal", "Drum", "Drum 1", "Drum 2" }; return tabpmod[c]; } static const char *getsconn ( unsigned short c ) { static const char *tabconn[] = { "Insert", "System" }; return tabconn[c]; } static const char *getslfow ( unsigned short c ) { static const char *tablfow[] = { "Saw", "Tri", "S&H" }; return tablfow[c]; } static const char *getspscl ( unsigned short c ) { static const char *tabpscl[] = { "100%", "50%", "20%", "10%", "5%", "0%" }; return tabpscl[c]; } static const char *getspdph ( unsigned short c ) { static const char *tabpdph[] = { "1/2oct", "1oct", "2oct", "4oct" }; return tabpdph[c]; } static const char *getselem ( unsigned short c ) { static const char *tabelem[] = { "1", "2", "1+2" }; return tabelem[c - 1]; } static const char *getschan ( unsigned short c ) { if (c < 16) { static char chan[4]; snprintf(chan, sizeof(chan), "%u", c + 1); return chan; } else if (c == 127) return "Off"; return nullptr; } static const char *getsvelc ( unsigned short c ) { static const char *tabvelc[] = { "Linear", "Exp" }; return tabvelc[c]; } static const char *getsvpan ( unsigned short c ) { if (c < 15) { static char vpan[3]; snprintf(vpan, sizeof(vpan), "%2d", int(c) - 7); return vpan; } else if (c == 15) return "Scale"; return nullptr; } // static const char *getsnote ( unsigned short c ) { static const char *tabnote[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; static char note[8]; snprintf(note, sizeof(note), "%-2s%2d", tabnote[c % 12], (c / 12) - 1); return note; } //--------------------------------------------------------------------- // QS300 Wave List. // const char *getswave ( unsigned short c ) { static struct _QS300WaveItem { unsigned short id; const char *name; unsigned short no; } wavetab[] = { // [Piano & Keyboard] { 0, "Grand", 37 }, // Ap { 1, "Brite", 38 }, // Ap { 2, "Honky", 39 }, // Ap { 3, "Roads", 56 }, // Ep { 4, "CP80", 172 }, // Ep { 5, "DX7", 55 }, // Ep { 6, "Accordion", 79 }, // Mk { 7, "Bandoneon", 241 }, // Mk { 8, "Celesta", 80 }, // Mk { 9, "Clavi.", 81 }, // Mk { 10, "Harpsichrd", 82 }, // Mk // [Chromatic & Organ] { 11, "Glocken", 105 }, // Cp { 12, "Marimba", 106 }, // Cp { 13, "SteelDrum", 107 }, // Cp { 14, "Timpani", 108 }, // Cp { 15, "TinkleBell", 109 }, // Cp { 16, "TabularBell", 110 }, // Cp { 17, "Vibes", 111 }, // Cp { 18, "Xylophone", 112 }, // Cp { 19, "Pipe", 86 }, // Ao { 20, "Reed", 87 }, // Ao { 21, "Drawbar 1", 83 }, // Eo { 22, "Drawbar 2", 240 }, // Eo { 23, "Percussive", 84 }, // Eo { 24, "Rock 1", 85 }, // Eo { 25, "Rock 2", 237 }, // Eo // [Guitar & Bass] { 26, "Nylon", 71 }, // Ag { 27, "Steel", 72 }, // Ag { 28, "12GtrUpper", 190 }, // Ag { 29, "Jazz Gtr", 73 }, // Eg { 30, "Clean", 74 }, // Eg { 31, "Muted", 75 }, // Eg { 32, "Overdrive", 76 }, // Eg { 33, "OverdriveLp", 183 }, // Eg { 34, "Distortion", 77 }, // Eg { 35, "Harmonics1", 78 }, // Eg { 36, "Harmonics2", 242 }, // Eg { 37, "Upright", 46 }, // Ab { 38, "Finger", 40 }, // Eb { 39, "Fretless", 41 }, // Eb { 40, "Picked", 42 }, // Eb { 41, "Slap 1", 43 }, // Eb { 42, "Slap 2", 44 }, // Eb { 43, "Thump", 45 }, // Eb { 44, "Bass 1", 97 }, // Mb { 45, "Bass 2", 98 }, // Mb // [Strings & Ensemble] { 46, "Violin", 88 }, // Bw { 47, "Viola", 89 }, // Bw { 48, "Cello", 90 }, // Bw { 49, "ContraBass", 91 }, // Bw { 50, "SectionEns", 92 }, // Oe { 51, "Pizzicato", 93 }, // Oe { 52, "StrngEnsLp", 180 }, // Oe { 53, "Ensemble", 231 }, // Oe { 54, "Aah", 53 }, // Ch { 55, "Ooh", 54 }, // Ch // [Brass & Reed] { 56, "Trumpet", 47 }, // Ar { 57, "MutedTrp", 48 }, // Ar { 58, "Trombone", 49 }, // Ar { 59, "Tuba", 50 }, // Ar { 60, "FrenchHorn", 51 }, // Ar { 61, "TrumpetEns", 52 }, // Ar { 62, "Brass", 99 }, // Sr { 63, "Bassoon", 113 }, // Rd { 64, "Clarinet", 114 }, // Rd { 65, "EnglshHorn", 115 }, // Rd { 66, "Oboe", 117 }, // Rd { 67, "SopranoSax", 120 }, // Rd { 68, "SprSaxAtk", 176 }, // Rd { 69, "AltoSax", 121 }, // Rd { 70, "AltoSaxAtk", 177 }, // Rd { 71, "TenorSax", 184 }, // Rd { 72, "BaritonSax", 123 }, // Rd { 73, "BariSaxAtk", 179 }, // Rd { 74, "BariSaxLp", 182 }, // Rd { 75, "Flute", 116 }, // Rd { 76, "Piccolo", 118 }, // Pi { 77, "SprRecordr", 119 }, // Pi // [Ethnic] { 78, "Banjo", 57 }, // Et { 79, "BagPipe", 58 }, // Et { 80, "Dulcimer", 59 }, // Et { 81, "Harmonica", 60 }, // Et { 82, "Harp", 61 }, // Et { 83, "Kalimba", 62 }, // Et { 84, "Koto", 63 }, // Et { 85, "Ocarina", 64 }, // Et { 86, "Shakuhachi", 66 }, // Et { 87, "Shamisen", 67 }, // Et { 88, "Sho", 69 }, // Et { 89, "Sitar", 70 }, // Et { 90, "Shanai", 188 }, // Et { 91, "PanFlute", 243 }, // Et // [Percusssive] { 92, "SideStick", 4 }, // Pc { 93, "Snare 1", 5 }, // Pc { 94, "Snare 2", 6 }, // Pc { 95, "Snare 3", 7 }, // Pc { 96, "Snare 4", 8 }, // Pc { 97, "Snare 5", 9 }, // Pc { 98, "Snare 6", 10 }, // Pc { 99, "SnareBrush", 11 }, // Pc { 100, "Tom 1", 12 }, // Pc { 101, "Tom 2", 13 }, // Pc { 102, "Tom 3", 14 }, // Pc { 103, "Tom 4", 15 }, // Pc { 104, "Tom 5", 16 }, // Pc { 105, "Tom 6", 17 }, // Pc { 106, "Kick 1", 18 }, // Pc { 107, "Kick 2", 19 }, // Pc { 108, "Kick 3", 20 }, // Pc { 109, "Kick 4", 21 }, // Pc { 110, "GranCassa", 22 }, // Pc { 111, "Stick", 23 }, // Pc { 112, "Cymbal 1", 24 }, // Pc { 113, "Cymbal 2", 25 }, // Pc { 114, "Cymbal 3", 26 }, // Pc { 115, "Cymbal 4", 27 }, // Pc { 116, "LoopCymbal", 29 }, // Pc { 117, "Agogo", 32 }, // Pc { 118, "Castanet", 33 }, // Pc { 119, "WoodBlock", 34 }, // Pc { 120, "Taiko", 35 }, // Pc { 121, "Triangle", 36 }, // Pc // [SFX] { 122, "BassSlap", 128 }, // Me { 123, "GtrStroke", 138 }, // Me { 124, "GtrFretNz", 139 }, // Me { 125, "KeyPad", 143 }, // Me { 126, "Metronome", 146 }, // Me { 127, "OrchHit", 148 }, // Me { 128, "WindChime", 163 }, // Me { 129, "TublrBell.p", 189 }, // Me { 130, "XylophonLp", 191 }, // Me { 131, "Scratch", 245 }, // Me { 132, "Applause", 124 }, // Ne { 133, "Bird 1", 125 }, // Ne { 134, "Bird 2", 126 }, // Ne { 135, "Breath", 127 }, // Ne { 136, "Bubble", 129 }, // Ne { 137, "CarPass", 130 }, // Ne { 138, "CarCrash", 131 }, // Ne { 139, "CarStart", 132 }, // Ne { 140, "Dog", 133 }, // Ne { 141, "DoorSlam", 134 }, // Ne { 142, "DoorSqueak", 135 }, // Ne { 142, "FootStep", 136 }, // Ne { 144, "Gallop", 137 }, // Ne { 145, "Gun", 140 }, // Ne { 146, "Helicopter", 141 }, // Ne { 147, "HeartBeat", 142 }, // Ne { 148, "Laughing", 144 }, // Ne { 149, "MachineGun", 145 }, // Ne { 150, "Punch", 149 }, // Ne { 151, "Rain", 150 }, // Ne { 152, "Scream", 151 }, // Ne { 153, "Stream", 152 }, // Ne { 154, "Surf", 153 }, // Ne { 155, "TelDial", 154 }, // Ne { 156, "TelRing 1", 155 }, // Ne { 157, "TelRing 2", 162 }, // Ne { 158, "Thunder", 156 }, // Ne { 159, "TireSkid", 157 }, // Ne { 160, "Train", 158 }, // Ne { 161, "Wind", 159 }, // Ne // [One-cycle Wave] { 162, "Square", 94 }, // Ow { 163, "Saw", 95 }, // Ow { 164, "Sine", 195 }, // Ow { 165, "Digi 1", 196 }, // Ow { 166, "Digi 2", 197 }, // Ow { 167, "Digi 3", 198 }, // Ow { 168, "Digi 4", 199 }, // Ow { 169, "Digi 5", 200 }, // Ow { 170, "Digi 6", 201 }, // Ow { 171, "Digi 7", 202 }, // Ow { 172, "Digi 8", 203 }, // Ow { 173, "Digi 9", 204 }, // Ow { 174, "Digi 10", 205 }, // Ow { 175, "Digi 11", 206 }, // Ow { 176, "Digi 12", 207 }, // Ow { 177, "Digi 13", 208 }, // Ow { 178, "Digi 14", 209 }, // Ow { 179, "Digi 15", 210 }, // Ow { 180, "Digi 16", 211 }, // Ow { 181, "Digi 17", 212 }, // Ow { 182, "Digi 19", 213 }, // Ow { 183, "Digi 20", 214 }, // Ow { 184, "Digi 21", 215 }, // Ow { 185, "Digi 22", 216 }, // Ow { 186, "Digi 23", 217 }, // Ow { 187, "Digi 24", 218 }, // Ow { 188, "Digi 25", 219 }, // Ow { 189, "Digi 26", 220 }, // Ow { 190, "Digi 27", 221 }, // Ow { 191, "Digi 28", 222 }, // Ow { 192, "Digi 29", 223 }, // Ow { 193, "Digi 30", 224 }, // Ow { 194, "Digi 31", 225 }, // Ow { 195, "Digi 32", 226 }, // Ow { 196, "Pulse 10", 228 }, // Ow { 197, "Pulse 25", 229 }, // Ow // [Loop & Misc] { 198, "Pad 1", 102 }, // Lw { 199, "Pad 2", 227 }, // Lw { 200, "Pad 3", 230 }, // Lw { 201, "Itopia", 236 }, // Lw { 202, "Mallet", 104 }, // Mw { 203, "Noise", 147 }, // Mw { 204, "Stndrd Kit", 1 } // Dr }; static QHash waves; if (waves.isEmpty()) { for (unsigned short i = 0; i < TSIZE(wavetab); ++i) waves.insert(wavetab[i].no, wavetab[i].name); } if (waves.contains(c)) return waves.value(c); return nullptr; } //------------------------------------------------------------------------- // static const char *unit_Hz (void) { return "Hz"; } static const char *unit_ms (void) { return "ms"; } static const char *unit_dB (void) { return "dB"; } static const char *unit_deg (void) { return "deg"; } static const char *unit_m (void) { return "m"; } static const char *unit_cen (void) { return "cents"; } static const char *unit_sem (void) { return "semitones"; } static const char *unit_pct (void) { return "%"; } //--------------------------------------------------------------------- // XG Normal Voice List // typedef struct _XGNormalVoiceItem { unsigned short bank; unsigned short prog; const char *name; unsigned short elem; } XGNormalVoiceItem; // Piano static XGNormalVoiceItem PianoTab[] = { // bank prog name elem { 0, 1, "GrandPno", 1 }, { 1, 1, "GrndPnoK", 1 }, { 18, 1, "MelloGrP", 1 }, { 40, 1, "PianoStr", 2 }, { 41, 1, "Dream", 2 }, { 0, 2, "BritePno", 1 }, { 1, 2, "BritPnoK", 1 }, { 0, 3, "E.Grand", 2 }, { 1, 3, "ElGrPnoK", 2 }, { 32, 3, "Det.CP80", 2 }, { 40, 3, "ElGrPno1", 2 }, { 41, 3, "ElGrPno2", 2 }, { 0, 4, "HnkyTonk", 2 }, { 1, 4, "HnkyTnkK", 2 }, { 5, 4, "0 E.Piano1", 2 }, { 1, 4, "El.Pno1K", 1 }, { 18, 4, "MelloEP1", 2 }, { 32, 4, "Chor.EP1", 2 }, { 40, 4, "HardEl.P", 2 }, { 45, 4, "VX El.P1", 2 }, { 64, 4, "60sEl.P", 1 }, { 0, 6, "E.Piano2", 2 }, { 1, 6, "El.Pno2K", 1 }, { 32, 6, "Chor.EP2", 2 }, { 33, 6, "DX Hard", 2 }, { 34, 6, "DXLegend", 2 }, { 40, 6, "DX Phase", 2 }, { 41, 6, "DX+Analg", 2 }, { 42, 6, "DXKotoEP", 2 }, { 45, 6, "VX El.P2", 2 }, { 0, 7, "Harpsi.", 1 }, { 1, 7, "Harpsi.K", 1 }, { 25, 7, "Harpsi.2", 2 }, { 35, 7, "Harpsi.3", 2 }, { 0, 8, "Clavi.", 2 }, { 1, 8, "Clavi. K", 1 }, { 27, 8, "ClaviWah", 2 }, { 64, 8, "PulseClv", 1 }, { 65, 8, "PierceCl", 2 } }; // Chromatic Percussion static XGNormalVoiceItem ChromaticPercussionTab[] = { // bank prog name elem { 0, 9, "Celesta", 1 }, { 0, 10, "Glocken", 1 }, { 0, 11, "MusicBox", 2 }, { 64, 11, "Orgel", 2 }, { 0, 12, "Vibes", 1 }, { 1, 12, "VibesK", 1 }, { 45, 12, "HardVibe", 2 }, { 0, 13, "Marimba", 1 }, { 1, 13, "MarimbaK", 1 }, { 64, 13, "SineMrmb", 2 }, { 97, 13, "Balafon2", 2 }, { 98, 13, "Log Drum", 2 }, { 0, 14, "Xylophon", 1 }, { 0, 15, "TubulBel", 1 }, { 96, 15, "ChrchBel", 2 }, { 97, 15, "Carillon", 2 }, { 0, 16, "Dulcimer", 1 }, { 35, 16, "Dulcimr2", 2 }, { 96, 16, "Cimbalom", 2 }, { 97, 16, "Santur", 2 } }; // Organ static XGNormalVoiceItem OrganTab[] = { // bank prog name elem { 0, 17, "DrawOrgn", 1 }, { 32, 17, "DetDrwOr", 2 }, { 33, 17, "60sDrOr1", 2 }, { 34, 17, "60sDrOr2", 2 }, { 35, 17, "70sDrOr1", 2 }, { 36, 17, "DrawOrg2", 2 }, { 37, 17, "60sDrOr3", 2 }, { 38, 17, "EvenBar", 2 }, { 40, 17, "16+2\"2/3", 2 }, { 64, 17, "Organ Ba", 1 }, { 65, 17, "70sDrOr2", 2 }, { 66, 17, "CheezOrg", 2 }, { 67, 17, "DrawOrg3", 2 }, { 0, 18, "PercOrgn", 1 }, { 24, 18, "70sPcOr1", 2 }, { 32, 18, "DetPrcOr", 2 }, { 33, 18, "LiteOrg", 2 }, { 37, 18, "PercOrg2", 2 }, { 0, 19, "RockOrgn", 2 }, { 64, 19, "RotaryOr", 2 }, { 65, 19, "SloRotar", 2 }, { 66, 19, "FstRotar", 2 }, { 0, 20, "ChrchOrg", 2 }, { 32, 20, "ChurOrg3", 2 }, { 35, 20, "ChurOrg2", 2 }, { 40, 20, "NotreDam", 2 }, { 64, 20, "OrgFlute", 2 }, { 65, 20, "TrmOrgFl", 2 }, { 0, 21, "ReedOrgn", 1 }, { 40, 21, "Puff Org", 2 }, { 0, 22, "Acordion", 2 }, { 32, 22, "AccordIt", 2 }, { 0, 23, "Harmnica", 1 }, { 32, 23, "Harmo 2", 2 }, { 0, 24, "TangoAcd", 2 }, { 64, 24, "TngoAcd2", 2 } }; // Guitar static XGNormalVoiceItem GuitarTab[] = { // bank prog name elem { 0, 25, "NylonGtr", 1 }, { 16, 25, "NylonGt2", 1 }, { 25, 25, "NylonGt3", 2 }, { 43, 25, "VelGtHrm", 2 }, { 96, 25, "Ukulele", 1 }, { 0, 26, "SteelGtr", 1 }, { 16, 26, "SteelGt2", 1 }, { 35, 26, "12StrGtr", 2 }, { 40, 26, "Nyln&Stl", 2 }, { 41, 26, "Stl&Body", 2 }, { 96, 26, "Mandolin", 2 }, { 0, 27, "Jazz Gtr", 1 }, { 18, 27, "MelloGtr", 1 }, { 32, 27, "JazzAmp", 2 }, { 0, 28, "CleanGtr", 1 }, { 32, 28, "ChorusGt", 2 }, { 0, 29, "Mute.Gtr", 1 }, { 40, 29, "FunkGtr1", 2 }, { 41, 29, "MuteStlG", 2 }, { 43, 29, "FunkGtr2", 2 }, { 45, 29, "Jazz Man", 1 }, { 0, 30, "Ovrdrive", 1 }, { 43, 30, "Gt.Pinch", 2 }, { 0, 31, "Dist.Gtr", 1 }, { 40, 31, "FeedbkGt", 2 }, { 41, 31, "FeedbGt2", 2 }, { 0, 32, "GtrHarmo", 1 }, { 65, 32, "GtFeedbk", 1 }, { 66, 32, "GtrHrmo2", 1 } }; // Bass static XGNormalVoiceItem BassTab[] = { // bank prog name elem { 0, 33, "Aco.Bass", 1 }, { 40, 33, "JazzRthm", 2 }, { 45, 33, "VXUprght", 2 }, { 0, 34, "FngrBass", 1 }, { 18, 34, "FingrDrk", 2 }, { 27, 34, "FlangeBa", 2 }, { 40, 34, "Ba&DstEG", 2 }, { 43, 34, "FngrSlap", 2 }, { 45, 34, "FngBass2", 2 }, { 65, 34, "ModAlem", 2 }, { 0, 35, "PickBass", 1 }, { 28, 35, "MutePkBa", 1 }, { 0, 36, "Fretless", 1 }, { 32, 36, "Fretles2", 2 }, { 33, 36, "Fretles3", 2 }, { 34, 36, "Fretles4", 2 }, { 96, 36, "SynFretl", 2 }, { 97, 36, "Smooth", 2 }, { 0, 37, "SlapBas1", 1 }, { 27, 37, "ResoSlap", 1 }, { 32, 37, "PunchThm", 2 }, { 0, 38, "SlapBas2", 1 }, { 43, 38, "VeloSlap", 2 }, { 0, 39, "SynBass1", 1 }, { 18, 39, "SynBa1Dk", 1 }, { 20, 39, "FastResB", 1 }, { 24, 39, "AcidBass", 1 }, { 35, 39, "Clv Bass", 2 }, { 40, 39, "TeknoBa", 2 }, { 64, 39, "Oscar", 2 }, { 65, 39, "SqrBass", 1 }, { 66, 39, "RubberBa", 2 }, { 96, 39, "Hammer", 2 }, { 0, 40, "SynBass2", 2 }, { 6, 40, "MelloSB1", 1 }, { 12, 40, "Seq Bass", 2 }, { 18, 40, "ClkSynBa", 2 }, { 19, 40, "SynBa2Dk", 1 }, { 32, 40, "SmthBa 2", 2 }, { 40, 40, "ModulrBa", 2 }, { 41, 40, "DX Bass", 2 }, { 64, 40, "X WireBa", 2 } }; // Strings static XGNormalVoiceItem StringsTab[] = { // bank prog name elem { 0, 41, "Violin", 1 }, { 8, 41, "SlowVln", 1 }, { 0, 42, "Viola", 1 }, { 0, 43, "Cello", 1 }, { 0, 44, "Contrabs", 1 }, { 0, 45, "Trem.Str", 1 }, { 8, 45, "SlowTrStr", 1 }, { 40, 45, "Susp Str", 2 }, { 0, 46, "Pizz.Str", 1 }, { 0, 47, "Harp", 1 }, { 40, 47, "YangChin", 2 }, { 0, 48, "Timpani", 1 } }; // Ensemble static XGNormalVoiceItem EnsembleTab[] = { // bank prog name elem { 0, 49, "Strings1", 1 }, { 3, 49, "S.Strngs", 2 }, { 8, 49, "SlowStr", 1 }, { 24, 49, "ArcoStr", 2 }, { 35, 49, "60sStrng", 2 }, { 40, 49, "Orchestr", 2 }, { 41, 49, "Orchstr2", 2 }, { 42, 49, "TremOrch", 2 }, { 45, 49, "VeloStr", 2 }, { 0, 50, "Strings2", 1 }, { 3, 50, "S.SlwStr", 2 }, { 8, 50, "LegatoSt", 2 }, { 40, 50, "Warm Str", 2 }, { 41, 50, "Kingdom", 2 }, { 64, 50, "70s Str", 1 }, { 65, 50, "Str Ens3", 1 }, { 0, 51, "Syn.Str1", 2 }, { 27, 51, "ResoStr", 2 }, { 64, 51, "Syn Str4", 2 }, { 65, 51, "SS Str", 2 }, { 0, 52, "Syn.Str2", 2 }, { 0, 53, "ChoirAah", 1 }, { 3, 53, "S.Choir", 2 }, { 16, 53, "Ch.Aahs2", 2 }, { 32, 53, "MelChoir", 2 }, { 40, 53, "ChoirStr", 2 }, { 0, 54, "VoiceOoh", 1 }, { 0, 55, "SynVoice", 1 }, { 40, 55, "SynVox2", 2 }, { 41, 55, "Choral", 2 }, { 64, 55, "AnaVoice", 1 }, { 0, 56, "Orch.Hit", 2 }, { 35, 56, "OrchHit2", 2 }, { 64, 56, "Impact", 2 } }; // Brass static XGNormalVoiceItem BrassTab[] = { // bank prog name elem { 0, 57, "Trumpet", 1 }, { 16, 57, "Trumpet2", 1 }, { 17, 57, "BriteTrp", 2 }, { 32, 57, "WarmTrp", 2 }, { 0, 58, "Trombone", 1 }, { 18, 58, "Trmbone2", 2 }, { 0, 59, "Tuba", 1 }, { 16, 59, "Tuba 2", 1 }, { 0, 60, "Mute.Trp", 1 }, { 0, 61, "Fr.Horn", 2 }, { 6, 61, "FrHrSolo", 2 }, { 32, 61, "FrHorn2", 1 }, { 37, 61, "HornOrch", 2 }, { 0, 62, "BrasSect", 1 }, { 35, 62, "Tp&TbSec", 2 }, { 40, 62, "BrssSec2", 2 }, { 41, 62, "HiBrass", 2 }, { 42, 62, "MelloBrs", 2 }, { 0, 63, "SynBras1", 2 }, { 12, 63, "QuackBr", 2 }, { 20, 63, "RezSynBr", 2 }, { 24, 63, "PolyBrss", 2 }, { 27, 63, "SynBras3", 2 }, { 32, 63, "JumpBrss", 2 }, { 45, 63, "AnaVelBr", 2 }, { 64, 63, "AnaBrss1", 2 }, { 0, 64, "SynBras2", 1 }, { 18, 64, "Soft Brs", 2 }, { 40, 64, "SynBras4", 2 }, { 41, 64, "ChorBrss", 2 }, { 45, 64, "VelBras2", 2 }, { 64, 64, "AnaBras2", 2 } }; // Reed static XGNormalVoiceItem ReedTab[] = { // bank prog name elem { 0, 65, "SprnoSax", 1 }, { 0, 66, "Alto Sax", 1 }, { 40, 66, "Sax Sect", 2 }, { 43, 66, "HyprAlto", 2 }, { 0, 67, "TenorSax", 1 }, { 40, 67, "BrthTnSx", 2 }, { 41, 67, "SoftTenr", 2 }, { 64, 67, "TnrSax 2", 1 }, { 0, 68, "Bari.Sax", 1 }, { 0, 69, "Oboe", 2 }, { 0, 70, "Eng.Horn", 1 }, { 0, 71, "Bassoon", 1 }, { 0, 72, "Clarinet", 1 } }; // Pipe static XGNormalVoiceItem PipeTab[] = { // bank prog name elem { 0, 73, "Piccolo", 1 }, { 0, 74, "Flute", 1 }, { 0, 75, "Recorder", 1 }, { 0, 76, "PanFlute", 1 }, { 0, 77, "Bottle", 2 }, { 0, 78, "Shakhchi", 2 }, { 0, 79, "Whistle", 1 }, { 0, 80, "Ocarina", 1 } }; // Synth Lead static XGNormalVoiceItem SynthLeadTab[] = { // bank prog name elem { 0, 81, "SquareLd", 2 }, { 6, 81, "Square 2", 1 }, { 8, 81, "LMSquare", 2 }, { 18, 81, "Hollow", 1 }, { 19, 81, "Shmoog", 2 }, { 64, 81, "Mellow", 2 }, { 65, 81, "SoloSine", 2 }, { 66, 81, "SineLead", 1 }, { 0, 82, "Saw.Lead", 2 }, { 6, 82, "Saw 2", 1 }, { 8, 82, "ThickSaw", 2 }, { 18, 82, "DynaSaw", 1 }, { 19, 82, "DigiSaw", 2 }, { 20, 82, "Big Lead", 2 }, { 24, 82, "HeavySyn", 2 }, { 25, 82, "WaspySyn", 2 }, { 40, 82, "PulseSaw", 2 }, { 41, 82, "Dr. Lead", 2 }, { 45, 82, "VeloLead", 2 }, { 96, 82, "Seq Ana", 2 }, { 0, 83, "CaliopLd", 2 }, { 65, 83, "Pure Pad", 2 }, { 0, 84, "Chiff Ld", 2 }, { 64, 84, "Rubby", 2 }, { 0, 85, "CharanLd", 2 }, { 64, 85, "DistLead", 2 }, { 65, 85, "WireLead", 2 }, { 0, 86, "Voice Ld", 2 }, { 24, 86, "SynthAah", 2 }, { 64, 86, "VoxLead", 2 }, { 0, 87, "Fifth Ld", 2 }, { 35, 87, "Big Five", 2 }, { 0, 88, "Bass &Ld", 2 }, { 16, 88, "Big&Low", 2 }, { 64, 88, "Fat&Prky", 2 }, { 65, 88, "SoftWurl", 2 } }; // Synth Pad static XGNormalVoiceItem SynthPadTab[] = { // bank prog name elem { 0, 89, "NewAgePd", 2 }, { 64, 89, "Fantasy2", 2 }, { 0, 90, "Warm Pad", 2 }, { 16, 90, "ThickPad", 2 }, { 17, 90, "Soft Pad", 2 }, { 18, 90, "SinePad", 2 }, { 64, 90, "Horn Pad", 2 }, { 65, 90, "RotarStr", 2 }, { 0, 91, "PolySyPd", 2 }, { 64, 91, "PolyPd80", 2 }, { 65, 91, "ClickPad", 2 }, { 66, 91, "Ana Pad", 2 }, { 67, 91, "SquarPad", 2 }, { 0, 92, "ChoirPad", 2 }, { 64, 92, "Heaven2", 2 }, { 66, 92, "Itopia", 2 }, { 67, 92, "CC Pad", 2 }, { 0, 93, "BowedPad", 2 }, { 64, 93, "Glacier", 2 }, { 65, 93, "GlassPad", 2 }, { 0, 94, "MetalPad", 2 }, { 64, 94, "Tine Pad", 2 }, { 65, 94, "Pan Pad", 2 }, { 0, 95, "Halo Pad", 2 }, { 0, 96, "SweepPad", 2 }, { 20, 96, "Shwimmer", 2 }, { 27, 96, "Converge", 2 }, { 64, 96, "PolarPad", 2 }, { 66, 96, "Celstial", 2 } }; // Synth Effects static XGNormalVoiceItem SynthEffectsTab[] = { // bank prog name elem { 0, 97, "Rain", 2 }, { 45, 97, "ClaviPad", 2 }, { 64, 97, "HrmoRain", 2 }, { 65, 97, "AfrcnWnd", 2 }, { 66, 97, "Caribean", 2 }, { 0, 98, "SoundTrk", 2 }, { 27, 98, "Prologue", 2 }, { 64, 98, "Ancestrl", 2 }, { 0, 99, "Crystal", 2 }, { 12, 99, "SynDrCmp", 2 }, { 14, 99, "Popcorn", 2 }, { 18, 99, "TinyBell", 2 }, { 35, 99, "RndGlock", 2 }, { 40, 99, "GlockChi", 2 }, { 41, 99, "ClearBel", 2 }, { 42, 99, "ChorBell", 2 }, { 64, 99, "SynMalet", 1 }, { 65, 99, "SftCryst", 2 }, { 66, 99, "LoudGlok", 2 }, { 67, 99, "XmasBell", 2 }, { 68, 99, "VibeBell", 2 }, { 69, 99, "DigiBell", 2 }, { 70, 99, "AirBells", 2 }, { 71, 99, "BellHarp", 2 }, { 72, 99, "Gamelmba", 2 }, { 0, 100, "Atmosphr", 2 }, { 18, 100, "WarmAtms", 2 }, { 19, 100, "HollwRls", 2 }, { 40, 100, "NylonEP", 2 }, { 64, 100, "NylnHarp", 2 }, { 65, 100, "Harp Vox", 2 }, { 66, 100, "AtmosPad", 2 }, { 67, 100, "Planet", 2 }, { 0, 101, "Bright", 2 }, { 64, 101, "FantaBel", 2 }, { 96, 101, "Smokey", 2 }, { 0, 102, "Goblins", 2 }, { 64, 102, "GobSyn", 2 }, { 65, 102, "50sSciFi", 2 }, { 66, 102, "Ring Pad", 2 }, { 67, 102, "Ritual", 2 }, { 68, 102, "ToHeaven", 2 }, { 70, 102, "Night", 2 }, { 71, 102, "Glisten", 2 }, { 96, 102, "BelChoir", 2 }, { 0, 103, "Echoes", 2 }, { 8, 103, "EchoPad2", 2 }, { 14, 103, "Echo Pan", 2 }, { 64, 103, "EchoBell", 2 }, { 65, 103, "Big Pan", 2 }, { 66, 103, "SynPiano", 2 }, { 67, 103, "Creation", 2 }, { 68, 103, "Stardust", 2 }, { 69, 103, "Reso Pan", 2 }, { 0, 104, "Sci-Fi", 2 }, { 64, 104, "Starz", 2 } }; // Ethnic static XGNormalVoiceItem EthnicTab[] = { // bank prog name elem { 0, 105, "Sitar", 1 }, { 32, 105, "DetSitar", 2 }, { 35, 105, "Sitar 2", 2 }, { 96, 105, "Tambra", 2 }, { 97, 105, "Tamboura", 2 }, { 0, 106, "Banjo", 1 }, { 28, 106, "MuteBnjo", 1 }, { 96, 106, "Rabab", 2 }, { 97, 106, "Gopichnt", 2 }, { 98, 106, "Oud", 2 }, { 0, 107, "Shamisen", 1 }, { 0, 108, "Koto", 1 }, { 96, 108, "T. Koto", 2 }, { 97, 108, "Kanoon", 2 }, { 0, 109, "Kalimba", 1 }, { 0, 110, "Bagpipe", 2 }, { 0, 111, "Fiddle", 1 }, { 0, 112, "Shanai", 1 }, { 64, 112, "Shanai2", 1 }, { 96, 112, "Pungi", 1 }, { 97, 112, "Hichriki", 2 } }; // Percussive static XGNormalVoiceItem PercussiveTab[] = { // bank prog name elem { 0, 113, "TnklBell", 2 }, { 96, 113, "Bonang", 2 }, { 97, 113, "Gender", 2 }, { 98, 113, "Gamelan", 2 }, { 99, 113, "S.Gamlan", 2 }, { 100, 113, "Rama Cym", 2 }, { 101, 113, "AsianBel", 2 }, { 0, 114, "Agogo", 2 }, { 0, 115, "SteelDrm", 2 }, { 97, 115, "GlasPerc", 2 }, { 98, 115, "ThaiBell", 2 }, { 0, 116, "WoodBlok", 1 }, { 96, 116, "Castanet", 1 }, { 0, 117, "TaikoDrm", 1 }, { 96, 117, "Gr.Cassa", 1 }, { 0, 118, "MelodTom", 2 }, { 64, 118, "Mel Tom2", 1 }, { 65, 118, "Real Tom", 2 }, { 66, 118, "Rock Tom", 2 }, { 0, 119, "Syn.Drum", 1 }, { 64, 119, "Ana Tom", 1 }, { 65, 119, "ElecPerc", 2 }, { 0, 120, "RevCymbl", 1 } }; // SoundEffects static XGNormalVoiceItem SoundEffectsTab[] = { // bank prog name elem { 0, 121, "FretNoiz", 2 }, { 0, 122, "BrthNoiz", 2 }, { 0, 123, "Seashore", 2 }, { 0, 124, "Tweet", 2 }, { 0, 125, "Telphone", 1 }, { 0, 126, "Helicptr", 1 }, { 0, 127, "Applause", 1 }, { 0, 128, "Gunshot", 1 } }; // SFX static XGNormalVoiceItem SFXTab[] = { // bank prog name elem { 8192, 1, "CuttngNz", 1 }, { 8192, 2, "CttngNz2", 2 }, { 8192, 4, "Str Slap", 1 }, { 8192, 17, "Fl.KClik", 1 }, { 8192, 33, "Rain", 1 }, { 8192, 34, "Thunder", 1 }, { 8192, 35, "Wind", 1 }, { 8192, 36, "Stream", 2 }, { 8192, 37, "Bubble", 2 }, { 8192, 38, "Feed", 2 }, { 8192, 49, "Dog", 1 }, { 8192, 50, "Horse", 1 }, { 8192, 51, "Bird 2", 1 }, { 8192, 55, "Ghost", 2 }, { 8192, 56, "Maou", 2 }, { 8192, 65, "Tel.Dial", 1 }, { 8192, 66, "DoorSqek", 1 }, { 8192, 67, "Door Slam", 1 }, { 8192, 68, "Scratch", 1 }, { 8192, 69, "Scratch 2", 2 }, { 8192, 70, "WindChm", 1 }, { 8192, 71, "Telphon2", 1 }, { 8192, 81, "CarEngin", 1 }, { 8192, 82, "Car Stop", 1 }, { 8192, 83, "Car Pass", 1 }, { 8192, 84, "CarCrash", 1 }, { 8192, 85, "Siren", 2 }, { 8192, 86, "Train", 1 }, { 8192, 87, "Jetplane", 2 }, { 8192, 88, "Starship", 2 }, { 8192, 89, "Burst", 2 }, { 8192, 90, "Coaster", 2 }, { 8192, 91, "SbMarine", 2 }, { 8192, 97, "Laughing", 1 }, { 8192, 98, "Scream", 1 }, { 8192, 99, "Punch", 1 }, { 8192, 100, "Heart", 1 }, { 8192, 101, "FootStep", 1 }, { 8192, 113, "MchinGun", 1 }, { 8192, 114, "LaserGun", 2 }, { 8192, 115, "Xplosion", 2 }, { 8192, 116, "FireWork", 2 } }; //--------------------------------------------------------------------- // XG Normal Voice Group List // typedef struct _XGNormalVoiceGroup { const char *name; XGNormalVoiceItem *items; unsigned short size; } XGNormalVoiceGroup; // Normal Voice Groups static XGNormalVoiceGroup InstrumentTab[] = { // name items size { "Piano", PianoTab, TSIZE(PianoTab) }, { "Organ", OrganTab, TSIZE(OrganTab) }, { "Guitar", GuitarTab, TSIZE(GuitarTab) }, { "Guitar", GuitarTab, TSIZE(GuitarTab) }, { "Bass", BassTab, TSIZE(BassTab) }, { "Strings", StringsTab, TSIZE(StringsTab) }, { "Ensemble", EnsembleTab, TSIZE(EnsembleTab) }, { "Brass", BrassTab, TSIZE(BrassTab) }, { "Reed", ReedTab, TSIZE(ReedTab) }, { "Pipe", PipeTab, TSIZE(PipeTab) }, { "Synth Lead", SynthLeadTab, TSIZE(SynthLeadTab) }, { "Synth Pad", SynthPadTab, TSIZE(SynthPadTab) }, { "Synth Effects", SynthEffectsTab, TSIZE(SynthEffectsTab) }, { "Ethnic", EthnicTab, TSIZE(EthnicTab) }, { "Percussive", PercussiveTab, TSIZE(PercussiveTab) }, { "Chromatic Percussion", ChromaticPercussionTab, TSIZE(ChromaticPercussionTab) }, { "Sound Effects", SoundEffectsTab, TSIZE(SoundEffectsTab) }, { "SFX", SFXTab, TSIZE(SFXTab) } }; //--------------------------------------------------------------------- // XG Drum Voice List // typedef struct _XGDrumVoiceItem { unsigned short note; const char *name; // Default values unsigned short level; unsigned short group; unsigned short pan; unsigned short reverb; unsigned short chorus; unsigned short noteOff; } XGDrumVoiceItem; // Standard Kit static XGDrumVoiceItem StandardKitTab[] = { // name level group pan reverb chorus noteOff { 13, "Surdo Mute", 102, 3, 51, 95, 95, 0 }, { 14, "Surdo Open", 121, 3, 51, 95, 95, 0 }, { 15, "Hi Q", 63, 0, 51, 127, 127, 0 }, { 16, "Whip Slap", 127, 0, 51, 127, 127, 0 }, { 17, "Scratch Push", 93, 4, 52, 63, 63, 0 }, { 18, "Scratch Pull", 116, 4, 52, 63, 63, 0 }, { 19, "Finger Snap", 127, 0, 64, 75, 0, 0 }, { 20, "Click Noise", 127, 0, 64, 127, 127, 0 }, { 21, "Metronome Click", 94, 0, 64, 63, 63, 0 }, { 22, "Metronome Bell", 98, 0, 64, 63, 63, 0 }, { 23, "Seq Click L", 92, 0, 64, 127, 127, 0 }, { 24, "Seq Click H", 119, 0, 64, 127, 127, 0 }, { 25, "Brush Tap", 49, 0, 64, 127, 127, 0 }, { 26, "Brush Swirl L", 47, 0, 64, 127, 127, 1 }, { 27, "Brush Slap", 52, 0, 64, 127, 127, 0 }, { 28, "Brush Swirl H", 45, 0, 64, 127, 127, 1 }, { 29, "Snare Roll", 79, 0, 64, 127, 127, 1 }, { 30, "Castanet", 127, 0, 64, 63, 63, 0 }, { 31, "Snare L", 75, 0, 64, 127, 127, 0 }, { 32, "Sticks", 127, 0, 64, 127, 127, 0 }, { 33, "Bass Drum L", 116, 0, 64, 32, 32, 0 }, { 34, "Open Rim Shot", 127, 0, 64, 127, 127, 0 }, { 35, "Bass Drum M", 102, 0, 64, 32, 32, 0 }, { 36, "Bass Drum H", 127, 0, 64, 32, 32, 0 }, { 37, "Side Stick", 93, 0, 64, 127, 127, 0 }, { 38, "Snare M", 127, 0, 64, 127, 127, 0 }, { 39, "Hand Clap", 110, 0, 64, 127, 127, 0 }, { 40, "Snare H", 123, 0, 64, 127, 127, 0 }, { 41, "Floor Tom L", 111, 0, 24, 127, 127, 0 }, { 42, "Hi-Hat Closed", 91, 1, 77, 32, 32, 0 }, { 43, "Floor Tom H", 113, 0, 39, 127, 127, 0 }, { 44, "Hi-Hat Pedal", 92, 1, 77, 32, 32, 0 }, { 45, "Low Tom", 99, 0, 52, 127, 127, 0 }, { 46, "Hi-Hat Open", 96, 1, 77, 32, 32, 0 }, { 47, "Mid Tom L", 87, 0, 64, 127, 127, 0 }, { 48, "Mid Tom H", 99, 0, 83, 127, 127, 0 }, { 49, "Crash Cymbal 1", 127, 0, 69, 127, 127, 0 }, { 50, "High Tom", 116, 0, 104, 127, 127, 0 }, { 51, "Ride Cymbal 1", 105, 0, 34, 127, 127, 0 }, { 52, "Chinese Cymbal", 120, 0, 34, 127, 127, 0 }, { 53, "Ride Cymbal Cup", 107, 0, 46, 127, 127, 0 }, { 54, "Tambourine", 116, 0, 64, 63, 63, 0 }, { 55, "Splash Cymbal", 127, 0, 64, 127, 127, 0 }, { 56, "Cowbell", 118, 0, 77, 63, 63, 0 }, { 57, "Crash Cymbal 2", 127, 0, 51, 127, 127, 0 }, { 58, "Vibraslap", 106, 0, 25, 127, 127, 0 }, { 59, "Ride Cymbal 2", 110, 0, 46, 127, 127, 0 }, { 60, "Bongo H", 110, 0, 110, 95, 95, 0 }, { 61, "Bongo L", 87, 0, 110, 95, 95, 0 }, { 62, "Conga H Mute", 73, 0, 39, 127, 127, 0 }, { 63, "Conga H Open", 89, 0, 25, 127, 127, 0 }, { 64, "Conga L", 111, 0, 64, 95, 95, 0 }, { 65, "Timbale H", 91, 0, 64, 127, 127, 0 }, { 66, "Timbale L", 95, 0, 64, 127, 127, 0 }, { 67, "Agogo H", 108, 0, 34, 100, 100, 0 }, { 68, "Agogo L", 108, 0, 34, 100, 100, 0 }, { 69, "Cabasa", 90, 0, 28, 63, 63, 0 }, { 70, "Maracas", 99, 0, 21, 63, 63, 0 }, { 71, "Samba Whistle H", 103, 0, 101, 127, 127, 1 }, { 72, "Samba Whistle L", 110, 0, 101, 127, 127, 1 }, { 73, "Guiro Short", 124, 0, 95, 63, 63, 0 }, { 74, "Guiro Long", 106, 0, 110, 63, 63, 1 }, { 75, "Claves", 88, 0, 64, 95, 95, 0 }, { 76, "Wood Block H", 107, 0, 104, 95, 95, 0 }, { 77, "Wood Block L", 96, 0, 104, 95, 95, 0 }, { 78, "Cuica Mute", 97, 0, 21, 127, 127, 0 }, { 79, "Cuica Open", 107, 0, 34, 127, 127, 0 }, { 80, "Triangle Mute", 127, 2, 25, 95, 95, 0 }, { 81, "Triangle Open", 127, 2, 25, 127, 127, 0 }, { 82, "Shaker", 106, 0, 83, 63, 63, 0 }, { 83, "Jingle Bell", 123, 0, 105, 127, 127, 0 }, { 84, "Bell Tree", 68, 0, 64, 127, 127, 0 } }; // Standard2 Kit static XGDrumVoiceItem Standard2KitTab[] = { // name level group pan reverb chorus noteOff { 29, "Snare Roll 2", 79, 0, 64, 127, 127, 1 }, { 31, "Snare L 2", 75, 0, 64, 127, 127, 0 }, { 34, "Open Rim Shot 2", 127, 0, 64, 127, 127, 0 }, { 35, "Bass Drum M 2", 102, 0, 64, 32, 32, 0 }, { 36, "Bass Drum H 2", 127, 0, 64, 32, 32, 0 }, { 38, "Snare M 2", 127, 0, 64, 127, 127, 0 }, { 40, "Snare H 2", 123, 0, 64, 127, 127, 0 } }; // Room Kit static XGDrumVoiceItem RoomKitTab[] = { // name level group pan reverb chorus noteOff { 38, "SD Room L", 127, 0, 64, 127, 127, 0 }, { 40, "SD Room H", 123, 0, 64, 127, 127, 0 }, { 41, "Room Tom 1", 123, 0, 24, 127, 127, 0 }, { 43, "Room Tom 2", 127, 0, 39, 127, 127, 0 }, { 45, "Room Tom 3", 117, 0, 52, 127, 127, 0 }, { 47, "Room Tom 4", 121, 0, 64, 127, 127, 0 }, { 48, "Room Tom 5", 123, 0, 83, 127, 127, 0 }, { 50, "Room Tom 6", 124, 0, 95, 127, 127, 0 } }; // Rock Kit static XGDrumVoiceItem RockKitTab[] = { // name level group pan reverb chorus noteOff { 31, "SD Rock M", 121, 0, 64, 127, 127, 0 }, { 33, "Bass Drum M", 111, 0, 64, 32, 32, 0 }, { 34, "Open Rim Shot 2", 127, 0, 64, 127, 127, 0 }, { 35, "Bass Drum H 3", 127, 0, 64, 32, 32, 0 }, { 36, "BD Rock", 119, 0, 64, 32, 32, 0 }, { 38, "SD Rock", 110, 0, 64, 127, 127, 0 }, { 40, "SD Rock Rim", 119, 0, 64, 127, 127, 0 }, { 41, "Rock Tom 1", 123, 0, 24, 127, 127, 0 }, { 43, "Rock Tom 2", 127, 0, 39, 127, 127, 0 }, { 45, "Rock Tom 3", 117, 0, 52, 127, 127, 0 }, { 47, "Rock Tom 4", 121, 0, 64, 127, 127, 0 }, { 48, "Rock Tom 5", 123, 0, 83, 127, 127, 0 }, { 50, "Rock Tom 6", 124, 0, 95, 127, 127, 0 } }; // Electro Kit static XGDrumVoiceItem ElectroKitTab[] = { // name level group pan reverb chorus noteOff { 28, "Reverse Cymbal", 100, 0, 64, 127, 127, 1 }, { 30, "Hi Q", 127, 0, 64, 63, 63, 0 }, { 31, "Snare M", 114, 0, 64, 127, 127, 0 }, { 33, "Bass Drum H 4", 123, 0, 64, 32, 32, 0 }, { 35, "BD Rock", 127, 0, 64, 32, 32, 0 }, { 36, "BD Gate", 127, 0, 64, 32, 32, 0 }, { 38, "SD Rock L", 107, 0, 64, 127, 127, 0 }, { 40, "SD Rock H", 102, 0, 64, 127, 127, 0 }, { 41, "E Tom 1", 92, 0, 24, 127, 127, 0 }, { 43, "E Tom 2", 94, 0, 39, 127, 127, 0 }, { 45, "E Tom 3", 97, 0, 52, 127, 127, 0 }, { 47, "E Tom 4", 93, 0, 64, 127, 127, 0 }, { 48, "E Tom 5", 102, 0, 83, 127, 127, 0 }, { 50, "E Tom 6", 97, 0, 101, 127, 127, 0 }, { 78, "Scratch Push", 89, 4, 21, 127, 127, 0 }, { 79, "Scratch Pull", 94, 4, 34, 127, 127, 0 } }; // Analog Kit static XGDrumVoiceItem AnalogKitTab[] = { // name level group pan reverb chorus noteOff { 28, "Reverse Cymbal", 100, 0, 64, 127, 127, 1 }, { 30, "Hi Q", 127, 0, 64, 63, 63, 0 }, { 31, "SD Rock H", 114, 0, 64, 127, 127, 0 }, { 33, "Bass Drum M", 111, 0, 64, 32, 32, 0 }, { 35, "BD Analog L", 123, 0, 64, 32, 32, 0 }, { 36, "BD Analog H", 127, 0, 64, 32, 32, 0 }, { 37, "Analog Side Stick", 116, 0, 64, 127, 127, 0 }, { 38, "Analog Snare L", 107, 0, 64, 127, 127, 0 }, { 40, "Analog Snare H", 102, 0, 64, 127, 127, 0 }, { 41, "Analog Tom 1", 127, 0, 24, 127, 127, 0 }, { 42, "Analog HH Closed 1", 108, 1, 77, 32, 32, 0 }, { 43, "Analog Tom 2", 112, 0, 39, 127, 127, 0 }, { 44, "Analog HH Closed 2", 91, 1, 77, 32, 32, 0 }, { 45, "Analog Tom 3", 108, 0, 52, 127, 127, 0 }, { 46, "Analog HH Open", 96, 1, 77, 32, 32, 0 }, { 47, "Analog Tom 4", 112, 0, 64, 127, 127, 0 }, { 48, "Analog Tom 5", 109, 0, 83, 127, 127, 0 }, { 49, "Analog Cymbal", 109, 0, 69, 127, 127, 0 }, { 50, "Analog Tom 6", 109, 0, 101, 127, 127, 0 }, { 56, "Analog Cowbell", 118, 0, 77, 63, 63, 0 }, { 62, "Analog Conga H", 89, 0, 39, 127, 127, 0 }, { 63, "Analog Conga M", 89, 0, 25, 127, 127, 0 }, { 64, "Analog Conga L", 115, 0, 64, 95, 95, 0 }, { 70, "Analog Maracas", 96, 0, 21, 63, 63, 0 }, { 75, "Analog Claves", 88, 0, 64, 95, 95, 0 }, { 78, "Scratch Push", 89, 4, 21, 127, 127, 0 }, { 79, "Scratch Pull", 94, 4, 34, 127, 127, 0 } }; // Jazz Kit static XGDrumVoiceItem JazzKitTab[] = { // name level group pan reverb chorus noteOff { 36, "BD Jazz", 120, 0, 64, 32, 32, 0 }, { 41, "Jazz Tom 1", 113, 0, 24, 127, 127, 0 }, { 43, "Jazz Tom 2", 122, 0, 39, 127, 127, 0 }, { 45, "Jazz Tom 3", 112, 0, 52, 127, 127, 0 }, { 47, "Jazz Tom 4", 127, 0, 64, 127, 127, 0 }, { 48, "Jazz Tom 5", 110, 0, 83, 127, 127, 0 }, { 50, "Jazz Tom 6", 116, 0, 104, 127, 127, 0 } }; // Brush Kit static XGDrumVoiceItem BrushKitTab[] = { // name level group pan reverb chorus noteOff { 31, "Brush Slap L", 85, 0, 64, 127, 127, 0 }, { 36, "BD Soft", 117, 0, 64, 32, 32, 0 }, { 38, "Brush Slap M", 84, 0, 64, 127, 127, 0 }, { 40, "Brush Tap H", 74, 0, 64, 127, 127, 0 }, { 41, "Brush Tom 1", 127, 0, 24, 127, 127, 0 }, { 43, "Brush Tom 2", 127, 0, 39, 127, 127, 0 }, { 45, "Brush Tom 3", 127, 0, 52, 127, 127, 0 }, { 47, "Brush Tom 4", 127, 0, 64, 127, 127, 0 }, { 48, "Brush Tom 5", 120, 0, 83, 127, 127, 0 }, { 50, "Brush Tom 6", 122, 0, 104, 127, 127, 0 } }; // Classic Kit static XGDrumVoiceItem ClassicKitTab[] = { // name level group pan reverb chorus noteOff { 33, "Bass Drum L2", 116, 0, 64, 32, 32, 0 }, { 35, "Gran Cassa", 127, 0, 64, 32, 32, 0 }, { 36, "Gran Cassa Mute", 127, 0, 64, 32, 32, 0 }, { 38, "Marching Sn M", 79, 0, 64, 127, 127, 0 }, { 40, "Marching Sn H", 79, 0, 64, 127, 127, 0 }, { 41, "Jazz Tom 1", 113, 0, 24, 127, 127, 0 }, { 43, "Jazz Tom 2", 122, 0, 39, 127, 127, 0 }, { 45, "Jazz Tom 3", 112, 0, 52, 127, 127, 0 }, { 47, "Jazz Tom 4", 127, 0, 64, 127, 127, 0 }, { 48, "Jazz Tom 5", 110, 0, 83, 127, 127, 0 }, { 49, "Hand Cym Open L", 123, 0, 64, 127, 127, 0 }, { 50, "Jazz Tom 6", 116, 0, 104, 127, 127, 0 }, { 51, "Hand Cym.Closed L", 124, 0, 34, 127, 127, 0 }, { 57, "Hand Cym.Open H", 127, 0, 51, 127, 127, 0 }, { 59, "Hand Cym.Closed H", 106, 0, 46, 127, 127, 0 } }; // SFX1 static XGDrumVoiceItem SFX1Tab[] = { // name level group pan reverb chorus noteOff { 36, "Guitar Cutting Noise", 127, 0, 64, 127, 127, 1 }, { 37, "Guitar Cutting Noise 2",127, 0, 64, 127, 127, 1 }, { 39, "String Slap", 127, 0, 64, 127, 127, 1 }, { 52, "FL.Key Click", 127, 0, 64, 127, 127, 1 }, { 68, "Rain", 127, 0, 64, 127, 127, 1 }, { 69, "Thunder", 127, 0, 64, 127, 127, 1 }, { 70, "Wind", 127, 0, 64, 127, 127, 1 }, { 71, "Stream", 127, 0, 64, 127, 127, 1 }, { 72, "Bubble", 127, 0, 64, 127, 127, 1 }, { 73, "Feed", 127, 0, 64, 127, 127, 1 }, { 84, "Dog", 127, 0, 64, 127, 127, 1 }, { 85, "Horse Gallop", 127, 0, 64, 127, 127, 1 }, { 86, "Bird 2", 127, 0, 64, 127, 127, 1 }, { 90, "Ghost", 127, 0, 64, 127, 127, 1 }, { 91, "Maou", 127, 0, 64, 127, 127, 1 } }; // SFX2 static XGDrumVoiceItem SFX2Tab[] = { // name level group pan reverb chorus noteOff { 36, "Dial Tone", 127, 0, 64, 127, 127, 1 }, { 37, "Door Creaking", 127, 0, 64, 127, 127, 1 }, { 38, "Door Slam", 127, 0, 64, 127, 127, 1 }, { 39, "Scratch", 127, 0, 64, 127, 127, 1 }, { 40, "Scratch 2", 127, 0, 64, 127, 127, 1 }, { 41, "Windchime", 127, 0, 64, 127, 127, 1 }, { 42, "Telephone Ring2", 127, 0, 64, 127, 127, 1 }, { 52, "Engine Start", 127, 0, 64, 127, 127, 1 }, { 53, "Tire Screech", 127, 0, 64, 127, 127, 1 }, { 54, "Car Passing", 127, 0, 64, 127, 127, 1 }, { 55, "Crash", 127, 0, 64, 127, 127, 1 }, { 56, "Siren", 127, 0, 64, 127, 127, 1 }, { 57, "Train", 127, 0, 64, 127, 127, 1 }, { 58, "Jetplane", 127, 0, 64, 127, 127, 1 }, { 59, "Starship", 127, 0, 64, 127, 127, 1 }, { 60, "Burst Noise", 127, 0, 64, 127, 127, 1 }, { 61, "Coaster", 127, 0, 64, 127, 127, 1 }, { 62, "SbMarine", 127, 0, 64, 127, 127, 1 }, { 68, "Laughing", 127, 0, 64, 127, 127, 1 }, { 69, "Screaming", 127, 0, 64, 127, 127, 1 }, { 70, "Punch", 127, 0, 64, 127, 127, 1 }, { 71, "Heartbeat", 127, 0, 64, 127, 127, 1 }, { 72, "Footsteps", 127, 0, 64, 127, 127, 1 }, { 84, "Machine Gun", 127, 0, 64, 127, 127, 1 }, { 85, "Laser Gun", 127, 0, 64, 127, 127, 1 }, { 86, "Explosion", 127, 0, 64, 127, 127, 1 }, { 87, "FireWork", 127, 0, 64, 127, 127, 1 } }; //--------------------------------------------------------------------- // XG Drum Kit List // typedef struct _XGDrumKitItem { unsigned short bank; unsigned short prog; const char *name; XGDrumVoiceItem *keys; unsigned short size; } XGDrumKitItem; static XGDrumKitItem DrumKitTab[] = { // bank prog name keys size { 16256, 1, "Standard Kit", StandardKitTab, TSIZE(StandardKitTab) }, { 16256, 2, "Standard2 Kit", Standard2KitTab, TSIZE(Standard2KitTab) }, { 16256, 9, "Room Kit", RoomKitTab, TSIZE(RoomKitTab) }, { 16256, 17, "Rock Kit", RockKitTab, TSIZE(RockKitTab) }, { 16256, 25, "Electro Kit", ElectroKitTab, TSIZE(ElectroKitTab)}, { 16256, 26, "Analog Kit", AnalogKitTab, TSIZE(AnalogKitTab) }, { 16256, 33, "Jazz Kit", JazzKitTab, TSIZE(JazzKitTab) }, { 16256, 41, "Brush Kit", BrushKitTab, TSIZE(BrushKitTab) }, { 16256, 49, "Classic Kit", ClassicKitTab, TSIZE(ClassicKitTab)}, { 16128, 1, "SFX 1", SFX1Tab, TSIZE(SFX1Tab) }, { 16128, 2, "SFX 2", SFX2Tab, TSIZE(SFX2Tab) } }; //------------------------------------------------------------------------- // XG Effect table helpers. // typedef struct _XGEffectParamItem { unsigned short id; // parameter index const char *name; // parameter name. unsigned short min; // minimum value. unsigned short max; // maximum value. float (*getv)(unsigned short); // convert to display value. unsigned short (*getu)(float); // invert to native value. const char * (*gets)(unsigned short); // enumerated string value. const char * (*unit)(); // unit suffix label. } XGEffectParamItem; typedef struct _XGEffectItem { unsigned char msb; // effect type MSB unsigned char lsb; // effect type LSB const char *name; // effect type name XGEffectParamItem *params; // effect type parameters unsigned short *defs; // effect type defaults } XGEffectItem; //------------------------------------------------------------------------- // XG Effect Parameter List // // HALL1,2, ROOM1,2,3, STAGE1,2, PLATE static XGEffectParamItem HALLROOMParamTab[] = { // id name min max getv getu gets unit { 0, "[Reverb ]Time", 0, 69, getvtab4, getutab4, nullptr, unit_ms }, { 1, "Diffusion", 0, 10, nullptr, nullptr, nullptr, nullptr }, { 2, "[Initial ]Delay", 0, 63, getvtab5, getutab5, nullptr, unit_ms }, { 3, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 4, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 5, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 6, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Rev Delay", 0, 63, getvtab5, getutab5, nullptr, unit_ms }, { 11, "Density", 0, 4, nullptr, nullptr, nullptr, nullptr }, { 12, "[Rev/Er ]Balance", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 13, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 14, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // WHITE ROOM, TUNNEL, CANYON, BASEMENT static XGEffectParamItem WHITEROOMParamTab[] = { // id name min max getv getu gets unit { 0, "[Reverb ]Time", 0, 69, getvtab4, getutab4, nullptr, unit_ms }, { 1, "Diffusion", 0, 10, nullptr, nullptr, nullptr, nullptr }, { 2, "[Initial ]Delay", 0, 63, getvtab5, getutab5, nullptr, unit_ms }, { 3, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 4, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 5, "Width", 0, 37, getvtab8 ,getutab8, nullptr, unit_m }, { 6, "Height", 0, 73, getvtab8 ,getutab8, nullptr, unit_m }, { 7, "Depth", 0, 104, getvtab8 ,getutab8, nullptr, unit_m }, { 8, "Wall Vary", 0, 30, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Rev Delay", 0, 63, getvtab5, getutab5, nullptr, unit_ms }, { 11, "Density", 0, 4, nullptr, nullptr, nullptr, nullptr }, { 12, "[Rev/Er ]Balance", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 13, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 14, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // DELAY L,C,R static XGEffectParamItem DELAYLCRParamTab[] = { // id name min max getv getu gets unit { 0, "L[ch] Delay", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 1, "R[ch] Delay", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 2, "C[ch] Delay", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 3, "[Feedback ]Delay", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 4, "[Feedback ]Level", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 5, "C[ch] Level", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 6, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 12, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 13, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 14, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 15, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB } }; // DELAY L,R static XGEffectParamItem DELAYLRParamTab[] = { // id name min max getv getu gets unit { 0, "L[ch ]Delay", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 1, "R[ch ]Delay", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 2, "[Feedback ]Delay 1", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 3, "[Feedback ]Delay 2", 1,7550, getv0_10, getu0_10, nullptr, unit_ms }, { 4, "[Feedback ]Level", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 5, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 6, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 12, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 13, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 14, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 15, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB } }; // ECHO static XGEffectParamItem ECHOParamTab[] = { // id name min max getv getu gets unit { 0, "L[ch] Delay 1", 1,3550, getv0_10, getu0_10, nullptr, unit_ms }, { 1, "L[ch] Feedb[ack Level]",0,127,getv0x40,getu0x40, nullptr, nullptr }, { 2, "R[ch] Delay 1", 1,3550, getv0_10, getu0_10, nullptr, unit_ms }, { 3, "R[ch] Feedb[ack Level]",1,127,getv0x40,getu0x40, nullptr, nullptr }, { 4, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 5, "L[ch] Delay 2", 1,3550, getv0_10, getu0_10, nullptr, unit_ms }, { 6, "R[ch] Delay 2", 1,3550, getv0_10, getu0_10, nullptr, unit_ms }, { 7, "Delay 2[ Level]", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 12, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 13, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 14, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 15, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB } }; // CROSS DELAY static XGEffectParamItem CROSSDELAYParamTab[] = { // id name min max getv getu gets unit { 0, "L->R Delay", 1,3550, getv0_10, getu0_10, nullptr, unit_ms }, { 1, "R->L Delay", 1,3550, getv0_10, getu0_10, nullptr, unit_ms }, { 2, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 3, "Input[ Select]", 0, 2, nullptr, nullptr, getsisel, nullptr }, { 4, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 5, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 6, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 12, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 13, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 14, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 15, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB } }; // EARLY REF1,2 static XGEffectParamItem EARLYREFParamTab[] = { // id name min max getv getu gets unit { 0, "Type", 0, 5, nullptr, nullptr, getsreft, nullptr }, { 1, "Room[ Size]", 0, 44, getvtab6, getutab6, nullptr, unit_m }, { 2, "Diffusion", 0, 10, nullptr, nullptr, nullptr, nullptr }, { 3, "[Initial ]Delay", 0, 63, getvtab5, getutab5, nullptr, unit_ms }, { 4, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 5, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Liveness", 0, 10, nullptr, nullptr, nullptr, nullptr }, { 11, "Density", 0, 3, nullptr, nullptr, nullptr, nullptr }, { 12, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, }; // GATE REVERB, REVERSE GATE static XGEffectParamItem GATEREVERBParamTab[] = { // id name min max getv getu gets unit { 0, "Type", 0, 1, nullptr, nullptr, getsrevt, nullptr }, { 1, "Room[ Size]", 0, 44, getvtab6, getutab6, nullptr, unit_m }, { 2, "Diffusion", 0, 10, nullptr, nullptr, nullptr, nullptr }, { 3, "[Initial ]Delay", 0, 63, getvtab5, getutab5, nullptr, unit_ms }, { 4, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 5, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Liveness", 0, 10, nullptr, nullptr, nullptr, nullptr }, { 11, "Density", 1, 3, nullptr, nullptr, nullptr, nullptr }, { 12, "[High ]Damp", 1, 10, getv0_10, getu0_10, nullptr, unit_ms }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // KARAOKE1,2,3 static XGEffectParamItem KARAOKEParamTab[] = { // id name min max getv getu gets unit { 0, "Delay[ Time]", 0, 127, getvtab7, getutab7, nullptr, unit_ms }, { 1, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 2, "HPF[ Cutoff Thru]", 0, 52, getvtab3, getutab3, nullptr, unit_Hz }, { 3, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 6, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 11, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 12, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // CHORUS1,2,3,4 CELESTE1,2,3,4 static XGEffectParamItem CHORUSParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "LFO PM[ Depth]", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 3, "Delay[ Offset]", 0, 127, getvtab2, getutab2, nullptr, unit_ms }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, "LFO AM[ Depth]", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 14, "Input[ Mode]", 0, 1, nullptr, nullptr, getsimod, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // FLANGER1,2,3 static XGEffectParamItem FLANGERParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "LFO Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 3, "Delay[ Offset]", 0, 63, getvtab2, getutab2, nullptr, unit_ms }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, nullptr }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, "LFO Phase[ Diff]", 4, 124, getv_180, getu_180, nullptr, unit_deg }, { 14, "Input[ Mode]", 0, 1, nullptr, nullptr, getsimod, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // SYMPHONIC static XGEffectParamItem SYMPHONICParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "LFO Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "Delay[ Offset]", 0, 0, getvtab2, getutab2, nullptr, unit_ms }, { 3, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ 9Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, "Dry/Wet", 1, 127, nullptr, nullptr, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // ROTARY SPEAKER static XGEffectParamItem ROTSPEAKERParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "LFO Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 3, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, "Dry/Wet", 1, 127, nullptr, nullptr, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // TREMOLO static XGEffectParamItem TREMOLOParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "AM Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "PM Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 3, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, "LFO Phase[ Diff]", 4, 124, getv_180, getu_180, nullptr, unit_deg }, { 14, "Input[ Mode]", 0, 1, nullptr, nullptr, getsimod, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // AUTO PAN static XGEffectParamItem AUTOPANParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "L/R Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "F/R Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 3, "[Pan ]Direction", 0, 5, nullptr, nullptr, getspand, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // PHASER1,2 static XGEffectParamItem PHASERParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "LFO Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "Phase[ Shift Offset]",0,127, nullptr, nullptr, nullptr, nullptr }, { 3, "Feedback[ Level]", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, "Dry/Wet", 1, 127, nullptr, nullptr, nullptr, nullptr }, { 10, "Stage", 1, 10, nullptr, nullptr, nullptr, nullptr }, { 11, "Diffusion", 0, 1, nullptr, nullptr, getsimod, nullptr }, { 12, "LFO Phase[ Diff]", 4, 124, getv_180, getu_180, nullptr, unit_deg }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // DISTORTION, OVERDRIVE static XGEffectParamItem DISTORTIONParamTab[] = { // id name min max getv getu gets unit { 0, "Drive", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 1, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 2, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 3, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 4, "Output[ Level]", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 5, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 6, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 7, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 8, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Edge[ (Clip Curve)]",0, 127, nullptr, nullptr, nullptr, nullptr }, { 11, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 12, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // GUITAR AMP SIMULATOR static XGEffectParamItem AMPSIMULParamTab[] = { // id name min max getv getu gets unit { 0, "Drive", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 1, "AMP[ Type]", 0, 3, nullptr, nullptr, getsampt, nullptr }, { 2, "LPF[ Cutoff]", 34, 60, getvtab3, getutab3, nullptr, unit_Hz }, { 3, "Output[ Level]", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 6, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Edge[ (Clip Curve)]",0, 127, nullptr, nullptr, nullptr, nullptr }, { 11, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 12, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // 3-BAND EQ (MONO) static XGEffectParamItem MONOEQParamTab[] = { // id name min max getv getu gets unit { 0, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 1, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 2, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 3, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 4, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 5, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 10, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 11, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 12, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // 2-BAND EQ (STEREO) static XGEffectParamItem STEREOEQParamTab[] = { // id name min max getv getu gets unit { 0, "[EQ ]Low Freq", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 1, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 2, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 3, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 6, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 7, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 8, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 9, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 10, "[EQ ]Mid Freq", 14, 54, getvtab3, getutab3, nullptr, unit_Hz }, { 11, "[EQ ]Mid Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 12, "[EQ ]Mid Width", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; // AUTO WAH (LFO) static XGEffectParamItem AUTOWAHParamTab[] = { // id name min max getv getu gets unit { 0, "LFO Freq", 0, 127, getvtab1, getutab1, nullptr, unit_Hz }, { 1, "LFO Depth", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 2, "[Cutoff Freq ]Offset",0,127, nullptr, nullptr, nullptr, nullptr }, { 3, "Resonance", 10, 120, nullptr, nullptr, nullptr, nullptr }, { 4, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 5, "[EQ ]Low Frequ", 4, 40, getvtab3, getutab3, nullptr, unit_Hz }, { 6, "[EQ ]Low Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 7, "[EQ ]High Freq", 28, 58, getvtab3, getutab3, nullptr, unit_Hz }, { 8, "[EQ ]High Gain", 52, 76, getv0x40, getu0x40, nullptr, unit_dB }, { 9, "Dry/Wet", 1, 127, getv0x40, getu0x40, nullptr, nullptr }, { 10, "Drive", 0, 127, nullptr, nullptr, nullptr, nullptr }, { 11, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 12, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 13, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 14, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr }, { 15, nullptr, 0, 0, nullptr, nullptr, nullptr, nullptr } }; //------------------------------------------------------------------------- // XG Effect Default Parameter Data // REVERB static unsigned short REVERBDefaultTab[][16] = { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // NO EFFECT { 18, 10, 8, 13, 49, 0, 0, 0, 0, 40, 0, 4, 50, 8, 64, 0 }, // HALL 1 { 25, 10, 28, 6, 46, 0, 0, 0, 0, 40, 13, 3, 74, 7, 64, 0 }, // HALL 2 { 5, 10, 16, 4, 49, 0, 0, 0, 0, 40, 5, 3, 64, 8, 64, 0 }, // ROOM 1 { 12, 10, 5, 4, 38, 0, 0, 0, 0, 40, 0, 4, 50, 8, 64, 0 }, // ROOM 2 { 9, 10, 47, 5, 36, 0, 0, 0, 0, 40, 0, 4, 60, 8, 64, 0 }, // ROOM 3 { 19, 10, 16, 7, 54, 0, 0, 0, 0, 40, 0, 3, 64, 6, 64, 0 }, // STAGE 1 { 11, 10, 16, 7, 51, 0, 0, 0, 0, 40, 2, 2, 64, 6, 64, 0 }, // STAGE 2 { 25, 10, 6, 8, 49, 0, 0, 0, 0, 40, 2, 3, 64, 5, 64, 0 }, // PLATE { 9, 5, 11, 0, 46, 30, 50, 70, 7, 40, 34, 4, 64, 7, 64, 0 }, // WHITE ROOM { 48, 6, 19, 0, 44, 33, 52, 70, 16, 40, 20, 4, 64, 7, 64, 0 }, // TUNNEL { 3, 6, 3, 0, 34, 26, 29, 59, 15, 40, 32, 4, 64, 8, 64, 0 } // BASEMENT }; // CHORUS static unsigned short CHORUSDefaultTab[][16] = { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // NO EFFECT { 6, 54, 77, 106, 0, 28, 64, 46, 64, 64, 46, 64, 10, 0, 0, 0 }, // CHORUS 1 { 8, 63, 64, 30, 0, 28, 62, 42, 58, 64, 46, 64, 10, 0, 0, 0 }, // CHORUS 2 { 4, 44, 64, 110, 0, 28, 64, 46, 66, 64, 46, 64, 10, 0, 0, 0 }, // CHORUS 3 { 9, 32, 69, 104, 0, 28, 64, 46, 64, 64, 46, 64, 10, 0, 1, 0 }, // CHORUS 4 { 12, 32, 64, 0, 0, 28, 64, 46, 64, 127, 40, 68, 10, 0, 0, 0 }, // CELESTE 1 { 28, 18, 90, 2, 0, 28, 62, 42, 60, 84, 40, 68, 10, 0, 0, 0 }, // CELESTE 2 { 4, 63, 44, 2, 0, 28, 64, 46, 68, 127, 40, 68, 10, 0, 0, 0 }, // CELESTE 3 { 8, 29, 64, 0, 0, 28, 64, 51, 66, 127, 40, 68, 10, 0, 1, 0 }, // CELESTE 4 { 14, 14, 104, 2, 0, 28, 64, 46, 64, 96, 40, 64, 10, 4, 0, 0 }, // FLANGER 1 { 32, 17, 26, 2, 0, 28, 64, 46, 60, 96, 40, 64, 10, 4, 0, 0 }, // FLANGER 2 { 4, 109, 109, 2, 0, 28, 64, 46, 64, 127, 40, 64, 10, 4, 0, 0 } // FLANGER 3 }; // VARIANTION static unsigned short VARIATIONDefaultTab[][16] = { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // NO EFFECT { 18, 10, 8, 13, 49, 0, 0, 0, 0, 40, 0, 4, 50, 8, 64, 0 }, // HALL 1 { 25, 10, 28, 6, 46, 0, 0, 0, 0, 40, 13, 3, 74, 7, 64, 0 }, // HALL 2 { 5, 10, 16, 4, 49, 0, 0, 0, 0, 40, 5, 3, 64, 8, 64, 0 }, // ROOM 1 { 12, 10, 5, 4, 38, 0, 0, 0, 0, 40, 0, 4, 50, 8, 64, 0 }, // ROOM 2 { 9, 10, 47, 5, 36, 0, 0, 0, 0, 40, 0, 4, 60, 8, 64, 0 }, // ROOM 3 { 19, 10, 16, 7, 54, 0, 0, 0, 0, 40, 0, 3, 64, 6, 64, 0 }, // STAGE 1 { 11, 10, 16, 7, 51, 0, 0, 0, 0, 40, 2, 2, 64, 6, 64, 0 }, // STAGE 2 { 25, 10, 6, 8, 49, 0, 0, 0, 0, 40, 2, 3, 64, 5, 64, 0 }, // PLATE {3333,1667,5000,5000, 74, 100, 10, 0, 0, 32, 0, 60, 28, 64, 46, 64 }, // DELAY L,C,R {2500,3750,3752,3750, 87, 10, 0, 0, 0, 32, 0, 60, 28, 64, 46, 64 }, // DELAY L,R {1700, 80,1780, 80, 10,1700,1780, 0, 0, 40, 0, 60, 28, 64, 46, 64 }, // ECHO {1700,1750, 111, 1, 10, 0, 0, 0, 0, 32, 0, 60, 28, 64, 46, 64 }, // CROSS DELAY { 0, 19, 5, 16, 64, 0, 46, 0, 0, 32, 5, 0, 10, 0, 0, 0 }, // EARLY REF 1 { 2, 7, 10, 16, 64, 3, 46, 0, 0, 32, 5, 2, 10, 0, 0, 0 }, // EARLY REF 2 { 0, 15, 6, 2, 64, 0, 44, 0, 0, 32, 4, 3, 10, 0, 0, 0 }, // GATE REVERB { 1, 19, 8, 3, 64, 0, 47, 0, 0, 32, 6, 3, 10, 0, 0, 0 }, // REVERSE GATE { 63, 97, 0, 48, 0, 0, 0, 0, 0, 64, 2, 0, 0, 0, 0, 0 }, // KARAOKE 1 { 55, 105, 0, 50, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0 }, // KARAOKE 2 { 43, 110, 14, 53, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0 }, // KARAOKE 3 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // THRU { 6, 54, 77, 106, 0, 28, 64, 46, 64, 64, 46, 64, 10, 0, 0, 0 }, // CHORUS 1 { 8, 63, 64, 30, 0, 28, 62, 42, 58, 64, 46, 64, 10, 0, 0, 0 }, // CHORUS 2 { 4, 44, 64, 110, 0, 28, 64, 46, 66, 64, 46, 64, 10, 0, 0, 0 }, // CHORUS 3 { 9, 32, 69, 104, 0, 28, 64, 46, 64, 64, 46, 64, 10, 0, 1, 0 }, // CHORUS 4 { 12, 32, 64, 0, 0, 28, 64, 46, 64, 127, 40, 68, 10, 0, 0, 0 }, // CELESTE 1 { 28, 18, 90, 2, 0, 28, 62, 42, 60, 84, 40, 68, 10, 0, 0, 0 }, // CELESTE 2 { 4, 63, 44, 2, 0, 28, 64, 46, 68, 127, 40, 68, 10, 0, 0, 0 }, // CELESTE 3 { 8, 29, 64, 0, 0, 28, 64, 51, 66, 127, 40, 68, 10, 0, 1, 0 }, // CELESTE 4 { 14, 14, 104, 2, 0, 28, 64, 46, 64, 96, 40, 64, 10, 4, 0, 0 }, // FLANGER 1 { 32, 17, 26, 2, 0, 28, 64, 46, 60, 96, 40, 64, 10, 4, 0, 0 }, // FLANGER 2 { 4, 109, 109, 2, 0, 28, 64, 46, 64, 127, 40, 64, 10, 4, 0, 0 }, // FLANGER 3 { 12, 25, 16, 0, 0, 28, 64, 46, 64, 127, 46, 64, 10, 0, 0, 0 }, // SYMPHONIC { 81, 35, 0, 0, 0, 24, 60, 45, 54, 127, 33, 52, 30, 0, 0, 0 }, // ROTARY SPEAKER { 83, 56, 0, 0, 0, 28, 64, 46, 64, 127, 40, 64, 10, 64, 0, 0 }, // TREMOLO { 76, 80, 32, 5, 0, 28, 64, 46, 64, 127, 40, 64, 10, 0, 0, 0 }, // AUTO PAN { 8, 111, 74, 104, 0, 28, 64, 46, 64, 64, 6, 1, 64, 0, 0, 0 }, // PHASER 1 { 8, 111, 74, 108, 0, 28, 64, 46, 64, 64, 5, 1, 4, 0, 0, 0 }, // PHASER 2 { 40, 20, 72, 53, 48, 0, 43, 74, 10, 127, 120, 0, 0, 0, 0, 0 }, // DISTORTION { 29, 24, 68, 45, 55, 0, 41, 72, 10, 127, 104, 0, 0, 0, 0, 0 }, // OVERDRIVE { 39, 1, 48, 55, 0, 0, 0, 0, 0, 127, 112, 0, 0, 0, 0, 0 }, // AMP SIMULATOR { 70, 34, 60, 10, 70, 28, 46, 0, 0, 127, 0, 0, 0, 0, 0, 0 }, // 3BAND EQ (MONO) { 28, 70, 46, 70, 0, 0, 0, 0, 0, 127, 34, 64, 10, 0, 0, 0 }, // 2BAND EQ (STEREO) { 70, 56, 39, 25, 0, 28, 66, 46, 64, 127, 0, 0, 0, 0, 0, 0 } // AUTO WAH (LFO) }; //------------------------------------------------------------------------- // XG Effect Type List // // REVERB static XGEffectItem REVERBEffectTab[] = { // msb lsb name params defs { 0x00, 0x00, "NO EFFECT", nullptr, REVERBDefaultTab[ 0] }, { 0x01, 0x00, "HALL 1", HALLROOMParamTab, REVERBDefaultTab[ 1] }, { 0x01, 0x01, "HALL 2", HALLROOMParamTab, REVERBDefaultTab[ 2] }, { 0x02, 0x00, "ROOM 1", HALLROOMParamTab, REVERBDefaultTab[ 3] }, { 0x02, 0x01, "ROOM 2", HALLROOMParamTab, REVERBDefaultTab[ 4] }, { 0x02, 0x02, "ROOM 3", HALLROOMParamTab, REVERBDefaultTab[ 5] }, { 0x03, 0x00, "STAGE 1", HALLROOMParamTab, REVERBDefaultTab[ 6] }, { 0x03, 0x01, "STAGE 2", HALLROOMParamTab, REVERBDefaultTab[ 7] }, { 0x04, 0x00, "PLATE", HALLROOMParamTab, REVERBDefaultTab[ 8] }, { 0x10, 0x00, "WHITE ROOM", WHITEROOMParamTab, REVERBDefaultTab[ 9] }, { 0x11, 0x00, "TUNNEL", WHITEROOMParamTab, REVERBDefaultTab[10] }, { 0x13, 0x00, "BASEMENT", WHITEROOMParamTab, REVERBDefaultTab[11] } }; // CHORUS static XGEffectItem CHORUSEffectTab[] = { // msb lsb name params defs { 0x00, 0x00, "NO EFFECT", nullptr, CHORUSDefaultTab[ 0] }, { 0x41, 0x00, "CHORUS 1", CHORUSParamTab, CHORUSDefaultTab[ 1] }, { 0x41, 0x01, "CHORUS 2", CHORUSParamTab, CHORUSDefaultTab[ 2] }, { 0x41, 0x02, "CHORUS 3", CHORUSParamTab, CHORUSDefaultTab[ 3] }, { 0x41, 0x08, "CHORUS 4", CHORUSParamTab, CHORUSDefaultTab[ 4] }, { 0x42, 0x00, "CELESTE 1", CHORUSParamTab, CHORUSDefaultTab[ 5] }, { 0x42, 0x01, "CELESTE 2", CHORUSParamTab, CHORUSDefaultTab[ 6] }, { 0x42, 0x02, "CELESTE 3", CHORUSParamTab, CHORUSDefaultTab[ 7] }, { 0x42, 0x08, "CELESTE 4", CHORUSParamTab, CHORUSDefaultTab[ 8] }, { 0x43, 0x00, "FLANGER 1", FLANGERParamTab, CHORUSDefaultTab[ 9] }, { 0x43, 0x01, "FLANGER 2", FLANGERParamTab, CHORUSDefaultTab[10] }, { 0x43, 0x08, "FLANGER 3", FLANGERParamTab, CHORUSDefaultTab[11] } }; // VARIATION static XGEffectItem VARIATIONEffectTab[] = { // msb lsb name params defs { 0x00, 0x00, "NO EFFECT", nullptr, VARIATIONDefaultTab[ 0] }, { 0x01, 0x00, "HALL 1", HALLROOMParamTab, VARIATIONDefaultTab[ 1] }, { 0x01, 0x01, "HALL 2", HALLROOMParamTab, VARIATIONDefaultTab[ 2] }, { 0x02, 0x00, "ROOM 1", HALLROOMParamTab, VARIATIONDefaultTab[ 3] }, { 0x02, 0x01, "ROOM 2", HALLROOMParamTab, VARIATIONDefaultTab[ 4] }, { 0x02, 0x02, "ROOM 3", HALLROOMParamTab, VARIATIONDefaultTab[ 5] }, { 0x03, 0x00, "STAGE 1", HALLROOMParamTab, VARIATIONDefaultTab[ 6] }, { 0x03, 0x01, "STAGE 2", HALLROOMParamTab, VARIATIONDefaultTab[ 7] }, { 0x04, 0x00, "PLATE", HALLROOMParamTab, VARIATIONDefaultTab[ 8] }, { 0x05, 0x00, "DELAY L,C,R", DELAYLCRParamTab, VARIATIONDefaultTab[ 9] }, { 0x06, 0x00, "DELAY L,R", DELAYLRParamTab, VARIATIONDefaultTab[10] }, { 0x07, 0x00, "ECHO", ECHOParamTab, VARIATIONDefaultTab[11] }, { 0x08, 0x00, "CROSS DELAY", CROSSDELAYParamTab, VARIATIONDefaultTab[12] }, { 0x09, 0x00, "EARLY REF 1", EARLYREFParamTab, VARIATIONDefaultTab[13] }, { 0x09, 0x01, "EARLY REF 2", EARLYREFParamTab, VARIATIONDefaultTab[14] }, { 0x0a, 0x00, "GATE REVERB", GATEREVERBParamTab, VARIATIONDefaultTab[15] }, { 0x0b, 0x00, "REVERSE GATE", GATEREVERBParamTab, VARIATIONDefaultTab[16] }, { 0x14, 0x00, "KARAOKE 1", KARAOKEParamTab, VARIATIONDefaultTab[17] }, { 0x14, 0x01, "KARAOKE 2", KARAOKEParamTab, VARIATIONDefaultTab[18] }, { 0x14, 0x02, "KARAOKE 3", KARAOKEParamTab, VARIATIONDefaultTab[19] }, { 0x40, 0x00, "THRU", nullptr, VARIATIONDefaultTab[20] }, { 0x41, 0x00, "CHORUS 1", CHORUSParamTab, VARIATIONDefaultTab[21] }, { 0x41, 0x01, "CHORUS 2", CHORUSParamTab, VARIATIONDefaultTab[22] }, { 0x41, 0x02, "CHORUS 3", CHORUSParamTab, VARIATIONDefaultTab[23] }, { 0x41, 0x08, "CHORUS 4", CHORUSParamTab, VARIATIONDefaultTab[24] }, { 0x42, 0x00, "CELESTE 1", CHORUSParamTab, VARIATIONDefaultTab[25] }, { 0x42, 0x01, "CELESTE 2", CHORUSParamTab, VARIATIONDefaultTab[26] }, { 0x42, 0x02, "CELESTE 3", CHORUSParamTab, VARIATIONDefaultTab[27] }, { 0x42, 0x08, "CELESTE 4", CHORUSParamTab, VARIATIONDefaultTab[28] }, { 0x43, 0x00, "FLANGER 1", FLANGERParamTab, VARIATIONDefaultTab[29] }, { 0x43, 0x01, "FLANGER 2", FLANGERParamTab, VARIATIONDefaultTab[30] }, { 0x43, 0x08, "FLANGER 3", FLANGERParamTab, VARIATIONDefaultTab[31] }, { 0x44, 0x00, "SYMPHONIC", SYMPHONICParamTab, VARIATIONDefaultTab[32] }, { 0x45, 0x00, "ROTARY SPEAKER", ROTSPEAKERParamTab, VARIATIONDefaultTab[33] }, { 0x46, 0x00, "TREMOLO", TREMOLOParamTab, VARIATIONDefaultTab[34] }, { 0x47, 0x00, "AUTO PAN", AUTOPANParamTab, VARIATIONDefaultTab[35] }, { 0x48, 0x00, "PHASER 1", PHASERParamTab, VARIATIONDefaultTab[36] }, { 0x48, 0x08, "PHASER 2", PHASERParamTab, VARIATIONDefaultTab[37] }, { 0x49, 0x00, "DISTORTION", DISTORTIONParamTab, VARIATIONDefaultTab[38] }, { 0x4a, 0x00, "OVERDRIVE", DISTORTIONParamTab, VARIATIONDefaultTab[39] }, { 0x4b, 0x00, "AMP SIMULATOR", AMPSIMULParamTab, VARIATIONDefaultTab[40] }, { 0x4c, 0x00, "3BAND EQ (MONO)", MONOEQParamTab, VARIATIONDefaultTab[41] }, { 0x4d, 0x00, "2BAND EQ (STEREO)",STEREOEQParamTab, VARIATIONDefaultTab[42] }, { 0x4e, 0x00, "AUTO WAH (LFO)", AUTOWAHParamTab, VARIATIONDefaultTab[43] } }; //------------------------------------------------------------------------- // XG Parameter table helpers. // typedef struct _XGParamItem { unsigned short id; // id=low address. unsigned short size; // data size in bytes. unsigned short min; // minimum value; 0=REVERB, 1=CHORUS, 2=VARIATION. unsigned short max; // maximum value; parameter index (0..15) const char *name; // parameter name; nullptr=depends on effect type. unsigned short def; // default value; float (*getv)(unsigned short); // convert to display value. unsigned short (*getu)(float); // invert to native value. const char * (*gets)(unsigned short); // enumerated string value. const char * (*unit)(); // unit suffix label. } XGParamItem; //------------------------------------------------------------------------- // XG Parameter tables // SYSTEM // Address: 0x00 0x00 // static XGParamItem SYSTEMParamTab[] = { //id size min max name def getv getu gets unit { 0x00, 4, 0, 2047, "[Master ]Tune", 1024, getv1024, getu1024, nullptr, unit_cen }, { 0x04, 1, 0, 127, "[Master ]Volume", 127, nullptr, nullptr, nullptr, nullptr }, { 0x06, 1, 40, 88, "Transpose", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x7d, 1, 0, 1, "Drum[ Setup ]Reset", 0, nullptr, nullptr, nullptr, nullptr }, // Drumset number (0,1) { 0x7e, 1, 0, 0, "XG System On", 0, nullptr, nullptr, nullptr, nullptr }, // 0=XG System ON (receive only) { 0x7f, 1, 0, 0, "All[ Parameter ]Reset", 0, nullptr, nullptr, nullptr, nullptr } // 0=ON (receive only) }; // EFFECT // Address: 0x02 0x01 // static XGParamItem EFFECTParamTab[] = { //id size min max name def getv getu gets unit { 0x00, 2, 0,16383, "[Reverb ]Type", 128, nullptr, nullptr, nullptr, nullptr }, // msb=0x01 lsb=0x00 (HALL 1) { 0x02, 1, 0, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 1 - depends on REVERB TYPE { 0x03, 1, 0, 1, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 2 - depends on REVERB TYPE { 0x04, 1, 0, 2, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 3 - depends on REVERB TYPE { 0x05, 1, 0, 3, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 4 - depends on REVERB TYPE { 0x06, 1, 0, 4, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 5 - depends on REVERB TYPE { 0x07, 1, 0, 5, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 6 - depends on REVERB TYPE { 0x08, 1, 0, 6, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 7 - depends on REVERB TYPE { 0x09, 1, 0, 7, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 8 - depends on REVERB TYPE { 0x0a, 1, 0, 8, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 9 - depends on REVERB TYPE { 0x0b, 1, 0, 9, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 10 - depends on REVERB TYPE { 0x0c, 1, 0, 127, "[Reverb ]Return", 64, nullptr, nullptr, nullptr, nullptr }, // -infdB..0dB..+6dB (0..64..127) { 0x0d, 1, 1, 127, "[Reverb ]Pan", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x10, 1, 0, 10, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 11 - depends on REVERB TYPE { 0x11, 1, 0, 11, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 12 - depends on REVERB TYPE { 0x12, 1, 0, 12, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 13 - depends on REVERB TYPE { 0x13, 1, 0, 13, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 14 - depends on REVERB TYPE { 0x14, 1, 0, 14, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 15 - depends on REVERB TYPE { 0x15, 1, 0, 15, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // REVERB PARAMETER 16 - depends on REVERB TYPE { 0x20, 2, 0,16383, "[Chorus ]Type", 8320, nullptr, nullptr, nullptr, nullptr }, // msb=41 lsb=00 (CHORUS 1) { 0x22, 1, 1, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 1 - depends on CHORUS TYPE { 0x23, 1, 1, 1, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 2 - depends on CHORUS TYPE { 0x24, 1, 1, 2, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 3 - depends on CHORUS TYPE { 0x25, 1, 1, 3, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 4 - depends on CHORUS TYPE { 0x26, 1, 1, 4, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 5 - depends on CHORUS TYPE { 0x27, 1, 1, 5, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 6 - depends on CHORUS TYPE { 0x28, 1, 1, 6, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 7 - depends on CHORUS TYPE { 0x29, 1, 1, 7, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 8 - depends on CHORUS TYPE { 0x2a, 1, 1, 8, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 9 - depends on CHORUS TYPE { 0x2b, 1, 1, 9, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 10 - depends on CHORUS TYPE { 0x2c, 1, 0, 127, "[Chorus ]Return", 64, nullptr, nullptr, nullptr, nullptr }, // -infdB..0dB..+6dB (0..64..127) { 0x2d, 1, 1, 127, "[Chorus ]Pan", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x2e, 1, 0, 127, "[Chorus ]Reverb[ Send]", 0, nullptr, nullptr, nullptr, nullptr }, // -infdB..0dB..+6dB (0..64..127) { 0x30, 1, 1, 10, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 11 - depends on CHORUS TYPE { 0x31, 1, 1, 11, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 12 - depends on CHORUS TYPE { 0x32, 1, 1, 12, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 13 - depends on CHORUS TYPE { 0x33, 1, 1, 13, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 14 - depends on CHORUS TYPE { 0x34, 1, 1, 14, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 15 - depends on CHORUS TYPE { 0x35, 1, 1, 15, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // CHORUS PARAMETER 16 - depends on CHORUS TYPE { 0x40, 2, 0,16383, "[Variation ]Type", 640, nullptr, nullptr, nullptr, nullptr }, // msb=05 lsb=00 (DELAY L,C,R) { 0x42, 2, 2, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 1 - depends on VARIATION TYPE { 0x44, 2, 2, 1, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 2 - depends on VARIATION TYPE { 0x46, 2, 2, 2, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 3 - depends on VARIATION TYPE { 0x48, 2, 2, 3, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 4 - depends on VARIATION TYPE { 0x4a, 2, 2, 4, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 5 - depends on VARIATION TYPE { 0x4c, 2, 2, 5, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 6 - depends on VARIATION TYPE { 0x4e, 2, 2, 6, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 7 - depends on VARIATION TYPE { 0x50, 2, 2, 7, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 8 - depends on VARIATION TYPE { 0x52, 2, 2, 8, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 9 - depends on VARIATION TYPE { 0x54, 2, 2, 9, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 10 - depends on VARIATION TYPE { 0x56, 1, 0, 127, "[Variation ]Return", 64, nullptr, nullptr, nullptr, nullptr }, // -infdB..0dB..+6dB (0..64..127) { 0x57, 1, 1, 127, "[Variation ]Pan", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x58, 1, 0, 127, "[Variation ]Reverb[ Send]",0,nullptr, nullptr, nullptr, nullptr }, // -infdB..0dB..+6dB (0..64..127) { 0x59, 1, 0, 127, "[Variation ]Chorus[ Send]",0,nullptr, nullptr, nullptr, nullptr }, // -infdB..0dB..+6dB (0..64..127) { 0x5a, 1, 0, 1, "[Variation ]Connection", 0, nullptr, nullptr, getsconn, nullptr }, { 0x5b, 1, 0, 127, "[Variation ]Part", 127, nullptr, nullptr, getschan, nullptr }, // part=0..15, 127=OFF { 0x5c, 1, 0, 127, "[Variation ]Wheel[ Depth]",64,getv0x40,getu0x40, nullptr, nullptr }, { 0x5d, 1, 0, 127, "[Variation ]Bend[ Depth]",64,getv0x40, getu0x40, nullptr, nullptr }, { 0x5e, 1, 0, 127, "[Variation ]CAT[ Depth]",64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5f, 1, 0, 127, "[Variation ]AC1[ Depth]",64, getv0x40, getu0x40, nullptr, nullptr }, { 0x60, 1, 0, 127, "[Variation ]AC2[ Depth]",64, getv0x40, getu0x40, nullptr, nullptr }, { 0x70, 1, 2, 10, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 11 - depends on VARIATION TYPE { 0x71, 1, 2, 11, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 12 - depends on VARIATION TYPE { 0x72, 1, 2, 12, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 13 - depends on VARIATION TYPE { 0x73, 1, 2, 13, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 14 - depends on VARIATION TYPE { 0x74, 1, 2, 14, nullptr, 0, nullptr, nullptr, nullptr, nullptr }, // VARIATION PARAMETER 15 - depends on VARIATION TYPE { 0x75, 1, 2, 15, nullptr, 0, nullptr, nullptr, nullptr, nullptr } // VARIATION PARAMETER 16 - depends on VARIATION TYPE }; // MULTI PART // Address: 0x08 // static XGParamItem MULTIPARTParamTab[] = { //id size min max name def getv getu gets unit { 0x00, 1, 0, 32, "Element[ Reserve]", 0, nullptr, nullptr, nullptr, nullptr }, // 0=part10, 2=other { 0x01, 1, 0, 127, "Bank [Select ]MSB", 0, nullptr, nullptr, nullptr, nullptr }, // 127=part10, 0=other { 0x02, 1, 0, 127, "Bank [Select ]LSB", 0, nullptr, nullptr, nullptr, nullptr }, { 0x03, 1, 0, 127, "Program[ Number]", 0, getvprog, getuprog, nullptr, nullptr }, { 0x04, 1, 0, 127, "[Rcv ]Channel", 0, nullptr, nullptr, getschan, nullptr }, // 0..15=partno, 127=OFF { 0x05, 1, 0, 1, "Mono/Poly[ Mode]", 1, nullptr, nullptr, getsmmod, nullptr }, { 0x06, 1, 0, 2, "Same [Note ]Key[ Assign]",1, nullptr, nullptr, getskeya, nullptr }, { 0x07, 1, 0, 3, "[Mode ]Type", 0, nullptr, nullptr, getspmod, nullptr }, // other than part10, 2=part10 { 0x08, 1, 40, 88, "[Note ]Shift", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x09, 2, 0, 255, "Detune", 128, getv12_7, getu12_7, nullptr, unit_Hz }, { 0x0b, 1, 0, 127, "Volume", 100, nullptr, nullptr, nullptr, nullptr }, { 0x0c, 1, 0, 127, "[Velocity Sense ]Depth", 64, nullptr, nullptr, nullptr, nullptr }, { 0x0d, 1, 0, 127, "[Velocity Sense ]Offset",64, nullptr, nullptr, nullptr, nullptr }, { 0x0e, 1, 0, 127, "Pan", 64, getv0x40, getu0x40, nullptr, nullptr }, // 0=random { 0x0f, 1, 0, 127, "[Note Limit ]Low", 0, nullptr, nullptr, getsnote, nullptr }, // C-2..G8 { 0x10, 1, 0, 127, "[Note Limit ]High", 127, nullptr, nullptr, getsnote, nullptr }, // C-2..G8 { 0x11, 1, 0, 127, "Dry/Wet[ Level]", 127, nullptr, nullptr, nullptr, nullptr }, { 0x12, 1, 0, 127, "Chorus[ Send]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x13, 1, 0, 127, "Reverb[ Send]", 40, nullptr, nullptr, nullptr, nullptr }, { 0x14, 1, 0, 127, "Variation[ Send]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x15, 1, 0, 127, "[Vibrato ]Rate", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x16, 1, 0, 127, "[Vibrato ]Depth", 64, getv0x40, getu0x40, nullptr, nullptr }, // drum part ignores { 0x17, 1, 0, 127, "[Vibrato ]Delay", 64, getv0x40, getu0x40, nullptr, nullptr }, // drum part ignores { 0x18, 1, 0, 127, "[Filter ]Cutoff[ Freq]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x19, 1, 0, 127, "[Filter ]Resonance", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x1a, 1, 0, 127, "[EG ]Attack[ Time]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x1b, 1, 0, 127, "[EG ]Decay[ Time]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x1c, 1, 0, 127, "[EG ]Release[ Time]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x1d, 1, 40, 88, "[Wheel ]Pitch", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x1e, 1, 0, 127, "[Wheel ]Filter", 64, getv94_5, getu94_5, nullptr, nullptr }, { 0x1f, 1, 1, 127, "[Wheel ]Ampl[itude]", 64, getv_100, getu_100, nullptr, unit_pct }, { 0x20, 1, 0, 127, "[Wheel ]LFO Pitch", 10, nullptr, nullptr, nullptr, nullptr }, { 0x21, 1, 0, 127, "[Whell ]LFO Filter", 0, nullptr, nullptr, nullptr, nullptr }, { 0x22, 1, 0, 127, "[Wheel ]LFO Ampl[itude]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x23, 1, 40, 88, "[Bend ]Pitch", 66, getv0x40, getu0x40, nullptr, unit_sem }, { 0x24, 1, 0, 127, "[Bend ]Filter", 64, getv94_5, getu94_5, nullptr, unit_cen }, { 0x25, 1, 0, 127, "[Bend ]Ampl[itude]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x26, 1, 0, 127, "[Bend ]LFO Pitch", 0, nullptr, nullptr, nullptr, nullptr }, { 0x27, 1, 0, 127, "[Bend ]LFO Filter", 0, nullptr, nullptr, nullptr, nullptr }, { 0x28, 1, 0, 127, "[Bend ]LFO Ampl[itude]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x30, 1, 0, 1, "[Rcv ]P[itch ]B[end]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x31, 1, 0, 1, "[Rcv ]C[han ]A[fter ]T[ouch]",1,nullptr,nullptr, getsonff, nullptr }, { 0x32, 1, 0, 1, "[Rcv ]P[rogram ]C[hange]",1, nullptr, nullptr, getsonff, nullptr }, { 0x33, 1, 0, 1, "[Rcv ]C[ontrol ]C[hange]",1, nullptr, nullptr, getsonff, nullptr }, { 0x34, 1, 0, 1, "[Rcv ]P[oly ]A[fter ]T[ouch]",1,nullptr,nullptr, getsonff, nullptr }, { 0x35, 1, 0, 1, "[Rcv ]Note[ Message]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x36, 1, 0, 1, "[Rcv ]RPN", 1, nullptr, nullptr, getsonff, nullptr }, { 0x37, 1, 0, 1, "[Rcv ]NRPN", 1, nullptr, nullptr, getsonff, nullptr }, // 1=XG, 0=GM { 0x38, 1, 0, 1, "[Rcv ]Mod[ulation]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x39, 1, 0, 1, "[Rcv ]Vol[ume]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x3a, 1, 0, 1, "[Rcv ]Pan", 1, nullptr, nullptr, getsonff, nullptr }, { 0x3b, 1, 0, 1, "[Rcv ]Expr[ession]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x3c, 1, 0, 1, "[Rcv ]Hold[1]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x3d, 1, 0, 1, "[Rcv ]Porta[mento]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x3e, 1, 0, 1, "[Rcv ]Sost[enuto]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x3f, 1, 0, 1, "[Rcv ]S[oft ]P[edal]", 1, nullptr, nullptr, getsonff, nullptr }, { 0x40, 1, 0, 1, "[Rcv ]B[ank ]S[elect]", 1, nullptr, nullptr, getsonff, nullptr }, // 1=XG, 0=GM { 0x41, 1, 0, 127, "[Scale Tuning ]C", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x42, 1, 0, 127, "[Scale Tuning ]C#", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x43, 1, 0, 127, "[Scale Tuning ]D", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x44, 1, 0, 127, "[Scale Tuning ]D#", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x45, 1, 0, 127, "[Scale Tuning ]E", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x46, 1, 0, 127, "[Scale Tuning ]F", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x47, 1, 0, 127, "[Scale Tuning ]F#", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x48, 1, 0, 127, "[Scale Tuning ]G", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x49, 1, 0, 127, "[Scale Tuning ]G#", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x4a, 1, 0, 127, "[Scale Tuning ]A", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x4b, 1, 0, 127, "[Scale Tuning ]A#", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x4c, 1, 0, 127, "[Scale Tuning ]B", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x4d, 1, 40, 88, "[CAT ]Pitch", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x4e, 1, 0, 127, "[CAT ]Filter", 64, getv94_5, getu94_5, nullptr, nullptr }, { 0x4f, 1, 0, 127, "[CAT ]Ampl[itude]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x50, 1, 0, 127, "[CAT ]LFO Pitch", 0, nullptr, nullptr, nullptr, nullptr }, { 0x51, 1, 0, 127, "[CAT ]LFO Filter", 0, nullptr, nullptr, nullptr, nullptr }, { 0x52, 1, 0, 127, "[CAT ]LFO Aampl[itude]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x53, 1, 40, 88, "[PAT ]Pitch", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x54, 1, 0, 127, "[PAT ]Filter", 64, getv94_5, getu94_5, nullptr, nullptr }, { 0x55, 1, 0, 127, "[PAT ]Ampl[itude]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x56, 1, 0, 127, "[PAT ]LFO Pitch", 0, nullptr, nullptr, nullptr, nullptr }, { 0x57, 1, 0, 127, "[PAT ]LFO Filter", 0, nullptr, nullptr, nullptr, nullptr }, { 0x58, 1, 0, 127, "[PAT ]LFO Ampl[itude]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x59, 1, 0, 95, "[AC1 ]Controller", 16, nullptr, nullptr, nullptr, nullptr }, { 0x5a, 1, 40, 88, "[AC1 ]Pitch", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x5b, 1, 0, 127, "[AC1 ]Filter", 64, getv94_5, getu94_5, nullptr, nullptr }, { 0x5c, 1, 0, 127, "[AC1 ]Ampl[itude]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5d, 1, 0, 127, "[AC1 ]LFO Pitch", 0, nullptr, nullptr, nullptr, nullptr }, { 0x5e, 1, 0, 127, "[AC1 ]LFO Filter", 0, nullptr, nullptr, nullptr, nullptr }, { 0x5f, 1, 0, 127, "[AC1 ]LFO Ampl[itude]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x60, 1, 0, 95, "[AC2 ]Controller", 17, nullptr, nullptr, nullptr, nullptr }, { 0x61, 1, 40, 88, "[AC2 ]Pitch", 64, getv0x40, getu0x40, nullptr, unit_sem }, { 0x62, 1, 0, 127, "[AC2 ]Filter", 64, getv94_5, getu94_5, nullptr, nullptr }, { 0x63, 1, 0, 127, "[AC2 ]Ampl[itude]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x64, 1, 0, 127, "[AC2 ]LFO Pitch", 0, nullptr, nullptr, nullptr, nullptr }, { 0x65, 1, 0, 127, "[AC2 ]LFO Filter", 0, nullptr, nullptr, nullptr, nullptr }, { 0x66, 1, 0, 127, "[AC2 ]LFO Ampl[itude]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x67, 1, 0, 1, "[Portamento ]Switch", 0, nullptr, nullptr, getsonff, nullptr }, { 0x68, 1, 0, 127, "[Portamento ]Time", 0, nullptr, nullptr, nullptr, nullptr }, { 0x69, 1, 0, 127, "[PEG ]Ini[tial] Level", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6a, 1, 0, 127, "[PEG ]Att[ack] Time", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6b, 1, 0, 127, "[PEG ]Rel[ease] Level", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6c, 1, 0, 127, "[PEG ]Rel[ease] Time", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6d, 1, 1, 127, "[Velocity Limit] Low", 1, nullptr, nullptr, nullptr, nullptr }, { 0x6e, 1, 1, 127, "[Velocity Limit] High", 127, nullptr, nullptr, nullptr, nullptr } }; // DRUM SETUP // Address: 0x3n n=0,1 (drumset) // static XGParamItem DRUMSETUPParamTab[] = { //id size min max name def getv getu gets unit { 0x00, 1, 0, 127, "[Pitch ]Coarse", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x01, 1, 0, 127, "[Pitch ]Fine", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x02, 1, 0, 127, "Level", 127, nullptr, nullptr, nullptr, nullptr }, // depend on the note { 0x03, 1, 0, 127, "[Alternate ]Group", 0, nullptr, nullptr, nullptr, nullptr }, // depend on the note (0=OFF) { 0x04, 1, 0, 127, "Pan", 64, getv0x40, getu0x40, nullptr, nullptr }, // depend on the note (0=random) { 0x05, 1, 0, 127, "Reverb[ Send]", 0, nullptr, nullptr, nullptr, nullptr }, // depend on the note { 0x06, 1, 0, 127, "Chorus[ Send]", 0, nullptr, nullptr, nullptr, nullptr }, // depend on the note { 0x07, 1, 0, 127, "Variation[ Send]", 127, nullptr, nullptr, nullptr, nullptr }, { 0x08, 1, 0, 1, "Same [Note ]Key[ Assign]",0, nullptr, nullptr, getskeya, nullptr }, { 0x09, 1, 0, 1, "[Rcv ]Note Off", 0, nullptr, nullptr, getsonff, nullptr }, // depend on the note { 0x0a, 1, 0, 1, "[Rcv ]Note On", 1, nullptr, nullptr, getsonff, nullptr }, { 0x0b, 1, 0, 127, "[Filter ]Cutoff[ Freq]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x0c, 1, 0, 127, "[Filter ]Resonance", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x0d, 1, 0, 127, "[EG ]Attack[ Rate]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x0e, 1, 0, 127, "[EG ]Decay 1[ Rate]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x0f, 1, 0, 127, "[EG ]Decay 2[ Rate]", 64, getv0x40, getu0x40, nullptr, nullptr } }; //------------------------------------------------------------------------- // XG MIDI Bulk Dump table (USER NORMAL VOICE) [QS300] // USER VOICE // Address: 0x11 // static XGParamItem USERVOICEParamTab[] = { //id size min max name def getv getu gets unit // [Common] { 0x00,10, 32, 127, "[Voice ]Name", 0, nullptr, nullptr, nullptr, nullptr }, { 0x0b, 1, 1, 3, "Element[ Switch]", 1, nullptr, nullptr, getselem, nullptr }, // 1=Element 1 on, 2=Element 2 on, 3=Element 1 and 2 on { 0x0c, 1, 0, 127, "[Voice ]Level", 64, nullptr, nullptr, nullptr, nullptr }, // [Element 1] { 0x3d, 2, 1, 245, "Wave Form", 37, nullptr, nullptr, getswave, nullptr }, { 0x3f, 1, 0, 127, "Note[ Limit] Low", 0, nullptr, nullptr, getsnote, nullptr }, { 0x40, 1, 0, 127, "Note[ Limit] High", 127, nullptr, nullptr, getsnote, nullptr }, { 0x41, 1, 0, 127, "Vel[ocity Limit] Low", 0, nullptr, nullptr, nullptr, nullptr }, { 0x42, 1, 0, 127, "Vel[ocity Limit] High", 127, nullptr, nullptr, nullptr, nullptr }, { 0x43, 1, 0, 1, "[FEG ]Vel Curve", 0, nullptr, nullptr, getsvelc, nullptr }, // 0=Linear, 1=Exp { 0x44, 1, 0, 2, "[LFO ]Wave[ Select]", 0, nullptr, nullptr, getslfow, nullptr }, { 0x45, 1, 0, 1, "[LFO ]Phase[ Initialize]",0, nullptr, nullptr, getsonff, nullptr }, { 0x46, 1, 0, 63, "[LFO ]Speed", 32, nullptr, nullptr, nullptr, nullptr }, { 0x47, 1, 0, 127, "[LFO ]Delay", 0, nullptr, nullptr, nullptr, nullptr }, { 0x48, 1, 0, 127, "[LFO ]Fade[ Time]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x49, 1, 0, 63, "[LFO ]Pitch[ Depth]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x4a, 1, 0, 15, "[LFO ]Cutoff[ Depth]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x4b, 1, 0, 31, "[LFO ]Ampl[itude Depth]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x4c, 1, 32, 96, "[Note ]Shift", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x4d, 1, 14, 114, "Detune", 64, getv0x40, getu0x40, nullptr, unit_cen }, { 0x4e, 1, 0, 5, "[Pitch ]Scaling", 0, nullptr, nullptr, getspscl, nullptr }, { 0x4f, 1, 0, 127, "[Pitch ]Center[ Note]", 64, nullptr, nullptr, getsnote, nullptr }, { 0x50, 1, 0, 3, "[PEG ]Depth", 0, nullptr, nullptr, getspdph, nullptr }, { 0x51, 1, 57, 71, "[PEG ]Vel [Sense ]Level",64, getv0x40, getu0x40, nullptr, nullptr }, { 0x52, 1, 57, 71, "[PEG ]Vel [Sense ]Rate", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x53, 1, 57, 71, "[PEG ]Rate[ Scaling]", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x54, 1, 0, 127, "[PEG ]Center[ Note]", 64, nullptr, nullptr, getsnote, nullptr }, { 0x55, 1, 0, 63, "[PEG ]Rate 1", 0, nullptr, nullptr, nullptr, nullptr }, { 0x56, 1, 0, 63, "[PEG ]Rate 2", 0, nullptr, nullptr, nullptr, nullptr }, { 0x57, 1, 0, 63, "[PEG ]Rate 3", 0, nullptr, nullptr, nullptr, nullptr }, { 0x58, 1, 0, 63, "[PEG ]Rate 4", 0, nullptr, nullptr, nullptr, nullptr }, { 0x59, 1, 0, 127, "[PEG ]Level 0", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5a, 1, 0, 127, "[PEG ]Level 1", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5b, 1, 0, 127, "[PEG ]Level 2", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5c, 1, 0, 127, "[PEG ]Level 3", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5d, 1, 0, 127, "[PEG ]Level 4", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x5e, 1, 0, 63, "[Filter ]Resonance", 32, nullptr, nullptr, nullptr, nullptr }, { 0x5f, 1, 0, 7, "Velocity[ Sensitivity]", 0, nullptr, nullptr, nullptr, nullptr }, { 0x60, 1, 0, 127, "Cutoff[ Frequency]", 64, nullptr, nullptr, nullptr, nullptr }, { 0x61, 1, 0, 127, "[Cutoff Sc ]Break 1", 25, nullptr, nullptr, getsnote, nullptr }, { 0x62, 1, 0, 127, "[Cutoff Sc ]Break 2", 50, nullptr, nullptr, getsnote, nullptr }, { 0x63, 1, 0, 127, "[Cutoff Sc ]Break 3", 75, nullptr, nullptr, getsnote, nullptr }, { 0x64, 1, 0, 127, "[Cutoff Sc ]Break 4", 100, nullptr, nullptr, getsnote, nullptr }, { 0x65, 1, 0, 127, "[Cutoff Sc ]Offset 1", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x66, 1, 0, 127, "[Cutoff Sc ]Offset 2", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x67, 1, 0, 127, "[Cutoff Sc ]Offset 3", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x68, 1, 0, 127, "[Cutoff Sc ]Offset 4", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x69, 1, 57, 71, "[FEG ]Vel [Sense ]Level",64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6a, 1, 57, 71, "[FEG ]Vel [Sense ]Rate", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6b, 1, 57, 71, "[FEG Rate ]Scaling", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x6c, 1, 0, 127, "[FEG ]Center[ Note]", 64, nullptr, nullptr, getsnote, nullptr }, { 0x6d, 1, 0, 63, "[FEG ]Rate 1", 0, nullptr, nullptr, nullptr, nullptr }, { 0x6e, 1, 0, 63, "[FEG ]Rate 2", 0, nullptr, nullptr, nullptr, nullptr }, { 0x6f, 1, 0, 63, "[FEG ]Rate 3", 0, nullptr, nullptr, nullptr, nullptr }, { 0x70, 1, 0, 63, "[FEG ]Rate 4", 0, nullptr, nullptr, nullptr, nullptr }, { 0x71, 1, 0, 127, "[FEG ]Level 0", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x72, 1, 0, 127, "[FEG ]Level 1", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x73, 1, 0, 127, "[FEG ]Level 2", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x74, 1, 0, 127, "[FEG ]Level 3", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x75, 1, 0, 127, "[FEG ]Level 4", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x76, 1, 0, 127, "[Element ]Level", 127, nullptr, nullptr, nullptr, nullptr }, { 0x77, 1, 0, 127, "[Level Sc ]Break 1", 25, nullptr, nullptr, getsnote, nullptr }, { 0x78, 1, 0, 127, "[Level Sc ]Break 2", 50, nullptr, nullptr, getsnote, nullptr }, { 0x79, 1, 0, 127, "[Level Sc ]Break 3", 75, nullptr, nullptr, getsnote, nullptr }, { 0x7a, 1, 0, 127, "[Level Sc ]Break 4", 100, nullptr, nullptr, getsnote, nullptr }, { 0x7b, 1, 0, 127, "[Level Sc ]Offset 1", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x7c, 1, 0, 127, "[Level Sc ]Offset 2", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x7d, 1, 0, 127, "[Level Sc ]Offset 3", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x7e, 1, 0, 127, "[Level Sc ]Offset 4", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x7f, 1, 0, 6, "Vel[ocity] Curve", 0, nullptr, nullptr, nullptr, nullptr }, { 0x80, 1, 0, 15, "Pan", 7, nullptr, nullptr, getsvpan, nullptr }, // 0=Left..14=Right, 15=Scaling { 0x81, 1, 57, 71, "[AEG Rate ]Scaling", 64, getv0x40, getu0x40, nullptr, nullptr }, { 0x82, 1, 0, 127, "[AEG ]Center[ Note]", 64, getv0x40, getu0x40, getsnote, nullptr }, { 0x83, 1, 0, 15, "[AEG Key On ]Delay", 0, nullptr, nullptr, nullptr, nullptr }, { 0x84, 1, 0, 63, "[AEG ]Attack[ Rate]", 63, nullptr, nullptr, nullptr, nullptr }, { 0x85, 1, 0, 63, "[AEG ]Decay 1[ Rate]", 32, nullptr, nullptr, nullptr, nullptr }, { 0x86, 1, 0, 63, "[AEG ]Decay 2[ Rate]", 32, nullptr, nullptr, nullptr, nullptr }, { 0x87, 1, 0, 63, "[AEG ]Release[ Rate]", 32, nullptr, nullptr, nullptr, nullptr }, { 0x88, 1, 0, 127, "[AEG Decay ]Level 1", 127, nullptr, nullptr, nullptr, nullptr }, { 0x89, 1, 0, 127, "[AEG Decay ]Level 2", 127, nullptr, nullptr, nullptr, nullptr }, { 0x8a, 2, 0,16383, "[Address ]Offset", 0, nullptr, nullptr, nullptr, nullptr }, { 0x8c, 1, 57, 71, "Resonance[ Sensitivity]",64, getv0x40, getu0x40, nullptr, nullptr } // [Element 2] // ... }; //------------------------------------------------------------------------- // XG NRPN Parameter table helpers. // typedef struct _XGRpnParamItem { unsigned short param; // (N)RPN parameter. unsigned short hi; // high address. unsigned short lo; // low address (id). } XGRpnParamItem; // NRPN map. // static XGRpnParamItem NRPNParamTab[] = { //param hi lo // MULTIPART NRPN map... // Address: 0x08 { 136, 0x08, 0x15 }, // Vibrato Rate { 137, 0x08, 0x16 }, // Vibrato Depth { 138, 0x08, 0x17 }, // Vibrato Delay { 160, 0x08, 0x18 }, // Filter Cutoff { 161, 0x08, 0x19 }, // Filter Resonance { 227, 0x08, 0x20 }, // EG Attack { 228, 0x08, 0x21 }, // EG Decay { 230, 0x08, 0x22 }, // EG Release // DRUMSETUP NRPN map... // Address: 0x3n n=0,1 (drumset) { 2560, 0x30, 0x0b }, // Drum Filter Cutoff { 2688, 0x30, 0x0c }, // Drum Filter Resonance { 2816, 0x30, 0x0e }, // Drum EG Attack { 2944, 0x30, 0x0f }, // Drum EG Decay { 3072, 0x30, 0x00 }, // Drum Pitch Coarse { 3200, 0x30, 0x01 }, // Drum Pitch Fine { 3328, 0x30, 0x02 }, // Drum Level { 3584, 0x30, 0x04 }, // Drum Pan { 3712, 0x30, 0x05 }, // Drum Reverb Send { 3840, 0x30, 0x06 }, // Drum Chorus Send { 3968, 0x30, 0x07 } // Drum Variation Send }; //------------------------------------------------------------------------- // XG Effect table helpers. static inline const XGEffectItem *XGEffectItem_find ( unsigned short etype, XGEffectItem items[], unsigned short nitems ) { unsigned short i; for (i = 0; i < nitems; ++i) { XGEffectItem *item = &items[i]; if (((item->msb << 7) + item->lsb) == etype) return item; } return nullptr; } static inline const XGEffectItem *REVERBEffectItem ( unsigned short etype ) { return XGEffectItem_find(etype, REVERBEffectTab, TSIZE(REVERBEffectTab)); } static inline const XGEffectItem *CHORUSEffectItem ( unsigned short etype ) { return XGEffectItem_find(etype, CHORUSEffectTab, TSIZE(CHORUSEffectTab)); } static inline const XGEffectItem *VARIATIONEffectItem ( unsigned short etype ) { return XGEffectItem_find(etype, VARIATIONEffectTab, TSIZE(VARIATIONEffectTab)); } //------------------------------------------------------------------------- // XG Effect default helpers. static inline unsigned short XGEffectDefault_find ( unsigned short etype, unsigned short index, XGEffectItem items[], unsigned short nitems, unsigned short defaults[][16] ) { unsigned short i; for (i = 0; i < nitems; ++i) { XGEffectItem *item = &items[i]; if (((item->msb << 7) + item->lsb) == etype) return defaults[i][index]; } return 0; } static inline unsigned short REVERBEffectDefault ( unsigned short etype, unsigned short index ) { return XGEffectDefault_find(etype, index, REVERBEffectTab, TSIZE(REVERBEffectTab), REVERBDefaultTab); } static inline unsigned short CHORUSEffectDefault ( unsigned short etype, unsigned short index ) { return XGEffectDefault_find(etype, index, CHORUSEffectTab, TSIZE(CHORUSEffectTab), CHORUSDefaultTab); } static inline unsigned short VARIATIONEffectDefault ( unsigned short etype, unsigned short index ) { return XGEffectDefault_find(etype, index, VARIATIONEffectTab, TSIZE(VARIATIONEffectTab), VARIATIONDefaultTab); } //------------------------------------------------------------------------- // XG Parameter table helpers. static inline const XGParamItem *XGParamItem_find ( unsigned short id, XGParamItem items[], unsigned short nitems ) { unsigned short i; for (i = 0; i < nitems; ++i) { XGParamItem *item = &items[i]; if (item->id == id) return item; } return nullptr; } static inline const XGParamItem *SYSTEMParamItem ( unsigned short id ) { return XGParamItem_find(id, SYSTEMParamTab, TSIZE(SYSTEMParamTab)); } static inline const XGParamItem *EFFECTParamItem ( unsigned short id ) { return XGParamItem_find(id, EFFECTParamTab, TSIZE(EFFECTParamTab)); } static inline const XGParamItem *MULTIPARTParamItem ( unsigned short id ) { return XGParamItem_find(id, MULTIPARTParamTab, TSIZE(MULTIPARTParamTab)); } static inline const XGParamItem *DRUMSETUPParamItem ( unsigned short id ) { return XGParamItem_find(id, DRUMSETUPParamTab, TSIZE(DRUMSETUPParamTab)); } static inline const XGParamItem *USERVOICEParamItem ( unsigned short id ) { return XGParamItem_find(id, USERVOICEParamTab, TSIZE(USERVOICEParamTab)); } //------------------------------------------------------------------------- // class XGInstrument - XG Instrument/Normal Voice Group descriptor. // // Constructor. XGInstrument::XGInstrument ( unsigned short id ) : m_group(nullptr) { if (id < XGInstrument::count()) m_group = &(InstrumentTab[id]); } // Descriptor acessor. const XGNormalVoiceGroup *XGInstrument::group (void) const { return m_group; } // Instrument name. const char *XGInstrument::name (void) const { return (m_group ? m_group->name : nullptr); } // Number of items. unsigned short XGInstrument::size (void) const { return (m_group ? m_group->size : 0); } // Voice index finder. int XGInstrument::find_voice ( unsigned short bank, unsigned short prog ) const { if (m_group) { for (int i = 0; i < m_group->size; ++i) { XGNormalVoiceItem *item = &(m_group->items[i]); if (item->bank == bank && (item->prog - 1) == prog) return i; } } return -1; } // Instrument list size (static). unsigned short XGInstrument::count (void) { return TSIZE(InstrumentTab); } //------------------------------------------------------------------------- // class XGNormalVoice - XG Normal Voice descriptor. // // Constructor. XGNormalVoice::XGNormalVoice ( XGInstrument *instr, unsigned short id ) : m_item(nullptr) { if (instr && instr->group() && id < instr->size()) m_item = &((instr->group())->items[id]); } // Voice properties accessors. unsigned short XGNormalVoice::bank (void) const { return (m_item ? m_item->bank : 0); } unsigned short XGNormalVoice::prog (void) const { return (m_item ? (m_item->prog - 1): 0); } const char *XGNormalVoice::name (void) const { return (m_item ? m_item->name : nullptr); } unsigned short XGNormalVoice::elem (void) const { return (m_item ? m_item->elem : 0); } //------------------------------------------------------------------------- // class XGDrumKit - XG Drum Kit descriptor. // // Constructor. XGDrumKit::XGDrumKit ( unsigned short id ) : m_item(nullptr) { if (id < XGDrumKit::count()) m_item = &(DrumKitTab[id]); } // Descriptor acessor. const XGDrumKitItem *XGDrumKit::item (void) const { return m_item; } // Drum Kit property accessors. unsigned short XGDrumKit::bank (void) const { return (m_item ? m_item->bank : 0); } unsigned short XGDrumKit::prog (void) const { return (m_item ? (m_item->prog - 1): 0); } const char *XGDrumKit::name (void) const { return (m_item ? m_item->name : nullptr); } unsigned short XGDrumKit::size (void) const { return (m_item ? m_item->size : 0); } // Voice index finder. int XGDrumKit::find_voice ( unsigned short key ) const { if (m_item) { for (int i = 0; i < m_item->size; ++i) { if (m_item->keys[i].note == key) return i; } } return -1; } // Drum Kit list size (static). unsigned short XGDrumKit::count (void) { return TSIZE(DrumKitTab); } //------------------------------------------------------------------------- // class XGDrumVoice - XG Drum Voice descriptor. // // Constructor. XGDrumVoice::XGDrumVoice ( XGDrumKit *drumkit, unsigned short id ) : m_key(nullptr) { if (drumkit && drumkit->item() && id < drumkit->size()) m_key = &((drumkit->item())->keys[id]); } // Voice properties accessors. unsigned short XGDrumVoice::note (void) const { return (m_key ? m_key->note : 0); } const char *XGDrumVoice::name (void) const { return (m_key ? m_key->name : nullptr); } // Default values accessors. unsigned short XGDrumVoice::level (void) const { return (m_key ? m_key->level : 127); } unsigned short XGDrumVoice::group (void) const { return (m_key ? m_key->group : 0); } unsigned short XGDrumVoice::pan (void) const { return (m_key ? m_key->pan : 64); } unsigned short XGDrumVoice::reverb (void) const { return (m_key ? m_key->reverb : 127); } unsigned short XGDrumVoice::chorus (void) const { return (m_key ? m_key->chorus : 127); } unsigned short XGDrumVoice::noteOff (void) const { return (m_key ? m_key->noteOff : 0); } //------------------------------------------------------------------------- // class XGParam - XG Generic parameter descriptor. // Constructor. XGParam::XGParam ( unsigned short high, unsigned short mid, unsigned short low ) : m_param(nullptr), m_value(0), m_high(high), m_mid(mid), m_low(low), m_busy(false) { if (m_high == 0x00 && m_mid == 0x00) { // SYSTEM Parameter Change... m_param = SYSTEMParamItem(m_low); } else if (m_high == 0x02 && m_mid == 0x01) { // EFFECT Parameter Change... m_param = EFFECTParamItem(m_low); } else if (m_high == 0x08) { // MULTI PART Parameter Change... m_param = MULTIPARTParamItem(m_low); } else if (high == 0x30 || high == 0x31) { // DRUM SETUP Parameter Change... m_param = DRUMSETUPParamItem(m_low); } else if (high == 0x11) { // USER VOICE Parameter Change... m_param = USERVOICEParamItem( m_low >= 0x3d ? 0x3d + ((m_low - 0x3d) % 0x50) : m_low); } // Set initial defaults. if (m_param) m_value = XGParam::def(); } // Virtual destructor. XGParam::~XGParam (void) { m_busy = true; QListIterator iter(m_observers); while (iter.hasNext()) iter.next()->set_param(nullptr); m_observers.clear(); } // Address acessors. unsigned short XGParam::high (void) const { return m_high; } unsigned short XGParam::mid (void) const { return m_mid; } unsigned short XGParam::low (void) const { return m_low; } // Number of bytes needed to encode subject. unsigned short XGParam::size (void) const { return (m_param ? m_param->size : 0); } // Virtual accessors. const char *XGParam::name (void) const { return (m_param ? m_param->name : nullptr); } unsigned short XGParam::min (void) const { return (m_param ? m_param->min : 0); } unsigned short XGParam::max (void) const { return (m_param ? m_param->max : 0); } unsigned short XGParam::def (void) const { // Take care of very special, hardcoded cases, here... if (m_high == 0x08) { switch (m_low) { case 0x00: // MULTIPART Element Reserve. return (m_mid == 9 ? 0x00 : 0x02); case 0x01: // MULTIPART Bank MSB. return (m_mid == 9 ? 0x7f : 0x00); case 0x04: // MULTIPART Channel. return m_mid; case 0x07: // MULTIPART Part Mode. return (m_mid == 9 ? 0x02 : 0x00); } } return (m_param ? m_param->def : 0); } float XGParam::getv ( unsigned short u ) const { return (m_param && m_param->getv ? m_param->getv(u) : float(u)); } unsigned short XGParam::getu ( float v ) const { return (m_param && m_param->getu ? m_param->getu(v) : (unsigned short) (v)); } const char *XGParam::gets ( unsigned short u ) const { return (m_param && m_param->gets ? m_param->gets(u) : nullptr); } const char *XGParam::unit (void) const { return (m_param && m_param->unit ? m_param->unit() : nullptr); } // Encode raw data from param value (7bit). void XGParam::set_data_value ( unsigned char *data, unsigned short u ) const { const unsigned short n = size(); const unsigned short bits = (n > 2 ? 4 : 7); const unsigned short mask = (1 << bits) - 1; for (unsigned short i = 0; i < n; ++i) data[i] = (u >> (bits * (n - i - 1))) & mask; } // Decode param value from raw data (7bit). unsigned short XGParam::data_value ( unsigned char *data ) const { const unsigned short n = size(); const unsigned short bits = (n > 2 ? 4 : 7); unsigned short ret = 0; for (unsigned short i = 0; i < n; ++i) ret += (data[i] << (bits * (n - i - 1))); return ret; } // Encode raw data from param value (4bit). void XGParam::set_data_value2 ( unsigned char *data, unsigned short u ) const { const unsigned short n = size(); const unsigned short bits = 4; unsigned short mask = (1 << bits) - 1; for (unsigned short i = 0; i < n; ++i) data[i] = (u >> (bits * (n - i - 1))) & mask; } // Decode param value from raw data (4bit). unsigned short XGParam::data_value2 ( unsigned char *data ) const { const unsigned short n = size(); const unsigned short bits = 4; unsigned short ret = 0; for (unsigned short i = 0; i < n; ++i) ret += (data[i] << (bits * (n - i - 1))); return ret; } // Value accessors. void XGParam::set_value_update ( unsigned short u, XGParamObserver *sender ) { if (gets(min()) && !gets(u)) return; m_value = u; notify_update(sender); } void XGParam::set_value ( unsigned short u, XGParamObserver *sender ) { if (m_value == u) return; set_value_update(u, sender); } unsigned short XGParam::value (void) const { return m_value; } // Value reset (to default). void XGParam::reset ( XGParamObserver *sender ) { set_value(def(), sender); } // Busy flag predicate. bool XGParam::busy (void) const { return m_busy; } // Observer/view resetter. void XGParam::notify_reset ( XGParamObserver *sender ) { if (m_busy) return; m_busy = true; QListIterator iter(m_observers); while (iter.hasNext()) { XGParamObserver *observer = iter.next(); if (sender && sender == observer) continue; observer->reset(); } m_busy = false; } // Observer/view updater. void XGParam::notify_update ( XGParamObserver *sender ) { if (m_busy) return; m_busy = true; QListIterator iter(m_observers); while (iter.hasNext()) { XGParamObserver *observer = iter.next(); if (sender && sender == observer) continue; observer->update(); } m_busy = false; } // Observer list accessors. void XGParam::attach ( XGParamObserver *observer ) { m_observers.append(observer); } void XGParam::detach ( XGParamObserver *observer ) { m_observers.removeAll(observer); } const QList& XGParam::observers (void) const { return m_observers; } // Textual (name parsed) representations. QString XGParam::label (void) const { QString slabel; const char *plabel = name(); if (plabel) { slabel = plabel; slabel.remove(QRegularExpression("\\[[^\\]]*\\]")); } return slabel; } QString XGParam::text (void) const { QString stext; const char *ptext = name(); if (ptext) { stext = ptext; stext.remove('[').remove(']'); const char *punit = unit(); if (punit) stext += QString(" (%1)").arg(punit); } return stext; } // Value randomizer (p = percent deviation from v). void XGParam::randomize ( int v, float p ) { if (gets(v)) return; const int q = max() - min() + 1; if (q > 2) { const int r = min() + (::rand() % q); set_value(v + int(0.1f * p * float(r - v))); } } void XGParam::randomize_value ( float p ) { randomize(value(), p); } void XGParam::randomize_def ( float p ) { randomize(def(), p); } //------------------------------------------------------------------------- // class XGEffectParam - XG Effect parameter descriptor. // Constructor. XGEffectParam::XGEffectParam ( unsigned short high, unsigned short mid, unsigned short low, unsigned short etype) : XGParam(high, mid, low), m_etype(etype), m_eparam(nullptr) { if (m_param && m_param->name == nullptr) { const XGEffectItem *effect = nullptr; switch (m_param->min) { case 0: // REVERB... effect = REVERBEffectItem(m_etype); break; case 1: // CHORUS... effect = CHORUSEffectItem(m_etype); break; case 2: // VARIATION... effect = VARIATIONEffectItem(m_etype); break; } if (effect && effect->params) m_eparam = &(effect->params[m_param->max]); } // Re(set) initial defaults. if (m_eparam) m_value = XGEffectParam::def(); } // Sub-address accessors. unsigned short XGEffectParam::etype (void) const { return m_etype; } // Virtual accessors. const char *XGEffectParam::name (void) const { return (m_eparam ? m_eparam->name : XGParam::name()); } unsigned short XGEffectParam::min (void) const { return (m_eparam ? m_eparam->min : XGParam::min()); } unsigned short XGEffectParam::max (void) const { return (m_eparam ? m_eparam->max : XGParam::max()); } unsigned short XGEffectParam::def (void) const { if (m_param && m_param->name == nullptr) { switch (m_param->min) { case 0: return REVERBEffectDefault(m_etype, m_param->max); case 1: return CHORUSEffectDefault(m_etype, m_param->max); case 2: return VARIATIONEffectDefault(m_etype, m_param->max); } } return XGParam::def(); } float XGEffectParam::getv ( unsigned short u ) const { return (m_eparam && m_eparam->getv ? m_eparam->getv(u) : XGParam::getv(u)); } unsigned short XGEffectParam::getu ( float v ) const { return (m_eparam && m_eparam->getu ? m_eparam->getu(v) : XGParam::getu(v)); } const char *XGEffectParam::gets ( unsigned short u ) const { return (m_eparam && m_eparam->gets ? m_eparam->gets(u) : XGParam::gets(u)); } const char *XGEffectParam::unit (void) const { return (m_eparam && m_eparam->unit ? m_eparam->unit() : XGParam::unit()); } //------------------------------------------------------------------------- // class XGDataParam - XG Data parameter descriptor. // // Constructor. XGDataParam::XGDataParam ( unsigned short high, unsigned short mid, unsigned short low ) : XGParam(high, mid, low) { unsigned short n = size(); m_data = new unsigned char [n]; ::memset(m_data, ' ', n); } // Destructor. XGDataParam::~XGDataParam (void) { delete [] m_data; } // Data accessors. void XGDataParam::set_data ( unsigned char *data, unsigned short len, XGParamObserver *sender ) { const unsigned short n = size(); if (len > n) len = n; if (data && len > 0) ::memcpy(m_data, data, len); if (len < n) ::memset(m_data + len, ' ', n - len); notify_update(sender); } unsigned char *XGDataParam::data (void) const { return m_data; } // Data reset (to default). void XGDataParam::reset ( XGParamObserver *sender ) { set_data(nullptr, 0, sender); } //------------------------------------------------------------------------- // class XGParamMap - XG Parameter mapper. // // Constructor. XGParamMap::XGParamMap (void) : m_key_param(nullptr), m_key(0), m_elements(0), m_element(0) { m_observer = new XGParamMap::Observer(this); } // Destructor. XGParamMap::~XGParamMap (void) { delete m_observer; XGParamMap::const_iterator iter = XGParamMap::constBegin(); for (; iter != XGParamMap::constEnd(); ++iter) delete iter.value(); } // Append method. void XGParamMap::add_param ( XGParam *param, unsigned short key ) { XGParamSet *paramset = find_paramset(param->low()); paramset->insert(key, param); XGParamMasterMap *pMasterMap = XGParamMasterMap::getInstance(); if (pMasterMap) pMasterMap->add_param_map(param, this); } // Map finders. XGParam *XGParamMap::find_param ( unsigned short id ) { XGParamSet *paramset = find_paramset(id); if (paramset == nullptr) return nullptr; unsigned short key = current_key(); return (paramset->contains(key) ? paramset->value(key) : nullptr); } // Key param accessors. void XGParamMap::set_key_param ( XGParam *param ) { if (m_key_param) m_key_param->detach(m_observer); m_key_param = param; if (m_key_param) m_key_param->attach(m_observer); } XGParam *XGParamMap::key_param (void) const { return m_key_param; } // Key value accessors. void XGParamMap::set_current_key ( unsigned short key ) { if (m_key_param) { m_key_param->set_value(key); } else { m_key = key; notify_reset(); } } unsigned short XGParamMap::current_key () const { return (m_key_param ? m_key_param->value() : m_key); } // Param set/factory method. XGParamSet *XGParamMap::find_paramset ( unsigned short id ) { XGParamSet *paramset = nullptr; if (XGParamMap::contains(id)) { paramset = XGParamMap::value(id); } else { paramset = new XGParamSet(); XGParamMap::insert(id, paramset); } return paramset; } // Local observers notify (key change). void XGParamMap::notify_reset (void) { if (m_key_param) m_key = m_key_param->value(); unsigned short id0 = 0x3d + (m_element * 0x50); XGParamMap::const_iterator iter = XGParamMap::constBegin(); for (; iter != XGParamMap::constEnd(); ++iter) { unsigned short id = iter.key(); if (m_elements > 0 && id >= 0x3d && (id < id0 || id >= id0 + 0x50)) continue; XGParamSet *paramset = iter.value(); if (paramset->contains(m_key)) { XGParam *param = paramset->value(m_key); if (param) param->notify_reset(); } } } // Key/type name stuff. const XGParamMap::Keys& XGParamMap::keys (void) const { return m_keys; } void XGParamMap::add_key ( unsigned short key, const QString& name ) { m_keys.insert(key, name); } // Special element stride settings (USERVOICE, QS300). void XGParamMap::set_elements ( unsigned short elements ) { m_elements = elements; } unsigned short XGParamMap::elements (void) const { return m_elements; } // Element key value accessors. void XGParamMap::set_current_element ( unsigned short element ) { m_element = element; unsigned short key = current_key(); unsigned short id0 = 0x3d + (m_element * 0x50); XGParamMap::const_iterator iter = XGParamMap::constBegin(); for (; iter != XGParamMap::constEnd(); ++iter) { unsigned short id = iter.key(); if (id >= id0 && id < id0 + 0x50) { XGParamSet *paramset = iter.value(); if (paramset->contains(key)) { XGParam *param = paramset->value(key); if (param) param->notify_reset(); } } } } unsigned short XGParamMap::current_element (void) const { return m_element; } // All parameter reset (to default) void XGParamMap::reset ( XGParamObserver *sender ) { unsigned short key = current_key(); XGParamMap::const_iterator iter = XGParamMap::constBegin(); for (; iter != XGParamMap::constEnd(); ++iter) { XGParamSet *paramset = iter.value(); if (paramset->contains(key)) { XGParam *param = paramset->value(key); if (param) param->reset(sender); } } } // All parameter randomizer (p = percent from value/def). void XGParamMap::randomize_value ( int p ) { unsigned short key = current_key(); unsigned short id0 = 0x3d + (m_element * 0x50); XGParamMap::const_iterator iter = XGParamMap::constBegin(); for (; iter != XGParamMap::constEnd(); ++iter) { unsigned short id = iter.key(); if (m_elements > 0 && id >= 0x3d && (id < id0 || id >= id0 + 0x50)) continue; XGParamSet *paramset = iter.value(); if (paramset->contains(key)) { XGParam *param = paramset->value(key); if (param) param->randomize_value(p); } } } void XGParamMap::randomize_def ( int p ) { unsigned short key = current_key(); unsigned short id0 = 0x3d + (m_element * 0x50); XGParamMap::const_iterator iter = XGParamMap::constBegin(); for (; iter != XGParamMap::constEnd(); ++iter) { unsigned short id = iter.key(); if (m_elements > 0 && id >= 0x3d && (id < id0 || id >= id0 + 0x50)) continue; XGParamSet *paramset = iter.value(); if (paramset->contains(key)) { XGParam *param = paramset->value(key); if (param) param->randomize_def(p); } } } //------------------------------------------------------------------------- // class XGParamMasterMap - XG Parameter master state database. // // Pseudo-singleton reference. XGParamMasterMap *XGParamMasterMap::g_pParamMasterMap = nullptr; // Pseudo-singleton accessor (static). XGParamMasterMap *XGParamMasterMap::getInstance (void) { return g_pParamMasterMap; } // Constructor. XGParamMasterMap::XGParamMasterMap (void) { unsigned short i, j, k; // Initialize the randomizer seed... ::srand(::time(nullptr)); // XG SYSTEM... for (i = 0; i < TSIZE(SYSTEMParamTab); ++i) { XGParamItem *item = &SYSTEMParamTab[i]; XGParam *param = new XGParam(0x00, 0x00, item->id); XGParamMasterMap::add_param(param); SYSTEM.add_param(param, 0); } // XG EFFECT... for (i = 0; i < TSIZE(EFFECTParamTab); ++i) { XGParamItem *item = &EFFECTParamTab[i]; if (item->id > 0x00 && item->id < 0x20) { // REVERB... for (j = 0; j < TSIZE(REVERBEffectTab); ++j) { XGEffectItem *eitem = &REVERBEffectTab[j]; unsigned short etype = (eitem->msb << 7) + eitem->lsb; XGEffectParam *eparam = new XGEffectParam(0x02, 0x01, item->id, etype); XGParamMasterMap::add_param(eparam); REVERB.add_param(eparam, etype); } } else if (item->id > 0x20 && item->id < 0x40) { // CHORUS... for (j = 0; j < TSIZE(CHORUSEffectTab); ++j) { XGEffectItem *eitem = &CHORUSEffectTab[j]; unsigned short etype = (eitem->msb << 7) + eitem->lsb; XGEffectParam *eparam = new XGEffectParam(0x02, 0x01, item->id, etype); XGParamMasterMap::add_param(eparam); CHORUS.add_param(eparam, etype); } } else if (item->id > 0x40 && item->id < 0x80) { // VARIATION... for (j = 0; j < TSIZE(VARIATIONEffectTab); ++j) { XGEffectItem *eitem = &VARIATIONEffectTab[j]; unsigned short etype = (eitem->msb << 7) + eitem->lsb; XGEffectParam *eparam = new XGEffectParam(0x02, 0x01, item->id, etype); XGParamMasterMap::add_param(eparam); VARIATION.add_param(eparam, etype); } } else { // REVERB, CHORUS, VARIATION TYPE... XGParam *param = new XGParam(0x02, 0x01, item->id); XGParamMasterMap::add_param(param); switch (item->id) { case 0x00: REVERB.set_key_param(param); break; case 0x20: CHORUS.set_key_param(param); break; case 0x40: VARIATION.set_key_param(param); break; } } } // XG MULTI PART... MULTIPART.set_current_key(0); for (i = 0; i < TSIZE(MULTIPARTParamTab); ++i) { XGParamItem *item = &MULTIPARTParamTab[i]; for (j = 0; j < 16; ++j) { XGParam *param = new XGParam(0x08, j, item->id); XGParamMasterMap::add_param(param); MULTIPART.add_param(param, j); } } // XG DRUM SETUP... DRUMSETUP.set_current_key(36); // Drums 1, Bass Drum (C1). for (i = 0; i < TSIZE(DRUMSETUPParamTab); ++i) { XGParamItem *item = &DRUMSETUPParamTab[i]; for (j = 0; j < 2; ++j) { for (k = 13; k < 85; ++k) { XGParam *param = new XGParam(0x30 + j, k, item->id); XGParamMasterMap::add_param(param); DRUMSETUP.add_param(param, (j << 7) + k); } } } // QS300 USER VOICE... USERVOICE.set_elements(2); USERVOICE.set_current_key(0); // User 1. for (i = 0; i < TSIZE(USERVOICEParamTab); ++i) { XGParamItem *item = &USERVOICEParamTab[i]; for (k = 0; k < 32; ++k) { for (j = 0; j < 2; ++j) { if (item->id >= 0x3d || j == 0) { unsigned short id = item->id + (j * 0x50); if (item->size > 4) { XGDataParam *param = new XGDataParam(0x11, k, id); XGParamMasterMap::add_param(param); USERVOICE.add_param(param, k); } else { XGParam *param = new XGParam(0x11, k, id); XGParamMasterMap::add_param(param); USERVOICE.add_param(param, k); } } } } } // REVERB key names... for (i = 0; i < TSIZE(REVERBEffectTab); ++i) { XGEffectItem *item = &REVERBEffectTab[i]; REVERB.add_key((item->msb << 7) + item->lsb, item->name); } // CHORUS key names... for (i = 0; i < TSIZE(CHORUSEffectTab); ++i) { XGEffectItem *item = &CHORUSEffectTab[i]; CHORUS.add_key((item->msb << 7) + item->lsb, item->name); } // VARIATION key names... for (i = 0; i < TSIZE(VARIATIONEffectTab); ++i) { XGEffectItem *item = &VARIATIONEffectTab[i]; VARIATION.add_key((item->msb << 7) + item->lsb, item->name); } // NRPN parameter map... for (i = 0; i < TSIZE(NRPNParamTab); ++i) { XGRpnParamItem *item = &NRPNParamTab[i]; // MULTIPART NRPN map... if (item->hi == 0x08) { for (j = 0; j < 16; ++j) { // parts... XGParam *param = find_param(item->hi, j, item->lo); if (param) NRPN.insert(XGRpnParamKey(j, item->param), param); } } else // DRUMSETUP NRPN map... if (item->hi == 0x30) { for (j = 0; j < 2; ++j) { // drumsets... for (k = 13; k < 85; ++k) { // notes... XGParam *param = find_param(item->hi + j, k, item->lo); if (param) NRPN.insert(XGRpnParamKey(j, item->param + k), param); } } } } // Pseudo-singleton set. g_pParamMasterMap = this; } // Destructor. XGParamMasterMap::~XGParamMasterMap (void) { // Pseudo-singleton reset. g_pParamMasterMap = nullptr; XGParamMasterMap::const_iterator iter = XGParamMasterMap::constBegin(); for (; iter != XGParamMasterMap::constEnd(); ++iter) delete iter.value(); } // Master append method. void XGParamMasterMap::add_param ( XGParam *param ) { XGParamMasterMap::insert(XGParamKey(param), param); } // Add widget to map. void XGParamMasterMap::add_param_map ( XGParam *param, XGParamMap *map ) { m_params_map.insert(param, map); } // Master map finders. XGParam *XGParamMasterMap::find_param ( unsigned short high, unsigned short mid, unsigned short low ) const { unsigned short etype = 0; if (high == 0x02 && mid == 0x01) { if (low > 0x00 && low < 0x20) etype = REVERB.current_key(); else if (low > 0x20 && low < 0x40) etype = CHORUS.current_key(); else if (low > 0x40 && low < 0x80) etype = VARIATION.current_key(); } return find_param(XGParamKey(high, mid, low), etype); } XGParam *XGParamMasterMap::find_param ( const XGParamKey& key, unsigned short etype ) const { const QList& list = XGParamMasterMap::values(key); QListIterator iter(list); while (iter.hasNext()) { XGParam *param = iter.next(); if (key.high() == 0x02 && key.mid() == 0x01 && key.low() != 0x00 && key.low() != 0x20 && key.low() != 0x40) { XGEffectParam *eparam = static_cast (param); if (eparam->etype() == etype) return param; } else return param; } return nullptr; } // Find map from param. XGParamMap *XGParamMasterMap::find_param_map ( XGParam *param ) const { return (m_params_map.contains(param) ? m_params_map.value(param) : nullptr); } // end of XGParam.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditMidiDevice.h0000644000000000000000000000013214772452451016577 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditMidiDevice.h0000644000175000001440000000525214772452451016573 0ustar00rncbcusers// qxgeditMidiDevice.h // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditMidiDevice_h #define __qxgeditMidiDevice_h #include #include #include #include //---------------------------------------------------------------------------- // qxgeditMidiDevice -- MIDI Device interface object. class qxgeditMidiDevice : public QObject { Q_OBJECT public: // Constructor. qxgeditMidiDevice(const QString& sClientName); // Destructor. ~qxgeditMidiDevice(); // Pseudo-singleton reference. static qxgeditMidiDevice *getInstance(); // MIDI SysEx sender. void sendSysex(const QByteArray& sysex) const; void sendSysex(unsigned char *pSysex, unsigned short iSysex) const; // MIDI Input(readable) / Output(writable) device list QStringList inputs() const; QStringList outputs() const; // MIDI Input(readable) / Output(writable) connects. bool connectInputs(const QStringList& inputs) const; bool connectOutputs(const QStringList& outputs) const; // Emit received data signals. void emitReceiveRpn(unsigned char ch, unsigned short rpn, unsigned short val) { emit receiveRpn(ch, rpn, val); } void emitReceiveNrpn(unsigned char ch, unsigned short nrpn, unsigned short val) { emit receiveNrpn(ch, nrpn, val); } void emitReceiveSysex(const QByteArray& sysex) { emit receiveSysex(sysex); } // Forward decl. class Impl; signals: // Received data signals. void receiveRpn(unsigned char ch, unsigned short rpn, unsigned short val); void receiveNrpn(unsigned char ch, unsigned short nrpn, unsigned short val); void receiveSysex(const QByteArray& sysex); private: // Name says it all. Impl *m_pImpl; // Pseudo-singleton reference. static qxgeditMidiDevice *g_pMidiDevice; }; #endif // __qxgeditMidiDevice_h // end of qxgeditMidiDevice.h qxgedit-1.0.1/src/PaxHeaders/qxgeditFilter.cpp0000644000000000000000000000013214772452451016355 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditFilter.cpp0000644000175000001440000001252514772452451016352 0ustar00rncbcusers// qxgeditFilter.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditFilter.h" #include #include #include //---------------------------------------------------------------------------- // qxgeditFilter -- Custom widget // Constructor. qxgeditFilter::qxgeditFilter ( QWidget *pParent ) : QFrame(pParent), m_iCutoff(0), m_iResonance(0), m_iMaxCutoff(127), m_iMaxResonance(127), m_bDragging(false) { setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditFilter::~qxgeditFilter (void) { } // Parameter accessors. void qxgeditFilter::setCutoff ( unsigned short iCutoff ) { if (iCutoff > m_iMaxCutoff) iCutoff = m_iMaxCutoff; if (m_iCutoff != iCutoff) { m_iCutoff = iCutoff; update(); emit cutoffChanged(cutoff()); } } unsigned short qxgeditFilter::cutoff (void) const { return m_iCutoff; } void qxgeditFilter::setResonance ( unsigned short iResonance ) { if (iResonance > m_iMaxResonance) iResonance = m_iMaxResonance; if (m_iResonance != iResonance) { m_iResonance = iResonance; update(); emit resonanceChanged(resonance()); } } unsigned short qxgeditFilter::resonance (void) const { return m_iResonance; } // Parameter range modifiers. void qxgeditFilter::setMaxCutoff ( unsigned short iMaxCutoff ) { m_iMaxCutoff = iMaxCutoff; } unsigned short qxgeditFilter::maxCutoff (void) const { return m_iMaxCutoff; } void qxgeditFilter::setMaxResonance ( unsigned short iMaxResonance ) { m_iMaxResonance = iMaxResonance; } unsigned short qxgeditFilter::maxResonance (void) const { return m_iMaxResonance; } // Draw curve. void qxgeditFilter::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = h >> 1; const int h4 = h >> 2; const int w4 = w >> 2; const int w8 = w >> 3; const int x = w8 + int((m_iCutoff * (w - w4)) / (m_iMaxCutoff + 1)); const int y = h2 - int((m_iResonance * (h + h4)) / (m_iMaxResonance + 1)); QPolygon poly(6); poly.putPoints(0, 6, 0, h2, x - w8, h2, x, h2, x, y, x + w8, h, 0, h); QPainterPath path; path.moveTo(poly.at(0)); path.lineTo(poly.at(1)); path.cubicTo(poly.at(2), poly.at(3), poly.at(4)); path.lineTo(poly.at(5)); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); QLinearGradient grad(0, 0, w << 1, h << 1); grad.setColorAt(0.0f, rgbLite); grad.setColorAt(1.0f, Qt::black); painter.setBrush(grad); painter.drawPath(path); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Cutoff (%1) Resonance (%2)") .arg(int(cutoff())) .arg(int(resonance()))); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Drag/move curve. void qxgeditFilter::dragCurve ( const QPoint& pos ) { int iCutoff = int(m_iCutoff) + ((pos.x() - m_posDrag.x()) * (m_iMaxCutoff + 1) * 3) / (width() << 1); int iResonance = int(m_iResonance) + ((m_posDrag.y() - pos.y()) * (m_iMaxResonance + 1)) / (height() >> 1); if (iCutoff < 0) iCutoff = 0; else if (iCutoff > m_iMaxCutoff) iCutoff = m_iMaxCutoff; if (iResonance < 0) iResonance = 0; else if (iResonance > m_iMaxResonance) iResonance = m_iMaxResonance; if (m_iCutoff != (unsigned short) iCutoff || m_iResonance != (unsigned short) iResonance) { m_posDrag = pos; setCutoff(iCutoff); setResonance(iResonance); } } // Mouse interaction. void qxgeditFilter::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) m_posDrag = pMouseEvent->pos(); QFrame::mousePressEvent(pMouseEvent); } void qxgeditFilter::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { const QPoint& pos = pMouseEvent->pos(); if (m_bDragging) { dragCurve(pos); } else { // if ((pos - m_posDrag).manhattanLength() > 4) setCursor(Qt::SizeAllCursor); m_bDragging = true; } } void qxgeditFilter::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); if (m_bDragging) { dragCurve(pMouseEvent->pos()); m_bDragging = false; unsetCursor(); } } // end of qxgeditFilter.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditKnob.h0000644000000000000000000000013214772452451015466 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditKnob.h0000644000175000001440000000515614772452451015465 0ustar00rncbcusers// qxgeditKnob.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditKnob_h #define __qxgeditKnob_h #include //------------------------------------------------------------------------- // qxgeditKnob - A better QDial for everybody class qxgeditKnob : public QDial { Q_OBJECT Q_PROPERTY(int defaultValue READ getDefaultValue WRITE setDefaultValue) Q_PROPERTY(DialMode dialMode READ getDialMode WRITE setDialMode) Q_ENUMS(DialMode) public: // Constructor. qxgeditKnob(QWidget *pParent = nullptr); // Destructor. ~qxgeditKnob(); int getDefaultValue() const { return m_iDefaultValue; } // Knob dial mode behavior: // DefaultMode - default (old) QDial behavior. // AngularMode - angularly relative to widget center. // LinearMode - proportionally to distance in one ortogonal axis. enum DialMode { DefaultMode, AngularMode, LinearMode }; DialMode getDialMode() const { return m_dialMode; } public slots: // Set default (mid) value. void setDefaultValue(int iDefaultValue); // Set knob dial mode behavior. void setDialMode(DialMode dialMode); protected: // Mouse angle determination. float mouseAngle(const QPoint& pos); // Alternate mouse behavior event handlers. virtual void mousePressEvent(QMouseEvent *pMouseEvent); virtual void mouseMoveEvent(QMouseEvent *pMouseEvent); virtual void mouseReleaseEvent(QMouseEvent *pMouseEvent); virtual void wheelEvent(QWheelEvent *pWheelEvent); private: // Default (mid) value. int m_iDefaultValue; // Knob dial mode behavior. DialMode m_dialMode; // Alternate mouse behavior tracking. bool m_bMousePressed; QPoint m_posMouse; // Just for more precission on the movement float m_fLastDragValue; }; #endif // __qxgeditKnob_h // end of qxgeditKnob.h qxgedit-1.0.1/src/PaxHeaders/qxgeditDial.h0000644000000000000000000000013214772452451015446 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditDial.h0000644000175000001440000000446714772452451015451 0ustar00rncbcusers// qxgeditDial.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditDial_h #define __qxgeditDial_h #include "XGParamWidget.h" #include // Forward declarations. class QLabel; class qxgeditKnob; class qxgeditSpin; class qxgeditDrop; //------------------------------------------------------------------------- // qxgeditDial - Custom composite widget. class qxgeditDial : public XGParamWidget { Q_OBJECT public: // Constructor. qxgeditDial(QWidget *pParent = 0); // Destructor. ~qxgeditDial(); // Specialty parameter accessors. void set_param(XGParam *pParam, Observer *pSender); XGParam *param() const; // Value accessors. void reset_value(); void set_value_update(unsigned short iValue); void set_value(unsigned short iValue, Observer *pSender); unsigned short value() const; // Special value text accessor. void setSpecialValueText(const QString& sText); QString specialValueText() const; signals: // Value change signal. void valueChanged(unsigned short); public slots: // Value settler. void setValue(unsigned short); protected slots: // Internal widget slots. void knobValueChanged(int); void spinValueChanged(unsigned short); void dropValueChanged(unsigned short); private: // Widget members. QLabel *m_pLabel; qxgeditKnob *m_pKnob; qxgeditSpin *m_pSpin; qxgeditDrop *m_pDrop; // Fake-mutex. int m_iBusy; }; #endif // __qxgeditDial_h // end of qxgeditDial.h qxgedit-1.0.1/src/PaxHeaders/qxgeditEdit.h0000644000000000000000000000013214772452451015462 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditEdit.h0000644000175000001440000000456114772452451015460 0ustar00rncbcusers// qxgeditEdit.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditEdit_h #define __qxgeditEdit_h #include "XGParamWidget.h" #include // Forward declarations. class QComboBox; class QToolButton; //------------------------------------------------------------------------- // qxgeditEdit - Custom edit-box widget. class qxgeditEdit : public XGParamWidget { Q_OBJECT public: // Constructor. qxgeditEdit(QWidget *pParent = 0); // Destructor. ~qxgeditEdit(); // Specialty parameter accessors. void set_param(XGParam *pParam, Observer *pSender); XGParam *param() const; // Value accessors. void set_value(unsigned short iValue, Observer *pSender); unsigned short value() const; signals: void loadPresetFile(const QString&); void savePresetFile(const QString&); public slots: void stabilizePreset(); protected slots: // Internal widget slots. void changePreset(const QString&); void openPreset(); void savePreset(); void removePreset(); protected: QString presetName() const; bool queryPreset(); void loadPreset(const QString&); void savePreset(const QString&); void refreshPreset(); static QString presetGroup(); private: // Instance variables. XGDataParam *m_pParam; // Widget members. QComboBox *m_pComboBox; QToolButton *m_pOpenButton; QToolButton *m_pSaveButton; QToolButton *m_pRemoveButton; // Widget internal state. int m_iUpdatePreset; int m_iDirtyPreset; }; #endif // __qxgeditEdit_h // end of qxgeditEdit.h qxgedit-1.0.1/src/PaxHeaders/CMakeLists.txt0000644000000000000000000000013214772452451015576 xustar0030 mtime=1743410473.473607941 30 atime=1743410473.473607941 30 ctime=1743410473.473607941 qxgedit-1.0.1/src/CMakeLists.txt0000644000175000001440000001047414772452451015574 0ustar00rncbcusers# project (qxgedit) set (CMAKE_INCLUDE_CURRENT_DIR ON) set (CMAKE_AUTOUIC ON) set (CMAKE_AUTOMOC ON) set (CMAKE_AUTORCC ON) if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h) file (REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/config.h) endif () configure_file (config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) set (HEADERS XGParam.h XGParamObserver.h XGParamWidget.h XGParamSysex.h qxgeditXGMasterMap.h qxgeditAbout.h qxgeditAmpEg.h qxgeditCheck.h qxgeditCombo.h qxgeditDial.h qxgeditDrop.h qxgeditDrumEg.h qxgeditEdit.h qxgeditFilter.h qxgeditKnob.h qxgeditPartEg.h qxgeditPitch.h qxgeditScale.h qxgeditSpin.h qxgeditUserEg.h qxgeditVibra.h qxgeditMidiDevice.h qxgeditMidiRpn.h qxgeditOptions.h qxgeditOptionsForm.h qxgeditPaletteForm.h qxgeditMainForm.h qxgedit.h ) set (SOURCES XGParam.cpp XGParamObserver.cpp XGParamWidget.cpp XGParamSysex.cpp qxgeditXGMasterMap.cpp qxgeditAmpEg.cpp qxgeditCheck.cpp qxgeditCombo.cpp qxgeditDial.cpp qxgeditDrop.cpp qxgeditDrumEg.cpp qxgeditEdit.cpp qxgeditFilter.cpp qxgeditKnob.cpp qxgeditPartEg.cpp qxgeditPitch.cpp qxgeditScale.cpp qxgeditSpin.cpp qxgeditUserEg.cpp qxgeditVibra.cpp qxgeditMidiDevice.cpp qxgeditMidiRpn.cpp qxgeditOptions.cpp qxgeditOptionsForm.cpp qxgeditPaletteForm.cpp qxgeditMainForm.cpp qxgedit.cpp ) set (FORMS qxgeditOptionsForm.ui qxgeditPaletteForm.ui qxgeditMainForm.ui ) set (RESOURCES qxgedit.qrc ) if (WIN32) set (RC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/win32/${PROJECT_NAME}.rc) set (RES_FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.res.obj) find_program (WINDRES_EXECUTABLE NAMES windres mingw32-windres i686-mingw32-windres) if (MINGW) exec_program (${WINDRES_EXECUTABLE} ARGS "-i ${RC_FILE} -o ${RES_FILE} --include-dir=${CMAKE_CURRENT_SOURCE_DIR}/images") list (APPEND SOURCES ${RES_FILE}) else () list (APPEND SOURCES ${RC_FILE}) endif () endif () if (APPLE) set (ICON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/images/${PROJECT_NAME}.icns) list (APPEND SOURCES ${ICON_FILE}) set (MACOSX_BUNDLE_ICON_FILE ${PROJECT_NAME}.icns) set_source_files_properties (${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) endif () add_executable (${PROJECT_NAME} ${HEADERS} ${SOURCES} ${FORMS} ${RESOURCES} ) # Add some debugger flags. if (CONFIG_DEBUG AND UNIX AND NOT APPLE) set (CONFIG_DEBUG_OPTIONS -g -fsanitize=address -fno-omit-frame-pointer) target_compile_options (${PROJECT_NAME} PRIVATE ${CONFIG_DEBUG_OPTIONS}) target_link_options (${PROJECT_NAME} PRIVATE ${CONFIG_DEBUG_OPTIONS}) endif () set_target_properties (${PROJECT_NAME} PROPERTIES CXX_STANDARD 17) if (WIN32) set_target_properties (${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE true) endif () if (APPLE) set_target_properties (${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE true) endif () target_link_libraries (${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Svg) if (CONFIG_XUNIQUE) target_link_libraries (${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Network) endif () if (CONFIG_ALSA_MIDI) target_link_libraries (${PROJECT_NAME} PRIVATE PkgConfig::ALSA) endif () if (CONFIG_RTMIDI) target_link_libraries (${PROJECT_NAME} PRIVATE PkgConfig::RTMIDI) endif () if (UNIX AND NOT APPLE) install (TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install (FILES images/${PROJECT_NAME}.png RENAME org.rncbc.${PROJECT_NAME}.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/32x32/apps) install (FILES images/${PROJECT_NAME}.svg RENAME org.rncbc.${PROJECT_NAME}.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) install (FILES appdata/org.rncbc.${PROJECT_NAME}.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) install (FILES appdata/org.rncbc.${PROJECT_NAME}.metainfo.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) install (FILES man1/${PROJECT_NAME}.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) install (FILES man1/${PROJECT_NAME}.fr.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/fr/man1 RENAME ${PROJECT_NAME}.1) install (FILES palette/KXStudio.conf palette/Wonton\ Soup.conf DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/palette) endif () if (WIN32) install (TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif () qxgedit-1.0.1/src/PaxHeaders/qxgeditOptionsForm.h0000644000000000000000000000013214772452451017054 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditOptionsForm.h0000644000175000001440000000412214772452451017043 0ustar00rncbcusers// qxgeditOptionsForm.h // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditOptionsForm_h #define __qxgeditOptionsForm_h #include "ui_qxgeditOptionsForm.h" // Forward declarations... class qxgeditOptions; //---------------------------------------------------------------------------- // qxgeditOptionsForm -- UI wrapper form. class qxgeditOptionsForm : public QDialog { Q_OBJECT public: // Constructor. qxgeditOptionsForm(QWidget *pParent = nullptr); // Destructor. ~qxgeditOptionsForm(); void setOptions(qxgeditOptions *pOptions); qxgeditOptions *options() const; protected slots: void accept(); void reject(); void changed(); void editColorThemes(); void midiInputsChanged(); void midiOutputsChanged(); void stabilizeForm(); protected: // Custom color/style themes settlers. void resetColorThemes(const QString& sColorTheme); void resetStyleThemes(const QString& sStyleTheme); private: // The Qt-designer UI struct... Ui::qxgeditOptionsForm m_ui; // Instance variables... qxgeditOptions *m_pOptions; int m_iDirtyCount; // MIDI specialties. int m_iMidiInputsChanged; int m_iMidiOutputsChanged; }; #endif // __qxgeditOptionsForm_h // end of qxgeditOptionsForm.h qxgedit-1.0.1/src/PaxHeaders/qxgeditScale.h0000644000000000000000000000013214772452451015624 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditScale.h0000644000175000001440000000612114772452451015614 0ustar00rncbcusers// qxgeditScale.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditScale_h #define __qxgeditScale_h #include //---------------------------------------------------------------------------- // qxgeditScale -- Custom widget class qxgeditScale : public QFrame { Q_OBJECT public: // Constructor. qxgeditScale(QWidget *pParent = nullptr); // Destructor. ~qxgeditScale(); // Parameter getters. unsigned short break1() const; unsigned short break2() const; unsigned short break3() const; unsigned short break4() const; unsigned short offset1() const; unsigned short offset2() const; unsigned short offset3() const; unsigned short offset4() const; public slots: // Parameter setters. void setBreak1(unsigned short iBreak1); void setBreak2(unsigned short iBreak2); void setBreak3(unsigned short iBreak3); void setBreak4(unsigned short iBreak4); void setOffset1(unsigned short iOffset1); void setOffset2(unsigned short iOffset2); void setOffset3(unsigned short iOffset3); void setOffset4(unsigned short iOffset4); signals: // Parameter change signals. void break1Changed(unsigned short iBreak1); void break2Changed(unsigned short iBreak2); void break3Changed(unsigned short iBreak3); void break4Changed(unsigned short iBreak4); void offset1Changed(unsigned short iOffset1); void offset2Changed(unsigned short iOffset2); void offset3Changed(unsigned short iOffset3); void offset4Changed(unsigned short iOffset4); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iBreak1; unsigned short m_iBreak2; unsigned short m_iBreak3; unsigned short m_iBreak4; unsigned short m_iOffset1; unsigned short m_iOffset2; unsigned short m_iOffset3; unsigned short m_iOffset4; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditScale_h // end of qxgeditScale.h qxgedit-1.0.1/src/PaxHeaders/qxgeditDrumEg.h0000644000000000000000000000013214772452451015760 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditDrumEg.h0000644000175000001440000000455014772452451015754 0ustar00rncbcusers// qxgeditDrumEg.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditDrumEg_h #define __qxgeditDrumEg_h #include //---------------------------------------------------------------------------- // qxgeditDrumEg -- Custom widget class qxgeditDrumEg : public QFrame { Q_OBJECT public: // Constructor. qxgeditDrumEg(QWidget *pParent = nullptr); // Destructor. ~qxgeditDrumEg(); // Parameter getters. unsigned short attack() const; unsigned short decay1() const; unsigned short decay2() const; public slots: // Parameter setters. void setAttack(unsigned short iAttack); void setDecay1(unsigned short iDecay1); void setDecay2(unsigned short iDecay2); signals: // Parameter change signals. void attackChanged(unsigned short iAttack); void decay1Changed(unsigned short iDecay1); void decay2Changed(unsigned short iDecay2); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iAttack; unsigned short m_iDecay1; unsigned short m_iDecay2; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditDrumEg_h // end of qxgeditDrumEg.h qxgedit-1.0.1/src/PaxHeaders/qxgeditXGMasterMap.h0000644000000000000000000000013214772452451016725 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditXGMasterMap.h0000644000175000001440000001023314772452451016714 0ustar00rncbcusers// qxgeditXGMasterMap.h // /**************************************************************************** Copyright (C) 2005-2021, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditXGMasterMap_h #define __qxgeditXGMasterMap_h #include "XGParam.h" #include //---------------------------------------------------------------------------- // qxgeditXGMasterMap -- XGParam master map. // class qxgeditXGMasterMap : public XGParamMasterMap { public: // Constructor. qxgeditXGMasterMap(); // Destructor. ~qxgeditXGMasterMap(); // Singleton (re)cast. static qxgeditXGMasterMap *getInstance(); // Direct RPN value receiver. bool set_rpn_value(unsigned char ch, unsigned short rpn, unsigned short val, bool bNotify = false); // Direct NRPN value receiver. bool set_nrpn_value(unsigned char ch, unsigned short nrpn, unsigned short val, bool bNotify = false); // Direct SysEx data receiver. typedef QMultiMap SysexData; bool add_sysex_data(SysexData& sysex_data, unsigned char *data, unsigned short len); bool set_sysex_data(const SysexData& sysex_data, bool bNotify = false); // Direct parameter data access. bool set_param_data( XGParam *pParam, unsigned char *data, bool bNotify = false); // All parameter reset (to default) void reset_all(); // Part reset (to default) void reset_part(unsigned short iPart); // Drums reset (to default) void reset_drums(unsigned short iDrumSet); // User voice reset (to default) void reset_user(unsigned short iUser); // Send regular XG Parameter change SysEx message. void send_param(XGParam *pParam); // Send Multi Part Bank Select/Program Number SysEx messages. void send_part(unsigned short iPart) const; // Send (QS300) USERVOICE Bulk Dump SysEx message. void send_user(unsigned short iUser) const; // MULTPART dirty slot simple managers. void reset_part_dirty(); void set_part_dirty(unsigned short iPart, bool bDirty); bool part_dirty(unsigned short iPart) const; // (QS300) USERVOICE dirty slot simple managers. void reset_user_dirty(); void set_user_dirty(unsigned short iUser, bool bDirty); bool user_dirty(unsigned short iUser) const; void set_user_dirty_1(unsigned short iUser, bool bDirty); bool user_dirty_1(unsigned short iUser) const; void set_user_dirty_2(unsigned short iUser, bool bDirty); bool user_dirty_2(unsigned short iUser) const; // (QS300) USERVOICE bulk dump auto-send feature. void set_auto_send(bool bAuto); bool auto_send() const; // Part randomize (from value/def) void randomize_part(unsigned short iPart, float p = 20.0f); // Drums randomize (from value/def) void randomize_drums( unsigned short iDrumSet, unsigned short iDrumKey, float p = 20.0f); // User voice randomize (from value/def) void randomize_user(unsigned short iUser, float p = 20.0f); private: // Simple XGParam observer. class Observer : public XGParamObserver { public: // Constructor. Observer(XGParam *pParam); protected: // View updater (observer callback). void reset(); void update(); }; // Local observer map. typedef QHash ObserverMap; // Instance variables. ObserverMap m_observers; // Multi Part dirty flag array. int m_part_dirty[16]; // QS300 User Voice dirty flag array. int m_user_dirty[32]; // QS300 User Voice auto-send feature. bool m_auto_send; }; #endif // __qxgeditXGMasterMap_h // end of qxgeditXGMasterMap.h qxgedit-1.0.1/src/PaxHeaders/qxgeditAbout.h0000644000000000000000000000013214772452451015647 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditAbout.h0000644000175000001440000000246014772452451015641 0ustar00rncbcusers// qxgeditAbout.h // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditAbout_h #define __qxgeditAbout_h #include "config.h" #define QXGEDIT_TITLE PROJECT_TITLE #define QXGEDIT_SUBTITLE PROJECT_DESCRIPTION #define QXGEDIT_WEBSITE PROJECT_HOMEPAGE_URL #define QXGEDIT_COPYRIGHT PROJECT_COPYRIGHT #define QXGEDIT_DOMAIN PROJECT_DOMAIN #endif // __qxgeditAbout_h // end of qxgeditAbout.h qxgedit-1.0.1/src/PaxHeaders/qxgeditMidiRpn.h0000644000000000000000000000013214772452451016137 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditMidiRpn.h0000644000175000001440000000313214772452451016126 0ustar00rncbcusers// qxgeditMidiRpn.h // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditMidiRpn_h #define __qxgeditMidiRpn_h //--------------------------------------------------------------------- // qxgeditMidiRpn - decl. class qxgeditMidiRpn { public: qxgeditMidiRpn(); ~qxgeditMidiRpn(); enum Type { None = 0, CC = 0x10, RPN = 0x20, NRPN = 0x30, CC14 = 0x40 }; struct Event { unsigned long time; int port; unsigned char status; unsigned short param; unsigned short value; }; bool isPending() const; bool process(const Event& event); bool dequeue(Event& event); void flush(); private: class Impl; Impl *m_pImpl; }; #endif // __qxgeditMidiRpn_h // end of qxgeditMidiRpn.h qxgedit-1.0.1/src/PaxHeaders/qxgeditOptions.cpp0000644000000000000000000000013214772452451016563 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditOptions.cpp0000644000175000001440000002575014772452451016564 0ustar00rncbcusers// qxgeditOptions.cpp // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditOptions.h" #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) #include #include #if defined(Q_OS_WINDOWS) #include #endif #endif #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include #endif //------------------------------------------------------------------------- // qxgeditOptions - Prototype settings structure (pseudo-singleton). // // Singleton instance pointer. qxgeditOptions *qxgeditOptions::g_pOptions = nullptr; // Singleton instance accessor (static). qxgeditOptions *qxgeditOptions::getInstance (void) { return g_pOptions; } // Constructor. qxgeditOptions::qxgeditOptions (void) : m_settings(QXGEDIT_DOMAIN, QXGEDIT_TITLE) { // Pseudo-singleton reference setup. g_pOptions = this; loadOptions(); } // Default Destructor. qxgeditOptions::~qxgeditOptions (void) { saveOptions(); // Pseudo-singleton reference shut-down. g_pOptions = nullptr; } // Explicit load method. void qxgeditOptions::loadOptions (void) { // And go into general options group. m_settings.beginGroup("/Options"); // MIDI specific options... m_settings.beginGroup("/Midi"); midiInputs = m_settings.value("/Inputs").toStringList(); midiOutputs = m_settings.value("/Outputs").toStringList(); m_settings.endGroup(); // Load display options... m_settings.beginGroup("/Display"); bConfirmReset = m_settings.value("/ConfirmReset", true).toBool(); bConfirmRemove = m_settings.value("/ConfirmRemove", true).toBool(); bCompletePath = m_settings.value("/CompletePath", true).toBool(); iMaxRecentFiles = m_settings.value("/MaxRecentFiles", 5).toInt(); fRandomizePercent = m_settings.value("/RandomizePercent", 20.0f).toFloat(); iBaseFontSize = m_settings.value("/BaseFontSize", 0).toInt(); sStyleTheme = m_settings.value("/StyleTheme", "Skulpture").toString(); sColorTheme = m_settings.value("/ColorTheme").toString(); m_settings.endGroup(); // And go into view options group. m_settings.beginGroup("/View"); bMenubar = m_settings.value("/Menubar", true).toBool(); bStatusbar = m_settings.value("/Statusbar", true).toBool(); bToolbar = m_settings.value("/Toolbar", true).toBool(); m_settings.endGroup(); m_settings.endGroup(); // End of options group. // Last but not least, get the defaults. m_settings.beginGroup("/Default"); sSessionDir = m_settings.value("/SessionDir").toString(); sPresetDir = m_settings.value("/PresetDir").toString(); recentFiles = m_settings.value("/RecentFiles").toStringList(); m_settings.endGroup(); // (QS300) USER VOICE Specific options. m_settings.beginGroup("/Uservoice"); bUservoiceAutoSend = m_settings.value("/AutoSend", false).toBool(); m_settings.endGroup(); } // Explicit save method. void qxgeditOptions::saveOptions (void) { // Make program version available in the future. m_settings.beginGroup("/Program"); m_settings.setValue("/Version", PROJECT_VERSION); m_settings.endGroup(); // And go into general options group. m_settings.beginGroup("/Options"); // MIDI specific options... m_settings.beginGroup("/Midi"); m_settings.setValue("/Inputs", midiInputs); m_settings.setValue("/Outputs", midiOutputs); m_settings.endGroup(); // Save display options. m_settings.beginGroup("/Display"); m_settings.setValue("/ConfirmReset", bConfirmReset); m_settings.setValue("/ConfirmRemove", bConfirmRemove); m_settings.setValue("/CompletePath", bCompletePath); m_settings.setValue("/MaxRecentFiles", iMaxRecentFiles); m_settings.setValue("/RandomizePercent", fRandomizePercent); m_settings.setValue("/BaseFontSize", iBaseFontSize); m_settings.setValue("/StyleTheme", sStyleTheme); m_settings.setValue("/ColorTheme", sColorTheme); m_settings.endGroup(); // View options group. m_settings.beginGroup("/View"); m_settings.setValue("/Menubar", bMenubar); m_settings.setValue("/Statusbar", bStatusbar); m_settings.setValue("/Toolbar", bToolbar); m_settings.endGroup(); m_settings.endGroup(); // End of options group. // Default directories. m_settings.beginGroup("/Default"); m_settings.setValue("/SessionDir", sSessionDir); m_settings.setValue("/PresetDir", sPresetDir); m_settings.setValue("/RecentFiles", recentFiles); m_settings.endGroup(); // (QS300) USER VOICE Specific options. m_settings.beginGroup("/Uservoice"); m_settings.setValue("/AutoSend", bUservoiceAutoSend); m_settings.endGroup(); // Save/commit to disk. m_settings.sync(); } //------------------------------------------------------------------------- // Settings accessor. // QSettings& qxgeditOptions::settings (void) { return m_settings; } //------------------------------------------------------------------------- // Command-line argument stuff. // #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) void qxgeditOptions::show_error( const QString& msg ) { #if defined(Q_OS_WINDOWS) QMessageBox::information(nullptr, QApplication::applicationName(), msg); #else const QByteArray tmp = msg.toUtf8() + '\n'; ::fputs(tmp.constData(), stderr); #endif } #else // Help about command line options. void qxgeditOptions::print_usage ( const QString& arg0 ) { QTextStream out(stderr); const QString sEot = "\n\t"; const QString sEol = "\n\n"; out << QObject::tr("Usage: %1 [options] [session-file]").arg(arg0) + sEol; out << QXGEDIT_TITLE " - " + QObject::tr(QXGEDIT_SUBTITLE) + sEol; out << QObject::tr("Options:") + sEol; out << " -h, --help" + sEot + QObject::tr("Show help about command line options.") + sEol; out << " -v, --version" + sEot + QObject::tr("Show version information") + sEol; } #endif // Parse command line arguments into m_settings. bool qxgeditOptions::parse_args ( const QStringList& args ) { #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) QCommandLineParser parser; parser.setApplicationDescription( QXGEDIT_TITLE " - " + QObject::tr(QXGEDIT_SUBTITLE)); const QCommandLineOption& helpOption = parser.addHelpOption(); const QCommandLineOption& versionOption = parser.addVersionOption(); parser.addPositionalArgument("session-file", QObject::tr("Session file (.syx)"), QObject::tr("[session-file]")); if (!parser.parse(args)) { show_error(parser.errorText()); return false; } if (parser.isSet(helpOption)) { show_error(parser.helpText()); return false; } if (parser.isSet(versionOption)) { QString sVersion = QString("%1 %2\n") .arg(QXGEDIT_TITLE) .arg(QCoreApplication::applicationVersion()); sVersion += QString("Qt: %1").arg(qVersion()); #if defined(QT_STATIC) sVersion += "-static"; #endif sVersion += '\n'; show_error(sVersion); return false; } foreach (const QString& sArg, parser.positionalArguments()) { sessionFiles.append(QFileInfo(sArg).absoluteFilePath()); } #else int iCmdArgs = 0; QTextStream out(stderr); const QString sEol = "\n\n"; const int argc = args.count(); for (int i = 1; i < argc; ++i) { QString sArg = args.at(i); if (iCmdArgs > 0) { sessionFiles.append(QFileInfo(sArg).absoluteFilePath()); ++iCmdArgs; continue; } if (sArg == "-h" || sArg == "--help") { print_usage(args.at(0)); return false; } else if (sArg == "-v" || sArg == "--version") { out << QString("%1: %2\n") .arg(QXGEDIT_TITLE) .arg(PROJECT_VERSION); out << QString("Qt: %1").arg(qVersion()); #if defined(QT_STATIC) out << "-static"; #endif out << '\n'; return false; } else { // If we don't have one by now, // this will be the startup session file... sessionFiles.append(QFileInfo(sArg).absoluteFilePath()); ++iCmdArgs; } } #endif // Alright with argument parsing. return true; } //--------------------------------------------------------------------------- // Widget geometry persistence helper methods. void qxgeditOptions::loadWidgetGeometry ( QWidget *pWidget, bool bVisible ) { // Try to restore old form window positioning. if (pWidget) { // if (bVisible) pWidget->show(); -- force initial exposure? m_settings.beginGroup("/Geometry/" + pWidget->objectName()); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) const QByteArray& geometry = m_settings.value("/geometry").toByteArray(); if (!geometry.isEmpty()) pWidget->restoreGeometry(geometry); if (geometry.isEmpty()) { QWidget *pParent = pWidget->parentWidget(); if (pParent) pParent = pParent->window(); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (pParent == nullptr) pParent = QApplication::desktop(); #endif if (pParent) { QRect wrect(pWidget->geometry()); wrect.moveCenter(pParent->geometry().center()); pWidget->move(wrect.topLeft()); } } else { pWidget->restoreGeometry(geometry); } #else//--LOAD_OLD_GEOMETRY QPoint wpos; QSize wsize; wpos.setX(m_settings.value("/x", -1).toInt()); wpos.setY(m_settings.value("/y", -1).toInt()); wsize.setWidth(m_settings.value("/width", -1).toInt()); wsize.setHeight(m_settings.value("/height", -1).toInt()); if (wpos.x() > 0 && wpos.y() > 0) pWidget->move(wpos); if (wsize.width() > 0 && wsize.height() > 0) pWidget->resize(wsize); else #endif // pWidget->adjustSize(); if (!bVisible) bVisible = m_settings.value("/visible", false).toBool(); if (bVisible) pWidget->show(); else pWidget->hide(); m_settings.endGroup(); } } void qxgeditOptions::saveWidgetGeometry ( QWidget *pWidget, bool bVisible ) { // Try to save form window position... // (due to X11 window managers ideossincrasies, we better // only save the form geometry while its up and visible) if (pWidget) { m_settings.beginGroup("/Geometry/" + pWidget->objectName()); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) m_settings.setValue("/geometry", pWidget->saveGeometry()); #else//--SAVE_OLD_GEOMETRY const QPoint& wpos = pWidget->pos(); const QSize& wsize = pWidget->size(); m_settings.setValue("/x", wpos.x()); m_settings.setValue("/y", wpos.y()); m_settings.setValue("/width", wsize.width()); m_settings.setValue("/height", wsize.height()); #endif if (!bVisible) bVisible = pWidget->isVisible(); m_settings.setValue("/visible", bVisible); m_settings.endGroup(); } } // end of qxgeditOptions.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditOptionsForm.cpp0000644000000000000000000000013214772452451017407 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditOptionsForm.cpp0000644000175000001440000002406114772452451017402 0ustar00rncbcusers// qxgeditOptionsForm.cpp // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditOptionsForm.h" #include "qxgeditOptions.h" #include "qxgeditMidiDevice.h" #include "qxgeditPaletteForm.h" #include #include #include #include // Default (empty/blank) name. static const char *g_pszDefName = QT_TRANSLATE_NOOP("qxgeditOptionsForm", "(default)"); //---------------------------------------------------------------------------- // qxgeditOptionsForm -- UI wrapper form. // Constructor. qxgeditOptionsForm::qxgeditOptionsForm ( QWidget *pParent ) : QDialog(pParent) { // Setup UI struct... m_ui.setupUi(this); #if QT_VERSION < QT_VERSION_CHECK(6, 1, 0) QDialog::setWindowIcon(QIcon(":/images/qxgedit.png")); #endif // No settings descriptor initially (the caller will set it). m_pOptions = nullptr; // Initialize dirty control state. m_iDirtyCount = 0; // MIDI specialties. m_iMidiInputsChanged = 0; m_iMidiOutputsChanged = 0; #ifdef CONFIG_RTMIDI m_ui.MidiInputListView->setSelectionMode(QAbstractItemView::SingleSelection); m_ui.MidiOutputListView->setSelectionMode(QAbstractItemView::SingleSelection); #endif // Try to fix window geometry. m_ui.MidiInputListView->setMaximumHeight(96); m_ui.MidiOutputListView->setMaximumHeight(96); adjustSize(); // UI signal/slot connections... QObject::connect(m_ui.MidiInputListView, SIGNAL(itemSelectionChanged()), SLOT(midiInputsChanged())); QObject::connect(m_ui.MidiOutputListView, SIGNAL(itemSelectionChanged()), SLOT(midiOutputsChanged())); QObject::connect(m_ui.ConfirmResetCheckBox, SIGNAL(stateChanged(int)), SLOT(changed())); QObject::connect(m_ui.ConfirmRemoveCheckBox, SIGNAL(stateChanged(int)), SLOT(changed())); QObject::connect(m_ui.CompletePathCheckBox, SIGNAL(stateChanged(int)), SLOT(changed())); QObject::connect(m_ui.MaxRecentFilesSpinBox, SIGNAL(valueChanged(int)), SLOT(changed())); QObject::connect(m_ui.RandomizePercentSpinBox, SIGNAL(valueChanged(double)), SLOT(changed())); QObject::connect(m_ui.BaseFontSizeComboBox, SIGNAL(editTextChanged(const QString&)), SLOT(changed())); QObject::connect(m_ui.StyleThemeComboBox, SIGNAL(activated(int)), SLOT(changed())); QObject::connect(m_ui.ColorThemeComboBox, SIGNAL(activated(int)), SLOT(changed())); QObject::connect(m_ui.ColorThemeToolButton, SIGNAL(clicked()), SLOT(editColorThemes())); QObject::connect(m_ui.DialogButtonBox, SIGNAL(accepted()), SLOT(accept())); QObject::connect(m_ui.DialogButtonBox, SIGNAL(rejected()), SLOT(reject())); } // Destructor. qxgeditOptionsForm::~qxgeditOptionsForm (void) { } // Populate (setup) dialog controls from settings descriptors. void qxgeditOptionsForm::setOptions ( qxgeditOptions *pOptions ) { // Set reference descriptor. m_pOptions = pOptions; // MIDI devices listings... m_ui.MidiInputListView->clear(); m_ui.MidiOutputListView->clear(); qxgeditMidiDevice *pMidiDevice = qxgeditMidiDevice::getInstance(); if (pMidiDevice) { m_ui.MidiInputListView->addItems(pMidiDevice->inputs()); m_ui.MidiOutputListView->addItems(pMidiDevice->outputs()); } // MIDI Inputs... QStringListIterator ins(m_pOptions->midiInputs); while (ins.hasNext()) { QListIterator iter( m_ui.MidiInputListView->findItems(ins.next(), Qt::MatchExactly)); while (iter.hasNext()) iter.next()->setSelected(true); } // MIDI Outputs... QStringListIterator outs(m_pOptions->midiOutputs); while (outs.hasNext()) { QListIterator iter( m_ui.MidiOutputListView->findItems(outs.next(), Qt::MatchExactly)); while (iter.hasNext()) iter.next()->setSelected(true); } // But (re)start clean... m_iMidiInputsChanged = 0; m_iMidiOutputsChanged = 0; // Other options finally. m_ui.ConfirmResetCheckBox->setChecked(m_pOptions->bConfirmReset); m_ui.ConfirmRemoveCheckBox->setChecked(m_pOptions->bConfirmRemove); m_ui.CompletePathCheckBox->setChecked(m_pOptions->bCompletePath); m_ui.MaxRecentFilesSpinBox->setValue(m_pOptions->iMaxRecentFiles); m_ui.RandomizePercentSpinBox->setValue(m_pOptions->fRandomizePercent); if (m_pOptions->iBaseFontSize > 0) m_ui.BaseFontSizeComboBox->setEditText(QString::number(m_pOptions->iBaseFontSize)); else m_ui.BaseFontSizeComboBox->setCurrentIndex(0); // Custom display options... resetColorThemes(m_pOptions->sColorTheme); resetStyleThemes(m_pOptions->sStyleTheme); // Done. Restart clean. m_iDirtyCount = 0; stabilizeForm(); } // Retrieve the editing options, if the case arises. qxgeditOptions *qxgeditOptionsForm::options (void) const { return m_pOptions; } // Accept settings (OK button slot). void qxgeditOptionsForm::accept (void) { // MIDI connections options. qxgeditMidiDevice *pMidiDevice = qxgeditMidiDevice::getInstance(); if (pMidiDevice) { // MIDI Inputs... if (m_iMidiInputsChanged > 0) { m_pOptions->midiInputs.clear(); QListIterator iter1( m_ui.MidiInputListView->selectedItems()); while (iter1.hasNext()) m_pOptions->midiInputs.append(iter1.next()->text()); pMidiDevice->connectInputs(m_pOptions->midiInputs); m_iMidiInputsChanged = 0; } // MIDI Outputs... if (m_iMidiOutputsChanged > 0) { m_pOptions->midiOutputs.clear(); QListIterator iter2( m_ui.MidiOutputListView->selectedItems()); while (iter2.hasNext()) m_pOptions->midiOutputs.append(iter2.next()->text()); pMidiDevice->connectOutputs(m_pOptions->midiOutputs); m_iMidiOutputsChanged = 0; } } // Save options... if (m_iDirtyCount > 0) { // Display options... m_pOptions->bConfirmReset = m_ui.ConfirmResetCheckBox->isChecked(); m_pOptions->bConfirmRemove = m_ui.ConfirmRemoveCheckBox->isChecked(); m_pOptions->bCompletePath = m_ui.CompletePathCheckBox->isChecked(); m_pOptions->iMaxRecentFiles = m_ui.MaxRecentFilesSpinBox->value(); m_pOptions->fRandomizePercent = float(m_ui.RandomizePercentSpinBox->value()); m_pOptions->iBaseFontSize = m_ui.BaseFontSizeComboBox->currentText().toInt(); // Custom options... if (m_ui.StyleThemeComboBox->currentIndex() > 0) m_pOptions->sStyleTheme = m_ui.StyleThemeComboBox->currentText(); else m_pOptions->sStyleTheme.clear(); if (m_ui.ColorThemeComboBox->currentIndex() > 0) m_pOptions->sColorTheme = m_ui.ColorThemeComboBox->currentText(); else m_pOptions->sColorTheme.clear(); // Reset dirty flag. m_iDirtyCount = 0; } // Save/commit to disk. m_pOptions->saveOptions(); // Just go with dialog acceptance QDialog::accept(); } // Reject settings (Cancel button slot). void qxgeditOptionsForm::reject (void) { bool bReject = true; // Check if there's any pending changes... if (m_iDirtyCount > 0) { switch (QMessageBox::warning(this, tr("Warning"), tr("Some settings have been changed.\n\n" "Do you want to apply the changes?"), QMessageBox::Apply | QMessageBox::Discard | QMessageBox::Cancel)) { case QMessageBox::Apply: accept(); return; case QMessageBox::Discard: break; default: // Cancel. bReject = false; } } if (bReject) QDialog::reject(); } // Dirty up settings. void qxgeditOptionsForm::changed (void) { m_iDirtyCount++; stabilizeForm(); } // Custom color palette theme manager. void qxgeditOptionsForm::editColorThemes (void) { qxgeditPaletteForm form(this); form.setSettings(&m_pOptions->settings()); QString sColorTheme; int iDirtyColorTheme = 0; const int iColorTheme = m_ui.ColorThemeComboBox->currentIndex(); if (iColorTheme > 0) { sColorTheme = m_ui.ColorThemeComboBox->itemText(iColorTheme); form.setPaletteName(sColorTheme); } if (form.exec() == QDialog::Accepted) { sColorTheme = form.paletteName(); ++iDirtyColorTheme; } if (iDirtyColorTheme > 0 || form.isDirty()) { resetColorThemes(sColorTheme); changed(); } } // Custom color palette themes settler. void qxgeditOptionsForm::resetColorThemes ( const QString& sColorTheme ) { m_ui.ColorThemeComboBox->clear(); m_ui.ColorThemeComboBox->addItem( tr(g_pszDefName)); m_ui.ColorThemeComboBox->addItems( qxgeditPaletteForm::namedPaletteList(&m_pOptions->settings())); int iColorTheme = 0; if (!sColorTheme.isEmpty()) { iColorTheme = m_ui.ColorThemeComboBox->findText(sColorTheme); if (iColorTheme < 0) iColorTheme = 0; } m_ui.ColorThemeComboBox->setCurrentIndex(iColorTheme); } // Custom widget style themes settler. void qxgeditOptionsForm::resetStyleThemes ( const QString& sStyleTheme ) { m_ui.StyleThemeComboBox->clear(); m_ui.StyleThemeComboBox->addItem( tr(g_pszDefName)); m_ui.StyleThemeComboBox->addItems(QStyleFactory::keys()); int iStyleTheme = 0; if (!sStyleTheme.isEmpty()) { iStyleTheme = m_ui.StyleThemeComboBox->findText(sStyleTheme); if (iStyleTheme < 0) iStyleTheme = 0; } m_ui.StyleThemeComboBox->setCurrentIndex(iStyleTheme); } // MIDI I/O changes void qxgeditOptionsForm::midiInputsChanged (void) { m_iMidiInputsChanged++; changed(); } void qxgeditOptionsForm::midiOutputsChanged (void) { m_iMidiOutputsChanged++; changed(); } // Stabilize current form state. void qxgeditOptionsForm::stabilizeForm (void) { bool bValid = (m_iDirtyCount > 0); m_ui.DialogButtonBox->button(QDialogButtonBox::Ok)->setEnabled(bValid); } // end of qxgeditOptionsForm.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditFilter.h0000644000000000000000000000013214772452451016022 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditFilter.h0000644000175000001440000000460214772452451016014 0ustar00rncbcusers// qxgeditFilter.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditFilter_h #define __qxgeditFilter_h #include //---------------------------------------------------------------------------- // qxgeditFilter -- Custom widget class qxgeditFilter : public QFrame { Q_OBJECT public: // Constructor. qxgeditFilter(QWidget *pParent = nullptr); // Destructor. ~qxgeditFilter(); // Parameter getters. unsigned short cutoff() const; unsigned short resonance() const; // Parameter range modifiers. void setMaxCutoff(unsigned short iMaxCutoff); unsigned short maxCutoff() const; void setMaxResonance(unsigned short iMaxResonance); unsigned short maxResonance() const; public slots: // Parameter setters. void setCutoff(unsigned short iCutoff); void setResonance(unsigned short iResonance); signals: // Parameter change signals. void cutoffChanged(unsigned short iCutoff); void resonanceChanged(unsigned short iResonance); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Drag/move curve. void dragCurve(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iCutoff; unsigned short m_iResonance; unsigned short m_iMaxCutoff; unsigned short m_iMaxResonance; // Drag state. bool m_bDragging; QPoint m_posDrag; }; #endif // __qxgeditFilter_h // end of qxgeditFilter.h qxgedit-1.0.1/src/PaxHeaders/qxgeditPaletteForm.ui0000644000000000000000000000013214772452451017205 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPaletteForm.ui0000644000175000001440000001717114772452451017204 0ustar00rncbcusers rncbc aka Rui Nuno Capela qxgedit - Qt XG Editor. Copyright (C) 2005-2024, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. qxgeditPaletteForm 0 0 534 640 0 0 Color Themes Name 0 0 320 0 Current color palette name true QComboBox::NoInsert Save current color palette name Save :/images/formSave.png Delete current color palette name Delete :/images/formRemove.png Palette 280 360 Current color palette true Generate: 0 0 Qt::StrongFocus Base color to generate palette Reset all current palette colors Reset :/images/itemReset.png Qt::Horizontal 8 20 Import a custom color theme (palette) from file Import... :/images/formOpen.png Export a custom color theme (palette) to file Export... :/images/formSave.png Qt::Horizontal 8 20 Show Details Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qxgeditPaletteForm::ColorButton nameCombo saveButton deleteButton paletteView generateButton resetButton importButton exportButton detailsCheck dialogButtons qxgedit-1.0.1/src/PaxHeaders/qxgeditDrop.cpp0000644000000000000000000000013214772452451016034 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditDrop.cpp0000644000175000001440000000601714772452451016030 0ustar00rncbcusers// qxgeditDrop.cpp // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditDrop.h" #include "XGParam.h" //------------------------------------------------------------------------- // qxgeditDrop - Custom drop-down list widget. // // Constructor. qxgeditDrop::qxgeditDrop ( QWidget *pParent ) : QComboBox(pParent), m_pParam(nullptr) { QObject::connect(this, SIGNAL(activated(int)), SLOT(comboActivated(int))); } // Destructor. qxgeditDrop::~qxgeditDrop (void) { } // Nominal value accessors. void qxgeditDrop::setValue ( unsigned short iValue, XGParamObserver *pSender ) { if (m_pParam == nullptr) return; if (iValue < m_pParam->min()) iValue = m_pParam->min(); if (iValue > m_pParam->max() && m_pParam->max() > m_pParam->min()) iValue = m_pParam->max(); bool bValueChanged = (iValue != m_pParam->value()); m_pParam->set_value(iValue, pSender); int iCombo = QComboBox::findData(iValue); if (iCombo >= 0) QComboBox::setCurrentIndex(iCombo); QPalette pal; if (QComboBox::isEnabled() && iValue != m_pParam->def()) { const QColor& rgbBase = (pal.window().color().value() < 0x7f ? QColor(Qt::darkYellow).darker() : QColor(Qt::yellow).lighter()); pal.setColor(QPalette::Base, rgbBase); // pal.setColor(QPalette::Text, Qt::black); } QComboBox::setPalette(pal); if (bValueChanged) emit valueChanged(iValue); } unsigned short qxgeditDrop::value (void) const { return (m_pParam ? m_pParam->value() : 0); } // Specialty parameter accessors. void qxgeditDrop::setParam ( XGParam *pParam, XGParamObserver *pSender ) { m_pParam = pParam; QComboBox::clear(); QComboBox::setPalette(QPalette()); if (m_pParam) { unsigned short iValue = m_pParam->min(); for (; m_pParam->max() >= iValue; ++iValue) { const char *pszItem = m_pParam->gets(iValue); if (pszItem) QComboBox::addItem(pszItem, iValue); } setValue(m_pParam->value(), pSender); } } XGParam *qxgeditDrop::param (void) const { return m_pParam; } // Internal widget slots. void qxgeditDrop::comboActivated ( int iCombo ) { setValue((unsigned short) QComboBox::itemData(iCombo).toUInt()); } // end of qxgeditDrop.cpp qxgedit-1.0.1/src/PaxHeaders/config.h.cmake0000644000000000000000000000013214772452451015533 xustar0030 mtime=1743410473.474959861 30 atime=1743410473.474959861 30 ctime=1743410473.474959861 qxgedit-1.0.1/src/config.h.cmake0000644000175000001440000000336114772452451015526 0ustar00rncbcusers#ifndef CONFIG_H #define CONFIG_H /* Define to the title of this package. */ #cmakedefine PROJECT_TITLE "@PROJECT_TITLE@" /* Define to the name of this package. */ #cmakedefine PROJECT_NAME "@PROJECT_NAME@" /* Define to the version of this package. */ #cmakedefine PROJECT_VERSION "@PROJECT_VERSION@" /* Define to the description of this package. */ #cmakedefine PROJECT_DESCRIPTION "@PROJECT_DESCRIPTION@" /* Define to the homepage of this package. */ #cmakedefine PROJECT_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@" /* Define to the copyright of this package. */ #cmakedefine PROJECT_COPYRIGHT "@PROJECT_COPYRIGHT@" /* Define to the domain of this package. */ #cmakedefine PROJECT_DOMAIN "@PROJECT_DOMAIN@" /* Default installation prefix. */ #cmakedefine CONFIG_PREFIX "@CONFIG_PREFIX@" /* Define to target installation dirs. */ #cmakedefine CONFIG_BINDIR "@CONFIG_BINDIR@" #cmakedefine CONFIG_LIBDIR "@CONFIG_LIBDIR@" #cmakedefine CONFIG_DATADIR "@CONFIG_DATADIR@" #cmakedefine CONFIG_MANDIR "@CONFIG_MANDIR@" /* Define if debugging is enabled. */ #cmakedefine CONFIG_DEBUG @CONFIG_DEBUG@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SIGNAL_H @HAVE_SIGNAL_H@ /* Define if debugging is enabled. */ #cmakedefine CONFIG_DEBUG @CONFIG_DEBUG@ /* Define if ALSA MIDI Sequencer library is enabled. */ #cmakedefine CONFIG_ALSA_MIDI @CONFIG_ALSA_MIDI@ /* Define if RtMidi library is enabled. */ #cmakedefine CONFIG_RTMIDI @CONFIG_RTMIDI@ /* Define if unique/single instance is enabled. */ #cmakedefine CONFIG_XUNIQUE @CONFIG_XUNIQUE@ /* Define if debugger stack-trace is enabled. */ #cmakedefine CONFIG_STACKTRACE @CONFIG_STACKTRACE@ /* Define if Wayland is supported */ #cmakedefine CONFIG_WAYLAND @CONFIG_WAYLAND@ #endif /* CONFIG_H */ qxgedit-1.0.1/src/PaxHeaders/qxgeditDrop.h0000644000000000000000000000013214772452451015501 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditDrop.h0000644000175000001440000000354114772452451015474 0ustar00rncbcusers// qxgeditDrop.h // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditDrop_h #define __qxgeditDrop_h #include // Forward declarations. class XGParam; class XGParamObserver; //------------------------------------------------------------------------- // qxgeditDrop - Custom drop-down list widget. class qxgeditDrop : public QComboBox { Q_OBJECT public: // Constructor. qxgeditDrop(QWidget *pParent = 0); // Destructor. ~qxgeditDrop(); // Specialty parameter accessors. void setParam(XGParam *pParam, XGParamObserver *pSender = nullptr); XGParam *param() const; // Value accessors. void setValue(unsigned short iValue, XGParamObserver *pSender = nullptr); unsigned short value() const; signals: // Value change signal. void valueChanged(unsigned short); protected slots: // Internal widget slots. void comboActivated(int); private: // Instance variables. XGParam *m_pParam; }; #endif // __qxgeditDrop_h // end of qxgeditDrop.h qxgedit-1.0.1/src/PaxHeaders/qxgeditCheck.h0000644000000000000000000000013214772452451015612 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditCheck.h0000644000175000001440000000356214772452451015610 0ustar00rncbcusers// qxgeditCheck.h // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditCheck_h #define __qxgeditCheck_h #include "XGParamWidget.h" #include //------------------------------------------------------------------------- // qxgeditCheck - Custom check-box widget. class qxgeditCheck : public XGParamWidget { Q_OBJECT public: // Constructor. qxgeditCheck(QWidget *pParent = 0); // Destructor. ~qxgeditCheck(); // Specialty parameter accessors. void set_param(XGParam *pParam, Observer *pSender); XGParam *param() const; // Value accessors. void set_value(unsigned short iValue, Observer *pSender); unsigned short value() const; signals: // Value change signal. void valueChanged(unsigned short); public slots: // Value settler. void setValue(unsigned short); protected slots: // Internal widget slots. void checkToggled(bool); private: // Instance variables. XGParam *m_pParam; }; #endif // __qxgeditCheck_h // end of qxgeditCheck.h qxgedit-1.0.1/src/PaxHeaders/qxgeditCombo.h0000644000000000000000000000013214772452451015634 xustar0030 mtime=1743410473.475374071 30 atime=1743410473.475374071 30 ctime=1743410473.475374071 qxgedit-1.0.1/src/qxgeditCombo.h0000644000175000001440000000346014772452451015627 0ustar00rncbcusers// qxgeditCombo.h // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditCombo_h #define __qxgeditCombo_h #include "XGParamWidget.h" #include //------------------------------------------------------------------------- // qxgeditCombo - Custom combo-box widget. class qxgeditCombo : public XGParamWidget { Q_OBJECT public: // Constructor. qxgeditCombo(QWidget *pParent = 0); // Destructor. ~qxgeditCombo(); // Specialty parameter accessors. void set_param(XGParam *pParam, Observer *pSender); XGParam *param() const; // Value accessors. void set_value(unsigned short iValue, Observer *pSender); unsigned short value() const; signals: // Value change signal. void valueChanged(unsigned short); protected slots: // Internal widget slots. void comboActivated(int); private: // Instance variables. XGParam *m_pParam; }; #endif // __qxgeditCombo_h // end of qxgeditCombo.h qxgedit-1.0.1/src/PaxHeaders/qxgeditMainForm.cpp0000644000000000000000000000013214772452451016640 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475607941 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditMainForm.cpp0000644000175000001440000025750714772452451016650 0ustar00rncbcusers// qxgeditMainForm.cpp // /**************************************************************************** Copyright (C) 2005-2025, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditMainForm.h" #include "qxgeditAbout.h" #include "qxgeditOptions.h" #include "qxgeditXGMasterMap.h" #include "qxgeditMidiDevice.h" #include "XGParamSysex.h" #include "qxgeditDial.h" #include "qxgeditCombo.h" #include "qxgeditOptionsForm.h" #include "qxgeditPaletteForm.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #include #endif //------------------------------------------------------------------------- // LADISH Level 1 support stuff. #ifdef HAVE_SIGNAL_H #include #include #include #include #include // File descriptor for SIGUSR1 notifier. static int g_fdSigusr1[2] = { -1, -1 }; // Unix SIGUSR1 signal handler. static void qxgedit_sigusr1_handler ( int /* signo */ ) { char c = 1; (void) (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0); } // File descriptor for SIGTERM notifier. static int g_fdSigterm[2] = { -1, -1 }; // Unix SIGTERM signal handler. static void qxgedit_sigterm_handler ( int /* signo */ ) { char c = 1; (void) (::write(g_fdSigterm[0], &c, sizeof(c)) > 0); } #endif // HAVE_SIGNAL_H //------------------------------------------------------------------------- // qxgeditMainForm -- UI wrapper form. // qxgeditMainForm *qxgeditMainForm::g_pMainForm = nullptr; // Constructor. qxgeditMainForm::qxgeditMainForm ( QWidget *pParent ) : QMainWindow(pParent) { // Setup UI struct... m_ui.setupUi(this); #if QT_VERSION < QT_VERSION_CHECK(6, 1, 0) QMainWindow::setWindowIcon(QIcon(":/images/qxgedit.png")); #endif // Pseudo-singleton reference setup. g_pMainForm = this; // Initialize some pointer references. m_pOptions = nullptr; m_pMidiDevice = nullptr; m_pMasterMap = nullptr; // We'll start clean. m_iUntitled = 0; m_iDirtyCount = 0; // Instrument/Normal Voice combo-box view soft-mutex. m_iMultipartVoiceUpdate = 0; // Uservoice element combo-box soft-mutex. m_iUservoiceElementUpdate = 0; #ifdef HAVE_SIGNAL_H // Set to ignore any fatal "Broken pipe" signals. ::signal(SIGPIPE, SIG_IGN); // LADISH Level 1 suport. // Initialize file descriptors for SIGUSR1 socket notifier. ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1); m_pSigusr1Notifier = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this); QObject::connect(m_pSigusr1Notifier, SIGNAL(activated(int)), SLOT(handle_sigusr1())); // Install SIGUSR1 signal handler. struct sigaction sigusr1; sigusr1.sa_handler = qxgedit_sigusr1_handler; sigemptyset(&sigusr1.sa_mask); sigusr1.sa_flags = 0; sigusr1.sa_flags |= SA_RESTART; ::sigaction(SIGUSR1, &sigusr1, nullptr); // Initialize file descriptors for SIGTERM socket notifier. ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm); m_pSigtermNotifier = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this); QObject::connect(m_pSigtermNotifier, SIGNAL(activated(int)), SLOT(handle_sigterm())); // Install SIGTERM signal handler. struct sigaction sigterm; sigterm.sa_handler = qxgedit_sigterm_handler; sigemptyset(&sigterm.sa_mask); sigterm.sa_flags = 0; sigterm.sa_flags |= SA_RESTART; ::sigaction(SIGTERM, &sigterm, nullptr); ::sigaction(SIGQUIT, &sigterm, nullptr); // Ignore SIGHUP/SIGINT signals. ::signal(SIGHUP, SIG_IGN); ::signal(SIGINT, SIG_IGN); #else // HAVE_SIGNAL_H m_pSigusr1Notifier = nullptr; m_pSigtermNotifier = nullptr; #endif // !HAVE_SIGNAL_H // Create some statusbar labels... const QSize pad(4, 0); QLabel *pLabel; // Track status. pLabel = new QLabel(tr("Session")); pLabel->setAlignment(Qt::AlignLeft); pLabel->setToolTip(tr("Current session name")); pLabel->setAutoFillBackground(true); m_statusItems[StatusName] = pLabel; statusBar()->addWidget(pLabel, 2); // Session modification status. pLabel = new QLabel(tr("MOD")); pLabel->setAlignment(Qt::AlignHCenter); pLabel->setMinimumSize(pLabel->sizeHint() + pad); pLabel->setToolTip(tr("Session modification state")); pLabel->setAutoFillBackground(true); m_statusItems[StatusMod] = pLabel; statusBar()->addWidget(pLabel); // Some actions surely need those // shortcuts firmly attached... addAction(m_ui.viewMenubarAction); // Ah, make it stand right. setFocus(); // UI signal/slot connections... QObject::connect(m_ui.fileNewAction, SIGNAL(triggered(bool)), SLOT(fileNew())); QObject::connect(m_ui.fileOpenAction, SIGNAL(triggered(bool)), SLOT(fileOpen())); QObject::connect(m_ui.fileSaveAction, SIGNAL(triggered(bool)), SLOT(fileSave())); QObject::connect(m_ui.fileSaveAsAction, SIGNAL(triggered(bool)), SLOT(fileSaveAs())); QObject::connect(m_ui.fileExitAction, SIGNAL(triggered(bool)), SLOT(fileExit())); QObject::connect(m_ui.viewMenubarAction, SIGNAL(triggered(bool)), SLOT(viewMenubar(bool))); QObject::connect(m_ui.viewStatusbarAction, SIGNAL(triggered(bool)), SLOT(viewStatusbar(bool))); QObject::connect(m_ui.viewToolbarAction, SIGNAL(triggered(bool)), SLOT(viewToolbar(bool))); QObject::connect(m_ui.viewRandomizeAction, SIGNAL(triggered(bool)), SLOT(viewRandomize())); QObject::connect(m_ui.viewOptionsAction, SIGNAL(triggered(bool)), SLOT(viewOptions())); QObject::connect(m_ui.helpAboutAction, SIGNAL(triggered(bool)), SLOT(helpAbout())); QObject::connect(m_ui.helpAboutQtAction, SIGNAL(triggered(bool)), SLOT(helpAboutQt())); QObject::connect(m_ui.fileMenu, SIGNAL(aboutToShow()), SLOT(updateRecentFilesMenu())); QObject::connect(m_ui.MainTabWidget, SIGNAL(currentChanged(int)), SLOT(stabilizeForm())); QObject::connect(m_ui.SystemEffectToolBox, SIGNAL(currentChanged(int)), SLOT(stabilizeForm())); } // Destructor. qxgeditMainForm::~qxgeditMainForm (void) { #ifdef HAVE_SIGNAL_H if (m_pSigusr1Notifier) delete m_pSigusr1Notifier; if (m_pSigtermNotifier) delete m_pSigtermNotifier; #endif // Free designated devices. if (m_pMidiDevice) delete m_pMidiDevice; if (m_pMasterMap) delete m_pMasterMap; // Pseudo-singleton reference shut-down. g_pMainForm = nullptr; } // kind of singleton reference. qxgeditMainForm *qxgeditMainForm::getInstance (void) { return g_pMainForm; } // Make and set a proper setup options step. void qxgeditMainForm::setup ( qxgeditOptions *pOptions ) { // We got options? m_pOptions = pOptions; // Initial decorations toggle state. m_ui.viewMenubarAction->setChecked(m_pOptions->bMenubar); m_ui.viewStatusbarAction->setChecked(m_pOptions->bStatusbar); m_ui.viewToolbarAction->setChecked(m_pOptions->bToolbar); // Initial decorations visibility state. viewMenubar(m_pOptions->bMenubar); viewStatusbar(m_pOptions->bStatusbar); viewToolbar(m_pOptions->bToolbar); // Try to restore old window positioning. m_pOptions->loadWidgetGeometry(this, true); // Primary startup stabilization... updateRecentFilesMenu(); // XG master database... m_pMasterMap = new qxgeditXGMasterMap(); m_pMasterMap->set_auto_send(m_pOptions->bUservoiceAutoSend); // Start proper devices... m_pMidiDevice = new qxgeditMidiDevice(QXGEDIT_TITLE); QObject::connect(m_pMidiDevice, SIGNAL(receiveSysex(const QByteArray&)), SLOT(sysexReceived(const QByteArray&))); QObject::connect(m_pMidiDevice, SIGNAL(receiveRpn(unsigned char, unsigned short, unsigned short)), SLOT(rpnReceived(unsigned char, unsigned short, unsigned short))); QObject::connect(m_pMidiDevice, SIGNAL(receiveNrpn(unsigned char, unsigned short, unsigned short)), SLOT(nrpnReceived(unsigned char, unsigned short, unsigned short))); // And respective connections... m_pMidiDevice->connectInputs(m_pOptions->midiInputs); m_pMidiDevice->connectOutputs(m_pOptions->midiOutputs); // Change to last known session dir... if (!m_pOptions->sSessionDir.isEmpty()) QDir::setCurrent(m_pOptions->sSessionDir); // Setup UI widgets... QWidget *pCentralWidget = centralWidget(); const QFont& font = pCentralWidget->font(); pCentralWidget->setFont(QFont(font.family(), font.pointSize() - 2)); XGParamMap *SYSTEM = &(m_pMasterMap->SYSTEM); XGParamMap *REVERB = &(m_pMasterMap->REVERB); XGParamMap *CHORUS = &(m_pMasterMap->CHORUS); XGParamMap *VARIATION = &(m_pMasterMap->VARIATION); XGParamMap *MULTIPART = &(m_pMasterMap->MULTIPART); XGParamMap *DRUMSETUP = &(m_pMasterMap->DRUMSETUP); XGParamMap *USERVOICE = &(m_pMasterMap->USERVOICE); // SYSTEM... QObject::connect(m_ui.MasterResetButton, SIGNAL(clicked()), SLOT(masterResetButtonClicked())); // SYSTEM widget mapping... m_ui.MasterTuneDial -> set_param_map(SYSTEM, 0x00); m_ui.MasterVolumeDial -> set_param_map(SYSTEM, 0x04); m_ui.MasterTransposeDial -> set_param_map(SYSTEM, 0x06); // REVERB... QObject::connect(m_ui.ReverbResetButton, SIGNAL(clicked()), SLOT(reverbResetButtonClicked())); // REVERB widget mapping... m_ui.ReverbTypeCombo -> set_param_map(REVERB, 0x00); m_ui.ReverbParam1Dial -> set_param_map(REVERB, 0x02); m_ui.ReverbParam2Dial -> set_param_map(REVERB, 0x03); m_ui.ReverbParam3Dial -> set_param_map(REVERB, 0x04); m_ui.ReverbParam4Dial -> set_param_map(REVERB, 0x05); m_ui.ReverbParam5Dial -> set_param_map(REVERB, 0x06); m_ui.ReverbParam6Dial -> set_param_map(REVERB, 0x07); m_ui.ReverbParam7Dial -> set_param_map(REVERB, 0x08); m_ui.ReverbParam8Dial -> set_param_map(REVERB, 0x09); m_ui.ReverbParam9Dial -> set_param_map(REVERB, 0x0a); m_ui.ReverbParam10Dial -> set_param_map(REVERB, 0x0b); m_ui.ReverbReturnDial -> set_param_map(REVERB, 0x0c); m_ui.ReverbPanDial -> set_param_map(REVERB, 0x0d); m_ui.ReverbParam11Dial -> set_param_map(REVERB, 0x10); m_ui.ReverbParam12Dial -> set_param_map(REVERB, 0x11); m_ui.ReverbParam13Dial -> set_param_map(REVERB, 0x12); m_ui.ReverbParam14Dial -> set_param_map(REVERB, 0x13); m_ui.ReverbParam15Dial -> set_param_map(REVERB, 0x14); m_ui.ReverbParam16Dial -> set_param_map(REVERB, 0x15); // CHORUS... QObject::connect(m_ui.ChorusResetButton, SIGNAL(clicked()), SLOT(chorusResetButtonClicked())); // CHORUS widget mapping... m_ui.ChorusTypeCombo -> set_param_map(CHORUS, 0x20); m_ui.ChorusParam1Dial -> set_param_map(CHORUS, 0x22); m_ui.ChorusParam2Dial -> set_param_map(CHORUS, 0x23); m_ui.ChorusParam3Dial -> set_param_map(CHORUS, 0x24); m_ui.ChorusParam4Dial -> set_param_map(CHORUS, 0x25); m_ui.ChorusParam5Dial -> set_param_map(CHORUS, 0x26); m_ui.ChorusParam6Dial -> set_param_map(CHORUS, 0x27); m_ui.ChorusParam7Dial -> set_param_map(CHORUS, 0x28); m_ui.ChorusParam8Dial -> set_param_map(CHORUS, 0x29); m_ui.ChorusParam9Dial -> set_param_map(CHORUS, 0x2a); m_ui.ChorusParam10Dial -> set_param_map(CHORUS, 0x2b); m_ui.ChorusReturnDial -> set_param_map(CHORUS, 0x2c); m_ui.ChorusPanDial -> set_param_map(CHORUS, 0x2d); m_ui.ChorusReverbDial -> set_param_map(CHORUS, 0x2e); m_ui.ChorusParam11Dial -> set_param_map(CHORUS, 0x30); m_ui.ChorusParam12Dial -> set_param_map(CHORUS, 0x31); m_ui.ChorusParam13Dial -> set_param_map(CHORUS, 0x32); m_ui.ChorusParam14Dial -> set_param_map(CHORUS, 0x33); m_ui.ChorusParam15Dial -> set_param_map(CHORUS, 0x34); m_ui.ChorusParam16Dial -> set_param_map(CHORUS, 0x35); // VARIATION... QObject::connect(m_ui.VariationResetButton, SIGNAL(clicked()), SLOT(variationResetButtonClicked())); // VARIATION widget mapping... m_ui.VariationTypeCombo -> set_param_map(VARIATION, 0x40); m_ui.VariationParam1Dial -> set_param_map(VARIATION, 0x42); m_ui.VariationParam2Dial -> set_param_map(VARIATION, 0x44); m_ui.VariationParam3Dial -> set_param_map(VARIATION, 0x46); m_ui.VariationParam4Dial -> set_param_map(VARIATION, 0x48); m_ui.VariationParam5Dial -> set_param_map(VARIATION, 0x4a); m_ui.VariationParam6Dial -> set_param_map(VARIATION, 0x4c); m_ui.VariationParam7Dial -> set_param_map(VARIATION, 0x4e); m_ui.VariationParam8Dial -> set_param_map(VARIATION, 0x50); m_ui.VariationParam9Dial -> set_param_map(VARIATION, 0x52); m_ui.VariationParam10Dial -> set_param_map(VARIATION, 0x54); m_ui.VariationReturnDial -> set_param_map(VARIATION, 0x56); m_ui.VariationPanDial -> set_param_map(VARIATION, 0x57); m_ui.VariationReverbDial -> set_param_map(VARIATION, 0x58); m_ui.VariationChorusDial -> set_param_map(VARIATION, 0x59); m_ui.VariationConnectDial -> set_param_map(VARIATION, 0x5a); m_ui.VariationPartDial -> set_param_map(VARIATION, 0x5b); m_ui.VariationWheelDial -> set_param_map(VARIATION, 0x5c); m_ui.VariationBendDial -> set_param_map(VARIATION, 0x5d); m_ui.VariationCATDial -> set_param_map(VARIATION, 0x5e); m_ui.VariationAC1Dial -> set_param_map(VARIATION, 0x5f); m_ui.VariationAC2Dial -> set_param_map(VARIATION, 0x60); m_ui.VariationParam11Dial -> set_param_map(VARIATION, 0x70); m_ui.VariationParam12Dial -> set_param_map(VARIATION, 0x71); m_ui.VariationParam13Dial -> set_param_map(VARIATION, 0x72); m_ui.VariationParam14Dial -> set_param_map(VARIATION, 0x73); m_ui.VariationParam15Dial -> set_param_map(VARIATION, 0x74); m_ui.VariationParam16Dial -> set_param_map(VARIATION, 0x75); // MULTIPART... m_ui.MultipartCombo->setMaxVisibleItems(16); m_ui.MultipartCombo->clear(); for (int iPart = 0; iPart < 16; ++iPart) m_ui.MultipartCombo->addItem(tr("Part %1").arg(iPart + 1)); // MULTIPART Instrument model/view combo-box... QTreeWidget *pMultipartVoiceListView = new QTreeWidget(); pMultipartVoiceListView->header()->hide(); pMultipartVoiceListView->setRootIsDecorated(true); pMultipartVoiceListView->setAllColumnsShowFocus(true); pMultipartVoiceListView->setUniformRowHeights(true); m_ui.MultipartVoiceCombo->setModel(pMultipartVoiceListView->model()); m_ui.MultipartVoiceCombo->setView(pMultipartVoiceListView); m_ui.MultipartVoiceCombo->setMaxVisibleItems(16); m_ui.MultipartVoiceCombo->setMinimumContentsLength(24); m_ui.MultipartVoiceCombo->clear(); QList items; QTreeWidgetItem *pInstrumentItem; for (unsigned short i = 0; i < XGInstrument::count(); ++i) { XGInstrument instr(i); pInstrumentItem = new QTreeWidgetItem(pMultipartVoiceListView); pInstrumentItem->setFlags(Qt::ItemIsEnabled); pInstrumentItem->setText(0, instr.name()); for (unsigned short j = 0; j < instr.size(); ++j) { XGNormalVoice voice(&instr, j); QTreeWidgetItem *pVoiceItem = new QTreeWidgetItem(pInstrumentItem); pVoiceItem->setText(0, voice.name()); } items.append(pInstrumentItem); } pInstrumentItem = new QTreeWidgetItem(pMultipartVoiceListView); pInstrumentItem->setFlags(Qt::ItemIsEnabled); pInstrumentItem->setText(0, "Drums"); for (unsigned short k = 0; k < XGDrumKit::count(); ++k) { XGDrumKit drumkit(k); QTreeWidgetItem *pVoiceItem = new QTreeWidgetItem(pInstrumentItem); pVoiceItem->setText(0, drumkit.name()); } pInstrumentItem = new QTreeWidgetItem(pMultipartVoiceListView); pInstrumentItem->setFlags(Qt::ItemIsEnabled); pInstrumentItem->setText(0, "QS300 User"); for (unsigned short iUser = 0; iUser < 32; ++iUser) { QTreeWidgetItem *pVoiceItem = new QTreeWidgetItem(pInstrumentItem); pVoiceItem->setText(0, QString("QS300 User %1").arg(iUser + 1)); } pMultipartVoiceListView->addTopLevelItems(items); // MULTIPART Special values... m_ui.MultipartPanDial->setSpecialValueText(tr("Random")); QObject::connect(m_ui.MultipartResetButton, SIGNAL(clicked()), SLOT(multipartResetButtonClicked())); QObject::connect(m_ui.MultipartCombo, SIGNAL(activated(int)), SLOT(multipartComboActivated(int))); QObject::connect(m_ui.MultipartVoiceCombo, SIGNAL(activated(int)), SLOT(multipartVoiceComboActivated(int))); QObject::connect(m_ui.MultipartBankMSBDial, SIGNAL(valueChanged(unsigned short)), SLOT(multipartVoiceChanged())); QObject::connect(m_ui.MultipartBankLSBDial, SIGNAL(valueChanged(unsigned short)), SLOT(multipartVoiceChanged())); QObject::connect(m_ui.MultipartProgramDial, SIGNAL(valueChanged(unsigned short)), SLOT(multipartVoiceChanged())); QObject::connect(m_ui.MultipartPartModeDial, SIGNAL(valueChanged(unsigned short)), SLOT(multipartPartModeChanged(unsigned short))); // MULTIPART AmpEg... QObject::connect( m_ui.MultipartAmpEg, SIGNAL(attackChanged(unsigned short)), m_ui.MultipartAttackDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartAttackDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartAmpEg, SLOT(setAttack(unsigned short))); QObject::connect( m_ui.MultipartAmpEg, SIGNAL(decayChanged(unsigned short)), m_ui.MultipartDecayDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartDecayDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartAmpEg, SLOT(setDecay(unsigned short))); QObject::connect( m_ui.MultipartAmpEg, SIGNAL(releaseChanged(unsigned short)), m_ui.MultipartReleaseDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartReleaseDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartAmpEg, SLOT(setRelease(unsigned short))); // MULTIPART Filter... QObject::connect( m_ui.MultipartFilter, SIGNAL(cutoffChanged(unsigned short)), m_ui.MultipartCutoffDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartCutoffDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartFilter, SLOT(setCutoff(unsigned short))); QObject::connect( m_ui.MultipartFilter, SIGNAL(resonanceChanged(unsigned short)), m_ui.MultipartResonanceDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartResonanceDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartFilter, SLOT(setResonance(unsigned short))); // MULTIPART Pitch... QObject::connect( m_ui.MultipartPitch, SIGNAL(attackTimeChanged(unsigned short)), m_ui.MultipartAttackTimeDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartAttackTimeDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartPitch, SLOT(setAttackTime(unsigned short))); QObject::connect( m_ui.MultipartPitch, SIGNAL(attackLevelChanged(unsigned short)), m_ui.MultipartAttackLevelDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartAttackLevelDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartPitch, SLOT(setAttackLevel(unsigned short))); QObject::connect( m_ui.MultipartPitch, SIGNAL(releaseTimeChanged(unsigned short)), m_ui.MultipartReleaseTimeDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartReleaseTimeDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartPitch, SLOT(setReleaseTime(unsigned short))); QObject::connect( m_ui.MultipartPitch, SIGNAL(releaseLevelChanged(unsigned short)), m_ui.MultipartReleaseLevelDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartReleaseLevelDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartPitch, SLOT(setReleaseLevel(unsigned short))); // MULTIPART Vibrato... QObject::connect( m_ui.MultipartVibra, SIGNAL(delayChanged(unsigned short)), m_ui.MultipartDelayDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartDelayDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartVibra, SLOT(setDelay(unsigned short))); QObject::connect( m_ui.MultipartVibra, SIGNAL(rateChanged(unsigned short)), m_ui.MultipartRateDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartRateDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartVibra, SLOT(setRate(unsigned short))); QObject::connect( m_ui.MultipartVibra, SIGNAL(depthChanged(unsigned short)), m_ui.MultipartDepthDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.MultipartDepthDial, SIGNAL(valueChanged(unsigned short)), m_ui.MultipartVibra, SLOT(setDepth(unsigned short))); // MULTIPART widget mapping... m_ui.MultipartElementDial -> set_param_map(MULTIPART, 0x00); m_ui.MultipartBankMSBDial -> set_param_map(MULTIPART, 0x01); m_ui.MultipartBankLSBDial -> set_param_map(MULTIPART, 0x02); m_ui.MultipartProgramDial -> set_param_map(MULTIPART, 0x03); m_ui.MultipartChannelDial -> set_param_map(MULTIPART, 0x04); m_ui.MultipartPolyModeDial -> set_param_map(MULTIPART, 0x05); m_ui.MultipartKeyAssignDial -> set_param_map(MULTIPART, 0x06); m_ui.MultipartPartModeDial -> set_param_map(MULTIPART, 0x07); m_ui.MultipartNoteShiftDial -> set_param_map(MULTIPART, 0x08); m_ui.MultipartDetuneDial -> set_param_map(MULTIPART, 0x09); m_ui.MultipartVolumeDial -> set_param_map(MULTIPART, 0x0b); m_ui.MultipartVelDepthDial -> set_param_map(MULTIPART, 0x0c); m_ui.MultipartVelOffsetDial -> set_param_map(MULTIPART, 0x0d); m_ui.MultipartPanDial -> set_param_map(MULTIPART, 0x0e); m_ui.MultipartNoteLowDial -> set_param_map(MULTIPART, 0x0f); m_ui.MultipartNoteHighDial -> set_param_map(MULTIPART, 0x10); m_ui.MultipartDryWetDial -> set_param_map(MULTIPART, 0x11); m_ui.MultipartChorusDial -> set_param_map(MULTIPART, 0x12); m_ui.MultipartReverbDial -> set_param_map(MULTIPART, 0x13); m_ui.MultipartVariationDial -> set_param_map(MULTIPART, 0x14); m_ui.MultipartRateDial -> set_param_map(MULTIPART, 0x15); m_ui.MultipartDepthDial -> set_param_map(MULTIPART, 0x16); m_ui.MultipartDelayDial -> set_param_map(MULTIPART, 0x17); m_ui.MultipartCutoffDial -> set_param_map(MULTIPART, 0x18); m_ui.MultipartResonanceDial -> set_param_map(MULTIPART, 0x19); m_ui.MultipartAttackDial -> set_param_map(MULTIPART, 0x1a); m_ui.MultipartDecayDial -> set_param_map(MULTIPART, 0x1b); m_ui.MultipartReleaseDial -> set_param_map(MULTIPART, 0x1c); m_ui.MultipartWheelPitchDial -> set_param_map(MULTIPART, 0x1d); m_ui.MultipartWheelFilterDial -> set_param_map(MULTIPART, 0x1e); m_ui.MultipartWheelAmplDial -> set_param_map(MULTIPART, 0x1f); m_ui.MultipartWheelLFOPmodDial -> set_param_map(MULTIPART, 0x20); m_ui.MultipartWheelLFOFmodDial -> set_param_map(MULTIPART, 0x21); m_ui.MultipartWheelLFOAmodDial -> set_param_map(MULTIPART, 0x22); m_ui.MultipartBendPitchDial -> set_param_map(MULTIPART, 0x23); m_ui.MultipartBendFilterDial -> set_param_map(MULTIPART, 0x24); m_ui.MultipartBendAmplDial -> set_param_map(MULTIPART, 0x25); m_ui.MultipartBendLFOPmodDial -> set_param_map(MULTIPART, 0x26); m_ui.MultipartBendLFOFmodDial -> set_param_map(MULTIPART, 0x27); m_ui.MultipartBendLFOAmodDial -> set_param_map(MULTIPART, 0x28); m_ui.MultipartPBCheck -> set_param_map(MULTIPART, 0x30); m_ui.MultipartCATCheck -> set_param_map(MULTIPART, 0x31); m_ui.MultipartPCCheck -> set_param_map(MULTIPART, 0x32); m_ui.MultipartCCCheck -> set_param_map(MULTIPART, 0x33); m_ui.MultipartPATCheck -> set_param_map(MULTIPART, 0x34); m_ui.MultipartNoteCheck -> set_param_map(MULTIPART, 0x35); m_ui.MultipartRPNCheck -> set_param_map(MULTIPART, 0x36); m_ui.MultipartNRPNCheck -> set_param_map(MULTIPART, 0x37); m_ui.MultipartModCheck -> set_param_map(MULTIPART, 0x38); m_ui.MultipartVolCheck -> set_param_map(MULTIPART, 0x39); m_ui.MultipartPanCheck -> set_param_map(MULTIPART, 0x3a); m_ui.MultipartExprCheck -> set_param_map(MULTIPART, 0x3b); m_ui.MultipartHold1Check -> set_param_map(MULTIPART, 0x3c); m_ui.MultipartPortaCheck -> set_param_map(MULTIPART, 0x3d); m_ui.MultipartSostCheck -> set_param_map(MULTIPART, 0x3e); m_ui.MultipartPedalCheck -> set_param_map(MULTIPART, 0x3f); m_ui.MultipartBankCheck -> set_param_map(MULTIPART, 0x40); m_ui.MultipartTuningC_Dial -> set_param_map(MULTIPART, 0x41); m_ui.MultipartTuningCsDial -> set_param_map(MULTIPART, 0x42); m_ui.MultipartTuningD_Dial -> set_param_map(MULTIPART, 0x43); m_ui.MultipartTuningDsDial -> set_param_map(MULTIPART, 0x44); m_ui.MultipartTuningE_Dial -> set_param_map(MULTIPART, 0x45); m_ui.MultipartTuningF_Dial -> set_param_map(MULTIPART, 0x46); m_ui.MultipartTuningFsDial -> set_param_map(MULTIPART, 0x47); m_ui.MultipartTuningG_Dial -> set_param_map(MULTIPART, 0x48); m_ui.MultipartTuningGsDial -> set_param_map(MULTIPART, 0x49); m_ui.MultipartTuningA_Dial -> set_param_map(MULTIPART, 0x4a); m_ui.MultipartTuningAsDial -> set_param_map(MULTIPART, 0x4b); m_ui.MultipartTuningB_Dial -> set_param_map(MULTIPART, 0x4c); m_ui.MultipartCATPitchDial -> set_param_map(MULTIPART, 0x4d); m_ui.MultipartCATFilterDial -> set_param_map(MULTIPART, 0x4e); m_ui.MultipartCATAmplDial -> set_param_map(MULTIPART, 0x4f); m_ui.MultipartCATLFOPmodDial -> set_param_map(MULTIPART, 0x50); m_ui.MultipartCATLFOFmodDial -> set_param_map(MULTIPART, 0x51); m_ui.MultipartCATLFOAmodDial -> set_param_map(MULTIPART, 0x52); m_ui.MultipartPATPitchDial -> set_param_map(MULTIPART, 0x53); m_ui.MultipartPATFilterDial -> set_param_map(MULTIPART, 0x54); m_ui.MultipartPATAmplDial -> set_param_map(MULTIPART, 0x55); m_ui.MultipartPATLFOPmodDial -> set_param_map(MULTIPART, 0x56); m_ui.MultipartPATLFOFmodDial -> set_param_map(MULTIPART, 0x57); m_ui.MultipartPATLFOAmodDial -> set_param_map(MULTIPART, 0x58); m_ui.MultipartAC1ControlDial -> set_param_map(MULTIPART, 0x59); m_ui.MultipartAC1PitchDial -> set_param_map(MULTIPART, 0x5a); m_ui.MultipartAC1FilterDial -> set_param_map(MULTIPART, 0x5b); m_ui.MultipartAC1AmplDial -> set_param_map(MULTIPART, 0x5c); m_ui.MultipartAC1LFOPmodDial -> set_param_map(MULTIPART, 0x5d); m_ui.MultipartAC1LFOFmodDial -> set_param_map(MULTIPART, 0x5e); m_ui.MultipartAC1LFOAmodDial -> set_param_map(MULTIPART, 0x5f); m_ui.MultipartAC2ControlDial -> set_param_map(MULTIPART, 0x60); m_ui.MultipartAC2PitchDial -> set_param_map(MULTIPART, 0x61); m_ui.MultipartAC2FilterDial -> set_param_map(MULTIPART, 0x62); m_ui.MultipartAC2AmplDial -> set_param_map(MULTIPART, 0x63); m_ui.MultipartAC2LFOPmodDial -> set_param_map(MULTIPART, 0x64); m_ui.MultipartAC2LFOFmodDial -> set_param_map(MULTIPART, 0x65); m_ui.MultipartAC2LFOAmodDial -> set_param_map(MULTIPART, 0x66); m_ui.MultipartPortamentoDial -> set_param_map(MULTIPART, 0x67); m_ui.MultipartPortaTimeDial -> set_param_map(MULTIPART, 0x68); m_ui.MultipartAttackLevelDial -> set_param_map(MULTIPART, 0x69); m_ui.MultipartAttackTimeDial -> set_param_map(MULTIPART, 0x6a); m_ui.MultipartReleaseLevelDial -> set_param_map(MULTIPART, 0x6b); m_ui.MultipartReleaseTimeDial -> set_param_map(MULTIPART, 0x6c); m_ui.MultipartVelLowDial -> set_param_map(MULTIPART, 0x6d); m_ui.MultipartVelHighDial -> set_param_map(MULTIPART, 0x6e); // DRUMSETUP... m_ui.DrumsetupCombo->clear(); for (int iDrumset = 0; iDrumset < 2; ++iDrumset) m_ui.DrumsetupCombo->addItem(tr("Drums %1").arg(iDrumset + 1)); m_ui.DrumsetupVoiceCombo->setMaxVisibleItems(16); m_ui.DrumsetupVoiceCombo->clear(); for (unsigned short k = 0; k < XGDrumKit::count(); ++k) { XGDrumKit drumkit(k); m_ui.DrumsetupVoiceCombo->addItem(drumkit.name()); } m_ui.DrumsetupNoteCombo->setMaxVisibleItems(16); m_ui.DrumsetupNoteCombo->setMinimumContentsLength(24); drumsetupVoiceComboActivated(0); // DRUMSETUP Special values... m_ui.DrumsetupGroupDial->setSpecialValueText(tr("Off")); m_ui.DrumsetupPanDial->setSpecialValueText(tr("Random")); QObject::connect(m_ui.DrumsetupResetButton, SIGNAL(clicked()), SLOT(drumsetupResetButtonClicked())); QObject::connect(m_ui.DrumsetupCombo, SIGNAL(activated(int)), SLOT(drumsetupComboActivated(int))); QObject::connect(m_ui.DrumsetupVoiceCombo, SIGNAL(activated(int)), SLOT(drumsetupVoiceComboActivated(int))); QObject::connect(m_ui.DrumsetupNoteCombo, SIGNAL(activated(int)), SLOT(drumsetupNoteComboActivated(int))); // DRUMSETUP Filter... QObject::connect( m_ui.DrumsetupFilter, SIGNAL(cutoffChanged(unsigned short)), m_ui.DrumsetupCutoffDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.DrumsetupCutoffDial, SIGNAL(valueChanged(unsigned short)), m_ui.DrumsetupFilter, SLOT(setCutoff(unsigned short))); QObject::connect( m_ui.DrumsetupFilter, SIGNAL(resonanceChanged(unsigned short)), m_ui.DrumsetupResonanceDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.DrumsetupResonanceDial, SIGNAL(valueChanged(unsigned short)), m_ui.DrumsetupFilter, SLOT(setResonance(unsigned short))); // DRUMSETUP AmpEg... QObject::connect( m_ui.DrumsetupAmpEg, SIGNAL(attackChanged(unsigned short)), m_ui.DrumsetupAttackDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.DrumsetupAttackDial, SIGNAL(valueChanged(unsigned short)), m_ui.DrumsetupAmpEg, SLOT(setAttack(unsigned short))); QObject::connect( m_ui.DrumsetupAmpEg, SIGNAL(decay1Changed(unsigned short)), m_ui.DrumsetupDecay1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.DrumsetupDecay1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.DrumsetupAmpEg, SLOT(setDecay1(unsigned short))); QObject::connect( m_ui.DrumsetupAmpEg, SIGNAL(decay2Changed(unsigned short)), m_ui.DrumsetupDecay2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.DrumsetupDecay2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.DrumsetupAmpEg, SLOT(setDecay2(unsigned short))); // DRUMSETUP widget mapping... m_ui.DrumsetupCoarseDial -> set_param_map(DRUMSETUP, 0x00); m_ui.DrumsetupFineDial -> set_param_map(DRUMSETUP, 0x01); m_ui.DrumsetupLevelDial -> set_param_map(DRUMSETUP, 0x02); m_ui.DrumsetupGroupDial -> set_param_map(DRUMSETUP, 0x03); m_ui.DrumsetupPanDial -> set_param_map(DRUMSETUP, 0x04); m_ui.DrumsetupReverbDial -> set_param_map(DRUMSETUP, 0x05); m_ui.DrumsetupChorusDial -> set_param_map(DRUMSETUP, 0x06); m_ui.DrumsetupVariationDial -> set_param_map(DRUMSETUP, 0x07); m_ui.DrumsetupKeyAssignDial -> set_param_map(DRUMSETUP, 0x08); m_ui.DrumsetupNoteOffCheck -> set_param_map(DRUMSETUP, 0x09); m_ui.DrumsetupNoteOnCheck -> set_param_map(DRUMSETUP, 0x0a); m_ui.DrumsetupCutoffDial -> set_param_map(DRUMSETUP, 0x0b); m_ui.DrumsetupResonanceDial -> set_param_map(DRUMSETUP, 0x0c); m_ui.DrumsetupAttackDial -> set_param_map(DRUMSETUP, 0x0d); m_ui.DrumsetupDecay1Dial -> set_param_map(DRUMSETUP, 0x0e); m_ui.DrumsetupDecay2Dial -> set_param_map(DRUMSETUP, 0x0f); // USERVOICE... m_ui.UservoiceCombo->setMaxVisibleItems(16); m_ui.UservoiceCombo->clear(); for (int iUser = 0; iUser < 32; ++iUser) m_ui.UservoiceCombo->addItem(tr("QS300 User %1").arg(iUser + 1)); m_ui.UservoiceNameEdit->setMinimumWidth(200); m_ui.UservoiceElementCombo->clear(); for (int iElem = 0; iElem < 2; ++iElem) m_ui.UservoiceElementCombo->addItem(tr("Element %1").arg(iElem + 1)); m_ui.UservoiceAutoSendCheck->setChecked(m_pMasterMap->auto_send()); QObject::connect(m_ui.UservoiceResetButton, SIGNAL(clicked()), SLOT(uservoiceResetButtonClicked())); QObject::connect(m_ui.UservoiceCombo, SIGNAL(activated(int)), SLOT(uservoiceComboActivated(int))); QObject::connect(m_ui.UservoiceElementCombo, SIGNAL(activated(int)), SLOT(uservoiceElementComboActivated(int))); QObject::connect(m_ui.UservoiceSendButton, SIGNAL(clicked()), SLOT(uservoiceSendButtonClicked())); QObject::connect(m_ui.UservoiceAutoSendCheck, SIGNAL(toggled(bool)), SLOT(uservoiceAutoSendCheckToggled(bool))); // USERVOICE Presets... QObject::connect(m_ui.UservoiceNameEdit, SIGNAL(loadPresetFile(const QString&)), SLOT(uservoiceLoadPresetFile(const QString&))); QObject::connect(m_ui.UservoiceNameEdit, SIGNAL(savePresetFile(const QString&)), SLOT(uservoiceSavePresetFile(const QString&))); // USERVOICE Elements... QObject::connect(m_ui.UservoiceElementDial, SIGNAL(valueChanged(unsigned short)), SLOT(uservoiceElementChanged(unsigned short))); // USERVOICE Pitch EG... QObject::connect( m_ui.UservoicePitchEg, SIGNAL(level0Changed(unsigned short)), m_ui.UservoicePEGLevel0Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGLevel0Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setLevel0(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(level1Changed(unsigned short)), m_ui.UservoicePEGLevel1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGLevel1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setLevel1(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(level2Changed(unsigned short)), m_ui.UservoicePEGLevel2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGLevel2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setLevel2(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(level3Changed(unsigned short)), m_ui.UservoicePEGLevel3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGLevel3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setLevel3(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(level4Changed(unsigned short)), m_ui.UservoicePEGLevel4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGLevel4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setLevel4(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(rate1Changed(unsigned short)), m_ui.UservoicePEGRate1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGRate1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setRate1(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(rate2Changed(unsigned short)), m_ui.UservoicePEGRate2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGRate2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setRate2(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(rate3Changed(unsigned short)), m_ui.UservoicePEGRate3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGRate3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setRate3(unsigned short))); QObject::connect( m_ui.UservoicePitchEg, SIGNAL(rate4Changed(unsigned short)), m_ui.UservoicePEGRate4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoicePEGRate4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoicePitchEg, SLOT(setRate4(unsigned short))); // USERVOICE Filter... m_ui.UservoiceFilter->setMaxResonance(63); QObject::connect( m_ui.UservoiceFilter, SIGNAL(cutoffChanged(unsigned short)), m_ui.UservoiceCutoffDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffDial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilter, SLOT(setCutoff(unsigned short))); QObject::connect( m_ui.UservoiceFilter, SIGNAL(resonanceChanged(unsigned short)), m_ui.UservoiceResonanceDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceResonanceDial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilter, SLOT(setResonance(unsigned short))); // USERVOICE Cutoff Scale... QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(break1Changed(unsigned short)), m_ui.UservoiceCutoffBreak1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffBreak1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setBreak1(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(break2Changed(unsigned short)), m_ui.UservoiceCutoffBreak2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffBreak2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setBreak2(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(break3Changed(unsigned short)), m_ui.UservoiceCutoffBreak3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffBreak3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setBreak3(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(break4Changed(unsigned short)), m_ui.UservoiceCutoffBreak4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffBreak4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setBreak4(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(offset1Changed(unsigned short)), m_ui.UservoiceCutoffOffset1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffOffset1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setOffset1(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(offset2Changed(unsigned short)), m_ui.UservoiceCutoffOffset2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffOffset2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setOffset2(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(offset3Changed(unsigned short)), m_ui.UservoiceCutoffOffset3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffOffset3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setOffset3(unsigned short))); QObject::connect( m_ui.UservoiceCutoffScale, SIGNAL(offset4Changed(unsigned short)), m_ui.UservoiceCutoffOffset4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceCutoffOffset4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceCutoffScale, SLOT(setOffset4(unsigned short))); // USERVOICE Filter EG... QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(level0Changed(unsigned short)), m_ui.UservoiceFEGLevel0Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGLevel0Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setLevel0(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(level1Changed(unsigned short)), m_ui.UservoiceFEGLevel1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGLevel1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setLevel1(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(level2Changed(unsigned short)), m_ui.UservoiceFEGLevel2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGLevel2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setLevel2(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(level3Changed(unsigned short)), m_ui.UservoiceFEGLevel3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGLevel3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setLevel3(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(level4Changed(unsigned short)), m_ui.UservoiceFEGLevel4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGLevel4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setLevel4(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(rate1Changed(unsigned short)), m_ui.UservoiceFEGRate1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGRate1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setRate1(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(rate2Changed(unsigned short)), m_ui.UservoiceFEGRate2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGRate2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setRate2(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(rate3Changed(unsigned short)), m_ui.UservoiceFEGRate3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGRate3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setRate3(unsigned short))); QObject::connect( m_ui.UservoiceFilterEg, SIGNAL(rate4Changed(unsigned short)), m_ui.UservoiceFEGRate4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceFEGRate4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceFilterEg, SLOT(setRate4(unsigned short))); // USERVOICE Level Scale... QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(break1Changed(unsigned short)), m_ui.UservoiceLevelBreak1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelBreak1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setBreak1(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(break2Changed(unsigned short)), m_ui.UservoiceLevelBreak2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelBreak2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setBreak2(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(break3Changed(unsigned short)), m_ui.UservoiceLevelBreak3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelBreak3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setBreak3(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(break4Changed(unsigned short)), m_ui.UservoiceLevelBreak4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelBreak4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setBreak4(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(offset1Changed(unsigned short)), m_ui.UservoiceLevelOffset1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelOffset1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setOffset1(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(offset2Changed(unsigned short)), m_ui.UservoiceLevelOffset2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelOffset2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setOffset2(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(offset3Changed(unsigned short)), m_ui.UservoiceLevelOffset3Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelOffset3Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setOffset3(unsigned short))); QObject::connect( m_ui.UservoiceLevelScale, SIGNAL(offset4Changed(unsigned short)), m_ui.UservoiceLevelOffset4Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceLevelOffset4Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceLevelScale, SLOT(setOffset4(unsigned short))); // USERVOICE Amp EG... QObject::connect( m_ui.UservoiceAmpEg, SIGNAL(attackChanged(unsigned short)), m_ui.UservoiceAEGAttackDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceAEGAttackDial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceAmpEg, SLOT(setAttack(unsigned short))); QObject::connect( m_ui.UservoiceAmpEg, SIGNAL(releaseChanged(unsigned short)), m_ui.UservoiceAEGReleaseDial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceAEGReleaseDial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceAmpEg, SLOT(setRelease(unsigned short))); QObject::connect( m_ui.UservoiceAmpEg, SIGNAL(decay1Changed(unsigned short)), m_ui.UservoiceAEGDecay1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceAEGDecay1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceAmpEg, SLOT(setDecay1(unsigned short))); QObject::connect( m_ui.UservoiceAmpEg, SIGNAL(decay2Changed(unsigned short)), m_ui.UservoiceAEGDecay2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceAEGDecay2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceAmpEg, SLOT(setDecay2(unsigned short))); QObject::connect( m_ui.UservoiceAmpEg, SIGNAL(level1Changed(unsigned short)), m_ui.UservoiceAEGLevel1Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceAEGLevel1Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceAmpEg, SLOT(setLevel1(unsigned short))); QObject::connect( m_ui.UservoiceAmpEg, SIGNAL(level2Changed(unsigned short)), m_ui.UservoiceAEGLevel2Dial, SLOT(setValue(unsigned short))); QObject::connect( m_ui.UservoiceAEGLevel2Dial, SIGNAL(valueChanged(unsigned short)), m_ui.UservoiceAmpEg, SLOT(setLevel2(unsigned short))); m_ui.UservoiceNameEdit -> set_param_map(USERVOICE, 0x00); m_ui.UservoiceElementDial -> set_param_map(USERVOICE, 0x0b); m_ui.UservoiceLevelDial -> set_param_map(USERVOICE, 0x0c); // Element 1 m_ui.UservoiceWaveDial -> setMaximumWidth(86); m_ui.UservoiceWaveDial -> set_param_map(USERVOICE, 0x3d); m_ui.UservoiceNoteLowDial -> set_param_map(USERVOICE, 0x3f); m_ui.UservoiceNoteHighDial -> set_param_map(USERVOICE, 0x40); m_ui.UservoiceVelLowDial -> set_param_map(USERVOICE, 0x41); m_ui.UservoiceVelHighDial -> set_param_map(USERVOICE, 0x42); m_ui.UservoiceFEGVelCurveDial -> set_param_map(USERVOICE, 0x43); m_ui.UservoiceLFOWaveDial -> set_param_map(USERVOICE, 0x44); m_ui.UservoiceLFOPhaseDial -> set_param_map(USERVOICE, 0x45); m_ui.UservoiceLFOSpeedDial -> set_param_map(USERVOICE, 0x46); m_ui.UservoiceLFODelayDial -> set_param_map(USERVOICE, 0x47); m_ui.UservoiceLFOFadeDial -> set_param_map(USERVOICE, 0x48); m_ui.UservoiceLFOPitchDial -> set_param_map(USERVOICE, 0x49); m_ui.UservoiceLFOCutoffDial -> set_param_map(USERVOICE, 0x4a); m_ui.UservoiceLFOAmplDial -> set_param_map(USERVOICE, 0x4b); m_ui.UservoiceNoteShiftDial -> set_param_map(USERVOICE, 0x4c); m_ui.UservoiceDetuneDial -> set_param_map(USERVOICE, 0x4d); m_ui.UservoicePitchScalingDial -> set_param_map(USERVOICE, 0x4e); m_ui.UservoicePitchCenterDial -> set_param_map(USERVOICE, 0x4f); m_ui.UservoicePEGDepthDial -> set_param_map(USERVOICE, 0x50); m_ui.UservoicePEGVelLevelDial -> set_param_map(USERVOICE, 0x51); m_ui.UservoicePEGVelRateDial -> set_param_map(USERVOICE, 0x52); m_ui.UservoicePEGScalingDial -> set_param_map(USERVOICE, 0x53); m_ui.UservoicePEGCenterDial -> set_param_map(USERVOICE, 0x54); m_ui.UservoicePEGRate1Dial -> set_param_map(USERVOICE, 0x55); m_ui.UservoicePEGRate2Dial -> set_param_map(USERVOICE, 0x56); m_ui.UservoicePEGRate3Dial -> set_param_map(USERVOICE, 0x57); m_ui.UservoicePEGRate4Dial -> set_param_map(USERVOICE, 0x58); m_ui.UservoicePEGLevel0Dial -> set_param_map(USERVOICE, 0x59); m_ui.UservoicePEGLevel1Dial -> set_param_map(USERVOICE, 0x5a); m_ui.UservoicePEGLevel2Dial -> set_param_map(USERVOICE, 0x5b); m_ui.UservoicePEGLevel3Dial -> set_param_map(USERVOICE, 0x5c); m_ui.UservoicePEGLevel4Dial -> set_param_map(USERVOICE, 0x5d); m_ui.UservoiceResonanceDial -> set_param_map(USERVOICE, 0x5e); m_ui.UservoiceVelocityDial -> set_param_map(USERVOICE, 0x5f); m_ui.UservoiceCutoffDial -> set_param_map(USERVOICE, 0x60); m_ui.UservoiceCutoffBreak1Dial -> set_param_map(USERVOICE, 0x61); m_ui.UservoiceCutoffBreak2Dial -> set_param_map(USERVOICE, 0x62); m_ui.UservoiceCutoffBreak3Dial -> set_param_map(USERVOICE, 0x63); m_ui.UservoiceCutoffBreak4Dial -> set_param_map(USERVOICE, 0x64); m_ui.UservoiceCutoffOffset1Dial-> set_param_map(USERVOICE, 0x65); m_ui.UservoiceCutoffOffset2Dial-> set_param_map(USERVOICE, 0x66); m_ui.UservoiceCutoffOffset3Dial-> set_param_map(USERVOICE, 0x67); m_ui.UservoiceCutoffOffset4Dial-> set_param_map(USERVOICE, 0x68); m_ui.UservoiceFEGVelLevelDial -> set_param_map(USERVOICE, 0x69); m_ui.UservoiceFEGVelRateDial -> set_param_map(USERVOICE, 0x6a); m_ui.UservoiceFEGScalingDial -> set_param_map(USERVOICE, 0x6b); m_ui.UservoiceFEGCenterDial -> set_param_map(USERVOICE, 0x6c); m_ui.UservoiceFEGRate1Dial -> set_param_map(USERVOICE, 0x6d); m_ui.UservoiceFEGRate2Dial -> set_param_map(USERVOICE, 0x6e); m_ui.UservoiceFEGRate3Dial -> set_param_map(USERVOICE, 0x6f); m_ui.UservoiceFEGRate4Dial -> set_param_map(USERVOICE, 0x70); m_ui.UservoiceFEGLevel0Dial -> set_param_map(USERVOICE, 0x71); m_ui.UservoiceFEGLevel1Dial -> set_param_map(USERVOICE, 0x72); m_ui.UservoiceFEGLevel2Dial -> set_param_map(USERVOICE, 0x73); m_ui.UservoiceFEGLevel3Dial -> set_param_map(USERVOICE, 0x74); m_ui.UservoiceFEGLevel4Dial -> set_param_map(USERVOICE, 0x75); m_ui.UservoiceElementLevelDial -> set_param_map(USERVOICE, 0x76); m_ui.UservoiceLevelBreak1Dial -> set_param_map(USERVOICE, 0x77); m_ui.UservoiceLevelBreak2Dial -> set_param_map(USERVOICE, 0x78); m_ui.UservoiceLevelBreak3Dial -> set_param_map(USERVOICE, 0x79); m_ui.UservoiceLevelBreak4Dial -> set_param_map(USERVOICE, 0x7a); m_ui.UservoiceLevelOffset1Dial -> set_param_map(USERVOICE, 0x7b); m_ui.UservoiceLevelOffset2Dial -> set_param_map(USERVOICE, 0x7c); m_ui.UservoiceLevelOffset3Dial -> set_param_map(USERVOICE, 0x7d); m_ui.UservoiceLevelOffset4Dial -> set_param_map(USERVOICE, 0x7e); m_ui.UservoiceVelCurveDial -> set_param_map(USERVOICE, 0x7f); m_ui.UservoicePanDial -> set_param_map(USERVOICE, 0x80); m_ui.UservoiceAEGRateDial -> set_param_map(USERVOICE, 0x81); m_ui.UservoiceAEGCenterDial -> set_param_map(USERVOICE, 0x82); m_ui.UservoiceAEGDelayDial -> set_param_map(USERVOICE, 0x83); m_ui.UservoiceAEGAttackDial -> set_param_map(USERVOICE, 0x84); m_ui.UservoiceAEGDecay1Dial -> set_param_map(USERVOICE, 0x85); m_ui.UservoiceAEGDecay2Dial -> set_param_map(USERVOICE, 0x86); m_ui.UservoiceAEGReleaseDial -> set_param_map(USERVOICE, 0x87); m_ui.UservoiceAEGLevel1Dial -> set_param_map(USERVOICE, 0x88); m_ui.UservoiceAEGLevel2Dial -> set_param_map(USERVOICE, 0x89); m_ui.UservoiceAEGOffsetDial -> set_param_map(USERVOICE, 0x8a); m_ui.UservoiceAEGResonanceDial -> set_param_map(USERVOICE, 0x8c); // Make sure there's nothing pending... m_pMasterMap->reset_part_dirty(); m_pMasterMap->reset_user_dirty(); m_iDirtyCount = 0; // Is any session pending to be loaded? if (!m_pOptions->sessionFiles.isEmpty()) { // Just load the prabably startup session... if (loadSessionFile(m_pOptions->sessionFiles.first())) m_pOptions->sessionFiles.clear(); } else { // Open up with a new empty session... newSession(); } // Make it ready :-) statusBar()->showMessage(tr("Ready"), 3000); } // Window close event handlers. bool qxgeditMainForm::queryClose (void) { bool bQueryClose = closeSession(); // Try to save current general state... if (m_pOptions) { // Try to save current positioning. if (bQueryClose) { // Save decorations state. m_pOptions->bMenubar = m_ui.MenuBar->isVisible(); m_pOptions->bStatusbar = statusBar()->isVisible(); m_pOptions->bToolbar = m_ui.ToolBar->isVisible(); // Specific options... if (m_pMasterMap) m_pOptions->bUservoiceAutoSend = m_pMasterMap->auto_send(); // Save main windows state. m_pOptions->saveWidgetGeometry(this, true); } } return bQueryClose; } void qxgeditMainForm::closeEvent ( QCloseEvent *pCloseEvent ) { // Let's be sure about that... if (queryClose()) { pCloseEvent->accept(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QApplication::exit(0); #else QApplication::quit(); #endif } else { pCloseEvent->ignore(); } } // Window drag-n-drop event handlers. void qxgeditMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent ) { // Accept external drags only... if (pDragEnterEvent->source() == nullptr && pDragEnterEvent->mimeData()->hasUrls()) { pDragEnterEvent->accept(); } else { pDragEnterEvent->ignore(); } } void qxgeditMainForm::dropEvent ( QDropEvent* pDropEvent ) { // Accept externally originated drops only... if (pDropEvent->source()) return; const QMimeData *pMimeData = pDropEvent->mimeData(); if (pMimeData->hasUrls()) { QString sFilename = QDir::toNativeSeparators(pMimeData->urls().first().toLocalFile()); // Close current session and try to load the new one... if (!sFilename.isEmpty() && closeSession()) loadSessionFile(sFilename); } } // LADISH Level 1 -- SIGUSR1 signal handler. void qxgeditMainForm::handle_sigusr1 (void) { #ifdef HAVE_SIGNAL_H char c; if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0) saveSession(false); #endif } void qxgeditMainForm::handle_sigterm (void) { #ifdef HAVE_SIGNAL_H char c; if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0) close(); #endif } // RPN Event handler. void qxgeditMainForm::rpnReceived ( unsigned char ch, unsigned short rpn, unsigned short val ) { if (m_pMasterMap) m_pMasterMap->set_rpn_value(ch, rpn, val); } // NRPN Event handler. void qxgeditMainForm::nrpnReceived ( unsigned char ch, unsigned short nrpn, unsigned short val ) { if (m_pMasterMap) m_pMasterMap->set_nrpn_value(ch, nrpn, val); } // SYSEX Event handler. void qxgeditMainForm::sysexReceived ( const QByteArray& sysex ) { if (m_pMasterMap) { qxgeditXGMasterMap::SysexData sysex_data; m_pMasterMap->add_sysex_data(sysex_data, (unsigned char *) sysex.data(), (unsigned short) sysex.length()); m_pMasterMap->set_sysex_data(sysex_data); } } //------------------------------------------------------------------------- // qxgeditMainForm -- Session file stuff. // Format the displayable session filename. QString qxgeditMainForm::sessionName ( const QString& sFilename ) { const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath); QString sSessionName = sFilename; if (sSessionName.isEmpty()) sSessionName = tr("Untitled") + QString::number(m_iUntitled); else if (!bCompletePath) sSessionName = QFileInfo(sSessionName).baseName(); return sSessionName; } // Create a new session file from scratch. bool qxgeditMainForm::newSession (void) { // Check if we can do it. if (!closeSession()) return false; // Reset it all... masterReset(); // Ok, increment untitled count. m_iUntitled++; // Stabilize form. m_sFilename.clear(); m_iDirtyCount = 0; stabilizeForm(); return true; } // Open an existing sampler session. bool qxgeditMainForm::openSession (void) { if (m_pOptions == nullptr) return false; // Ask for the filename to open... QString sFilename; const QString sExt("syx"); const QString& sTitle = tr("Open Session"); const QString& sFilter = tr("Session files (*.%1)").arg(sExt); #if 0//QT_VERSION < QT_VERSION_CHECK(4, 4, 0) sFilename = QFileDialog::getOpenFileName(this, sTitle, m_pOptions->sSessionDir, sFilter); #else // Construct open-file session/template dialog... QFileDialog fileDialog(this, sTitle, m_pOptions->sSessionDir, sFilter); // Set proper open-file modes... fileDialog.setAcceptMode(QFileDialog::AcceptOpen); fileDialog.setFileMode(QFileDialog::ExistingFile); fileDialog.setHistory(m_pOptions->recentFiles); fileDialog.setDefaultSuffix(sExt); // Stuff sidebar... QList urls(fileDialog.sidebarUrls()); urls.append(QUrl::fromLocalFile(m_pOptions->sSessionDir)); fileDialog.setSidebarUrls(urls); // Show dialog... if (!fileDialog.exec()) return false; // Have the open-file name... sFilename = fileDialog.selectedFiles().first(); #endif // Have we cancelled? if (sFilename.isEmpty()) return false; // Check if we're going to discard safely the current one... if (!closeSession()) return false; // Load it right away. return loadSessionFile(sFilename); } // Save current sampler session with another name. bool qxgeditMainForm::saveSession ( bool bPrompt ) { if (m_pOptions == nullptr) return false; // Suggest a filename, if there's none... QString sFilename = m_sFilename; if (sFilename.isEmpty()) bPrompt = true; // Ask for the file to save... if (bPrompt) { // Prompt the guy... const QString sExt("syx"); const QString& sTitle = tr("Save Session"); const QString& sFilter = tr("Session files (*.%1)").arg(sExt); #if 0//QT_VERSION < QT_VERSION_CHECK(4, 4, 0) sFilename = QFileDialog::getSaveFileName(this, sTitle, sFilename, sFilter); #else // Construct save-file session/template dialog... QFileDialog fileDialog(this, sTitle, sFilename, sFilter); // Set proper save-file modes... fileDialog.setAcceptMode(QFileDialog::AcceptSave); fileDialog.setFileMode(QFileDialog::AnyFile); fileDialog.setHistory(m_pOptions->recentFiles); fileDialog.setDefaultSuffix(sExt); // Stuff sidebar... QList urls(fileDialog.sidebarUrls()); urls.append(QUrl::fromLocalFile(m_pOptions->sSessionDir)); fileDialog.setSidebarUrls(urls); // Show save-file dialog... if (!fileDialog.exec()) return false; // Have the save-file name... sFilename = fileDialog.selectedFiles().first(); #endif // Have we cancelled it? if (sFilename.isEmpty()) return false; // Enforce extension... if (QFileInfo(sFilename).suffix() != sExt) { sFilename += '.' + sExt; // Check if already exists... if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) { if (QMessageBox::warning(this, tr("Warning"), tr("The file already exists:\n\n" "\"%1\"\n\n" "Do you want to replace it?") .arg(sessionName(sFilename)), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return false; } } } // Save it right away. return saveSessionFile(sFilename); } // Close current session. bool qxgeditMainForm::closeSession (void) { bool bClose = true; // Are we dirty enough to prompt it? if (m_iDirtyCount > 0) { switch (QMessageBox::warning(this, tr("Warning"), tr("The current session has been changed:\n\n" "\"%1\"\n\n" "Do you want to save the changes?") .arg(sessionName(m_sFilename)), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)) { case QMessageBox::Save: bClose = saveSession(false); // Fall thru.... case QMessageBox::Discard: break; default: // Cancel. bClose = false; break; } } // If we may close it, dot it. if (bClose) { // TODO: Actually close session... // we're now clean, for sure. m_iDirtyCount = 0; } return bClose; } // Load a session from specific file path. bool qxgeditMainForm::loadSessionFile ( const QString& sFilename ) { // Open the source file... QFile file(sFilename); if (!file.open(QIODevice::ReadOnly)) return false; // Tell the world we'll take some time... QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); // Reset it all... masterReset(); int iSysex = 0; unsigned short iBuff = 0; unsigned char *pBuff = nullptr; unsigned short i = 0; // Read the file.... qxgeditXGMasterMap::SysexData sysex_data; while (!file.atEnd()) { // (Re)allocate buffer... if (i >= iBuff) { unsigned char *pTemp = pBuff; iBuff += 1024; pBuff = new unsigned char [iBuff]; if (pTemp) { ::memcpy(pBuff, pTemp, i); delete [] pTemp; } } // Read the next chunk... unsigned short iRead = file.read((char *) pBuff + i, iBuff - i) + i; while (i < iRead) { if (pBuff[i++] == 0xf7) { ++iSysex; m_pMasterMap->add_sysex_data(sysex_data, pBuff, i); if (i < iRead) { ::memmove(pBuff, pBuff + i, iRead -= i); i = 0; } } } } // Cleanup... if (pBuff) delete [] pBuff; file.close(); // Notify! m_pMasterMap->set_sysex_data(sysex_data, (iSysex > 0)); // Deferred QS300 Bulk Dump feedback... for (unsigned short iUser = 0; iUser < 32; ++iUser) { if (m_pMasterMap->user_dirty(iUser)) { m_pMasterMap->send_user(iUser); m_pMasterMap->set_user_dirty(iUser, false); } } // Deferred XG Multi Part feedback... for (unsigned short iPart = 0; iPart < 16; ++iPart) { if (m_pMasterMap->part_dirty(iPart)) { m_pMasterMap->send_part(iPart); m_pMasterMap->set_part_dirty(iPart, false); } } // We're formerly done. QApplication::restoreOverrideCursor(); // Reset the official session title. m_sFilename = sFilename; updateRecentFiles(sFilename); m_iDirtyCount = 0; // Save as default session directory. if (m_pOptions) m_pOptions->sSessionDir = QFileInfo(sFilename).absolutePath(); stabilizeForm(); return (iSysex > 0); } // Save current session to specific file path. bool qxgeditMainForm::saveSessionFile ( const QString& sFilename ) { // Open the target file... QFile file(sFilename); if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) return false; // Tell the world we'll take some time... QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); // XG Parameter changes... XGParamMasterMap::const_iterator iter = m_pMasterMap->constBegin(); for (; iter != m_pMasterMap->constEnd(); ++iter) { XGParam *pParam = iter.value(); if (pParam->high() == 0x11 || pParam->value() == pParam->def()) continue; XGParamSysex sysex(pParam); file.write((const char *) sysex.data(), sysex.size()); } // (QS300) USER VOICE Bulk Dumps, whether dirty... for (unsigned short iUser = 0; iUser < 32; ++iUser) { if (m_pMasterMap->user_dirty(iUser)) { XGUserVoiceSysex sysex(iUser); file.write((const char *) sysex.data(), sysex.size()); } } file.close(); // We're formerly done. QApplication::restoreOverrideCursor(); // Reset the official session title. m_sFilename = sFilename; updateRecentFiles(sFilename); m_iDirtyCount = 0; // Save as default session directory. if (m_pOptions) m_pOptions->sSessionDir = QFileInfo(sFilename).absolutePath(); stabilizeForm(); return true; } //------------------------------------------------------------------------- // qxgeditMainForm -- File Action slots. // Create a new sampler session. void qxgeditMainForm::fileNew (void) { // Of course we'll start clean new. newSession(); } // Open an existing sampler session. void qxgeditMainForm::fileOpen (void) { // Open it right away. openSession(); } // Open a recent file session. void qxgeditMainForm::fileOpenRecent (void) { // Retrive filename index from action data... QAction *pAction = qobject_cast (sender()); if (pAction && m_pOptions) { int iIndex = pAction->data().toInt(); if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) { QString sFilename = m_pOptions->recentFiles[iIndex]; // Check if we can safely close the current session... if (!sFilename.isEmpty() && closeSession()) loadSessionFile(sFilename); } } } // Save current sampler session. void qxgeditMainForm::fileSave (void) { // Save it right away. saveSession(false); } // Save current sampler session with another name. void qxgeditMainForm::fileSaveAs (void) { // Save it right away, maybe with another name. saveSession(true); } // Exit application program. void qxgeditMainForm::fileExit (void) { // Go for close the whole thing. close(); } //------------------------------------------------------------------------- // qxgeditMainForm -- View Action slots. // Show/hide the main program window menubar. void qxgeditMainForm::viewMenubar ( bool bOn ) { m_ui.MenuBar->setVisible(bOn); } // Show/hide the main program window statusbar. void qxgeditMainForm::viewStatusbar ( bool bOn ) { statusBar()->setVisible(bOn); } // Show/hide the file-toolbar. void qxgeditMainForm::viewToolbar ( bool bOn ) { m_ui.ToolBar->setVisible(bOn); } // Randomize current parameter page view. void qxgeditMainForm::viewRandomize (void) { if (m_pMasterMap == nullptr) return; float p = 100.0f; if (m_pOptions) { p = m_pOptions->fRandomizePercent; if (m_pOptions->bConfirmReset) { QString sText; switch (m_ui.MainTabWidget->currentIndex()) { case 0: // SYSTEM / EFFECT page... switch (m_ui.SystemEffectToolBox->currentIndex()) { case 1: // REVERB section... sText = tr("REVERB / %1") .arg(m_ui.ReverbTypeCombo->currentText()); break; case 2: // CHORUS section... sText = tr("CHORUS / %1") .arg(m_ui.ChorusTypeCombo->currentText()); break; case 3: // VARIATION section... sText = tr("VARIATION / %1") .arg(m_ui.VariationTypeCombo->currentText()); break; default: break; } break; case 1: // MULTI PART page... sText = tr("MULTI PART / %1") .arg(m_ui.MultipartCombo->currentText()); break; case 2: // DRUM SETUP page... sText = tr("DRUM SETUP / %1 - %2") .arg(m_ui.DrumsetupCombo->currentText()) .arg(m_ui.DrumsetupNoteCombo->currentText()); break; case 3: // USER VOICE page... sText = tr("USER VOICE / %1 - %2") .arg(m_ui.UservoiceCombo->currentText()) .arg(m_ui.UservoiceElementCombo->currentText()); break; default: break; } if (QMessageBox::warning(this, tr("Warning"), tr("About to randomize current parameter values:\n\n" "%1.\n\n" "Are you sure?").arg(sText), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } } switch (m_ui.MainTabWidget->currentIndex()) { case 0: // SYSTEM / EFFECT page... switch (m_ui.SystemEffectToolBox->currentIndex()) { case 1: // REVERB section... m_pMasterMap->REVERB.randomize_value(p); break; case 2: // CHORUS section... m_pMasterMap->CHORUS.randomize_value(p); break; case 3: // VARIATION section... m_pMasterMap->VARIATION.randomize_value(p); break; default: break; } break; case 1: // MULTI PART page... m_pMasterMap->randomize_part(m_ui.MultipartCombo->currentIndex(), p); break; case 2: // DRUM SETUP page... m_pMasterMap->randomize_drums( m_ui.DrumsetupCombo->currentIndex(), m_ui.DrumsetupNoteCombo->itemData( m_ui.DrumsetupNoteCombo->currentIndex()).toUInt(), p); break; case 3: // USER VOICE page... m_pMasterMap->randomize_user(m_ui.UservoiceCombo->currentIndex(), p); break; default: break; } stabilizeForm(); } // Show options dialog. void qxgeditMainForm::viewOptions (void) { if (m_pOptions == nullptr) return; // Load the current setup settings. const bool bOldCompletePath = m_pOptions->bCompletePath; const int iOldMaxRecentFiles = m_pOptions->iMaxRecentFiles; const int iOldBaseFontSize = m_pOptions->iBaseFontSize; const QString sOldStyleTheme = m_pOptions->sStyleTheme; const QString sOldColorTheme = m_pOptions->sColorTheme; // Load the current setup settings. qxgeditOptionsForm optionsForm(this); optionsForm.setOptions(m_pOptions); if (optionsForm.exec()) { // Check whether restart is needed or whether // custom options maybe set up immediately... int iNeedRestart = 0; if (m_pOptions->sStyleTheme != sOldStyleTheme) { if (m_pOptions->sStyleTheme.isEmpty()) { ++iNeedRestart; } else { QApplication::setStyle( QStyleFactory::create(m_pOptions->sStyleTheme)); } } if (m_pOptions->sColorTheme != sOldColorTheme) { if (m_pOptions->sColorTheme.isEmpty()) { ++iNeedRestart; } else { QPalette pal; if (qxgeditPaletteForm::namedPalette( &m_pOptions->settings(), m_pOptions->sColorTheme, pal)) QApplication::setPalette(pal); } } // Show restart message if needed... if (iOldBaseFontSize != m_pOptions->iBaseFontSize) ++iNeedRestart; if (( bOldCompletePath && !m_pOptions->bCompletePath) || (!bOldCompletePath && m_pOptions->bCompletePath) || (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles)) updateRecentFilesMenu(); // Show restart needed message... if (iNeedRestart > 0) { QMessageBox::information(this, tr("Information"), tr("Some settings may be only effective\n" "next time you start this program.")); } } // This makes it. stabilizeForm(); } //------------------------------------------------------------------------- // qxgeditMainForm -- Help Action slots. // Show information about application program. void qxgeditMainForm::helpAbout (void) { // Stuff the about box text... QString sText = "

" QXGEDIT_TITLE "

\n"; sText += "

" + tr(QXGEDIT_SUBTITLE) + "
\n"; sText += "
\n"; sText += tr("Version") + ": " PROJECT_VERSION "
\n"; // sText += "" + tr("Build") + ": " CONFIG_BUILD_DATE "
\n"; #ifdef CONFIG_DEBUG sText += ""; sText += tr("Debugging option enabled."); sText += "\n"; #endif sText += "
\n"; sText += tr("Using: Qt %1").arg(qVersion()); #if defined(QT_STATIC) sText += "-static"; #endif sText += "
\n"; sText += "
\n"; sText += tr("Website") + ": " QXGEDIT_WEBSITE "
\n"; sText += "
\n"; sText += ""; sText += QXGEDIT_COPYRIGHT "
\n"; sText += "
\n"; sText += tr("This program is free software; you can redistribute it and/or modify it") + "
\n"; sText += tr("under the terms of the GNU General Public License version 2 or later."); sText += "
"; sText += "
\n"; sText += "

\n"; QMessageBox::about(this, tr("About"), sText); } // Show information about the Qt toolkit. void qxgeditMainForm::helpAboutQt (void) { QMessageBox::aboutQt(this); } //------------------------------------------------------------------------- // qxgeditMainForm -- Main window stabilization. void qxgeditMainForm::stabilizeForm (void) { // Update the main application caption... QString sSessionName = sessionName(m_sFilename); if (m_iDirtyCount > 0) sSessionName += ' ' + tr("[modified]"); setWindowTitle(sSessionName); // Update the main menu state... m_ui.fileSaveAction->setEnabled(m_iDirtyCount > 0); // Randomize view menu. m_ui.viewRandomizeAction->setEnabled(isRandomizable()); // Recent files menu. m_ui.fileOpenRecentMenu->setEnabled(m_pOptions->recentFiles.count() > 0); m_statusItems[StatusName]->setText(sessionName(m_sFilename)); if (m_iDirtyCount > 0) m_statusItems[StatusMod]->setText(tr("MOD")); else m_statusItems[StatusMod]->clear(); // QS300 User Voice dirty flag array status. if (m_pMasterMap) { unsigned short iUser = m_ui.UservoiceCombo->currentIndex(); m_ui.UservoiceSendButton->setEnabled(m_pMasterMap->user_dirty_1(iUser)); m_ui.UservoiceNameEdit->stabilizePreset(); } } // Update the recent files list and menu. void qxgeditMainForm::updateRecentFiles ( const QString& sFilename ) { if (m_pOptions == nullptr) return; // Remove from list if already there (avoid duplicates) int iIndex = m_pOptions->recentFiles.indexOf(sFilename); if (iIndex >= 0) m_pOptions->recentFiles.removeAt(iIndex); // Put it to front... m_pOptions->recentFiles.push_front(sFilename); } // Update the recent files list and menu. void qxgeditMainForm::updateRecentFilesMenu (void) { if (m_pOptions == nullptr) return; // Time to keep the list under limits. int iRecentFiles = m_pOptions->recentFiles.count(); while (iRecentFiles > m_pOptions->iMaxRecentFiles) { m_pOptions->recentFiles.pop_back(); iRecentFiles--; } // Rebuild the recent files menu... m_ui.fileOpenRecentMenu->clear(); for (int i = 0; i < iRecentFiles; i++) { const QString& sFilename = m_pOptions->recentFiles[i]; if (QFileInfo(sFilename).exists()) { QAction *pAction = m_ui.fileOpenRecentMenu->addAction( QString("&%1 %2").arg(i + 1).arg(sessionName(sFilename)), this, SLOT(fileOpenRecent())); pAction->setData(i); } } } // XG System Reset... void qxgeditMainForm::masterReset (void) { XGParam *pParam = m_pMasterMap->find_param(0x00, 0x00, 0x7e); if (pParam) pParam->set_value_update(0); } void qxgeditMainForm::masterResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "XG System.\n\n" "Are you sure?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } masterReset(); } void qxgeditMainForm::reverbResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "REVERB / %1.\n\n" "Are you sure?").arg(m_ui.ReverbTypeCombo->currentText()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } m_pMasterMap->REVERB.reset(); } void qxgeditMainForm::chorusResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "CHORUS / %1.\n\n" "Are you sure?").arg(m_ui.ChorusTypeCombo->currentText()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } m_pMasterMap->CHORUS.reset(); } void qxgeditMainForm::variationResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "VARIATION / %1.\n\n" "Are you sure?").arg(m_ui.VariationTypeCombo->currentText()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } m_pMasterMap->VARIATION.reset(); } // Switch the current MULTIPART section... void qxgeditMainForm::multipartComboActivated ( int iPart ) { if (m_pMasterMap) m_pMasterMap->MULTIPART.set_current_key(iPart); } // Switch the current MULTIPART Instrument Normal Voice... void qxgeditMainForm::multipartVoiceComboActivated ( int iVoice ) { if (m_iMultipartVoiceUpdate > 0) return; ++m_iMultipartVoiceUpdate; const QModelIndex& parent = m_ui.MultipartVoiceCombo->view()->currentIndex().parent(); // Check for a normal voice first... XGInstrument instr(parent.row()); if (instr.group()) { XGNormalVoice voice(&instr, iVoice); #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::multipartVoiceComboActivated(%d)" " parent=(%d) [%s/%s]", iVoice, parent.row(), instr.name(), voice.name()); #endif m_ui.MultipartPartModeDial->reset_value(); m_ui.MultipartBankMSBDial->set_value_update(voice.bank() >> 7); m_ui.MultipartBankLSBDial->set_value_update(voice.bank() & 0x7f); m_ui.MultipartProgramDial->set_value_update(voice.prog()); } else if (parent.row() == XGInstrument::count()) { // May it be a Drums voice... XGDrumKit drumkit(iVoice); if (drumkit.item()) { #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::multipartVoiceComboActivated(%d)" " parent=(%d) [Drums/%s]", iVoice, parent.row(), drumkit.name()); #endif m_ui.MultipartPartModeDial->set_value_update(1); // DRUMS m_ui.MultipartBankMSBDial->set_value_update(drumkit.bank() >> 7); m_ui.MultipartBankLSBDial->set_value_update(drumkit.bank() & 0x7f); m_ui.MultipartProgramDial->set_value_update(drumkit.prog()); } } else if (parent.row() == XGInstrument::count() + 1) { #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::multipartVoiceComboActivated(%d)" " parent=(%d) [QS300 User %d]", iVoice, parent.row(), iVoice + 1); #endif // Can only be a QS300 User voice... m_ui.MultipartPartModeDial->reset_value(); m_ui.MultipartBankMSBDial->set_value_update(63); m_ui.MultipartBankLSBDial->set_value_update(0); m_ui.MultipartProgramDial->set_value_update(iVoice); // QS300 USser voice immediate conviniency... m_ui.UservoiceCombo->setCurrentIndex(iVoice); uservoiceComboActivated(iVoice); } --m_iMultipartVoiceUpdate; } void qxgeditMainForm::multipartVoiceChanged (void) { if (m_iMultipartVoiceUpdate > 0) return; ++m_iMultipartVoiceUpdate; const unsigned short iBank = (m_ui.MultipartBankMSBDial->value() << 7) | m_ui.MultipartBankLSBDial->value(); const unsigned char iProg = m_ui.MultipartProgramDial->value(); unsigned short i = 0; // Normal regular voice lookup... for (; i < XGInstrument::count(); ++i) { XGInstrument instr(i); int j = instr.find_voice(iBank, iProg); if (j >= 0) { XGNormalVoice voice(&instr, j); // m_ui.MultipartVoiceCombo->showPopup(); const QModelIndex& parent = m_ui.MultipartVoiceCombo->model()->index(i, 0); const QModelIndex& index = m_ui.MultipartVoiceCombo->model()->index(j, 0, parent); #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::multipartVoiceChanged(%d)" " parent=%d bank=%u prog=%u [%s/%s]", index.row(), parent.row(), iBank, iProg, instr.name(), voice.name()); #endif // m_ui.MultipartVoiceCombo->view()->setCurrentIndex(index); QModelIndex oldroot = m_ui.MultipartVoiceCombo->rootModelIndex(); m_ui.MultipartVoiceCombo->setRootModelIndex(parent); m_ui.MultipartVoiceCombo->setCurrentIndex(index.row()); m_ui.MultipartVoiceCombo->setRootModelIndex(oldroot); // m_ui.MultipartPartModeDial->reset_value(); break; } } // Drums voice lookup... if (i >= XGInstrument::count()) { unsigned short k = 0; for (; k < XGDrumKit::count(); ++k) { XGDrumKit drumkit(k); if (drumkit.bank() == iBank && drumkit.prog() == iProg) { // m_ui.MultipartVoiceCombo->showPopup(); const QModelIndex& parent = m_ui.MultipartVoiceCombo->model()->index(i, 0); const QModelIndex& index = m_ui.MultipartVoiceCombo->model()->index(k, 0, parent); #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::multipartVoiceChanged(%d)" " parent=%d bank=%u prog=%u [Drums/%s]", index.row(), parent.row(), iBank, iProg, drumkit.name()); #endif // m_ui.MultipartVoiceCombo->view()->setCurrentIndex(index); QModelIndex oldroot = m_ui.MultipartVoiceCombo->rootModelIndex(); m_ui.MultipartVoiceCombo->setRootModelIndex(parent); m_ui.MultipartVoiceCombo->setCurrentIndex(index.row()); m_ui.MultipartVoiceCombo->setRootModelIndex(oldroot); // m_ui.MultipartPartModeDial->set_value_update(1); // DRUMS break; } } // QS300 voice lookup... if (k >= XGDrumKit::count() && iBank == (63 << 7)) { // m_ui.MultipartVoiceCombo->showPopup(); const QModelIndex& parent = m_ui.MultipartVoiceCombo->model()->index(++i, 0); const QModelIndex& index = m_ui.MultipartVoiceCombo->model()->index(iProg, 0, parent); #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::multipartVoiceChanged(%d)" " parent=%d bank=%u prog=%u [QS300 User %d]", index.row(), parent.row(), iBank, iProg, iProg + 1); #endif // m_ui.MultipartVoiceCombo->view()->setCurrentIndex(index); QModelIndex oldroot = m_ui.MultipartVoiceCombo->rootModelIndex(); m_ui.MultipartVoiceCombo->setRootModelIndex(parent); m_ui.MultipartVoiceCombo->setCurrentIndex(index.row()); m_ui.MultipartVoiceCombo->setRootModelIndex(oldroot); // m_ui.MultipartPartModeDial->reset_value(); // QS300 User voice immediate conveniency... m_ui.UservoiceCombo->setCurrentIndex(iProg); uservoiceComboActivated(iProg); } } --m_iMultipartVoiceUpdate; } void qxgeditMainForm::multipartPartModeChanged ( unsigned short iPartMode ) { const bool bEnabled = (iPartMode == 0); m_ui.MultipartPedalCheck->setEnabled(bEnabled); m_ui.MultipartBankLSBDial->setEnabled(bEnabled); m_ui.MultipartPolyModeDial->setEnabled(bEnabled); m_ui.MultipartPortamentoBox->setEnabled(bEnabled); m_ui.MultipartTuningBox->setEnabled(bEnabled); m_ui.MultipartPATBox->setEnabled(bEnabled); m_ui.MultipartPitchEgBox->setEnabled(bEnabled); } void qxgeditMainForm::multipartResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; const int iPart = m_ui.MultipartCombo->currentIndex(); if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "MULTI PART / %1.\n\n" "Are you sure?").arg(m_ui.MultipartCombo->currentText()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } m_pMasterMap->reset_part(iPart); multipartVoiceChanged(); } // Switch the current DRUMSETUP section... void qxgeditMainForm::drumsetupComboActivated ( int iDrumset ) { if (m_pMasterMap) { int iNote = m_ui.DrumsetupNoteCombo->currentIndex(); unsigned short key = (unsigned short) (iDrumset << 7) + m_ui.DrumsetupNoteCombo->itemData(iNote).toUInt(); m_pMasterMap->DRUMSETUP.set_current_key(key); } } // Switch the current DRUMSETUP Drum Kit Voice... void qxgeditMainForm::drumsetupVoiceComboActivated ( int iDrumKit ) { XGDrumKit drumkit(iDrumKit); if (drumkit.item()) { XGDrumKit stdkit(0); // Standard Kit (default) m_ui.DrumsetupNoteCombo->clear(); for (unsigned short k = 13; k < 85; ++k) { QString sName; int i = drumkit.find_voice(k); if (i >= 0) { sName = XGDrumVoice(&drumkit, i).name(); } else if (stdkit.item()) { i = stdkit.find_voice(k); if (i >= 0) sName = XGDrumVoice(&stdkit, i).name(); } if (!sName.isEmpty()) sName += ' '; sName += QString("(%1)").arg(getsnote(k)); m_ui.DrumsetupNoteCombo->addItem(sName, k); } const int iNote = m_ui.DrumsetupNoteCombo->findData( m_pMasterMap->DRUMSETUP.current_key()); if (iNote >= 0) m_ui.DrumsetupNoteCombo->setCurrentIndex(iNote); } } void qxgeditMainForm::drumsetupNoteComboActivated ( int iNote ) { if (m_pMasterMap) { const int iDrumset = m_ui.DrumsetupCombo->currentIndex(); const unsigned short drum_key = m_ui.DrumsetupNoteCombo->itemData(iNote).toUInt(); const unsigned short key = (unsigned short) (iDrumset << 7) + drum_key; m_pMasterMap->DRUMSETUP.set_current_key(key); // Update drum voice/key defaults... const int iDrumKit = m_ui.DrumsetupVoiceCombo->currentIndex(); XGDrumKit drumkit(iDrumKit); if (drumkit.item()) { const int i = drumkit.find_voice(drum_key); if (i >= 0) { const XGDrumVoice drum(&drumkit, i); m_ui.DrumsetupLevelDial->setValue(drum.level()); m_ui.DrumsetupGroupDial->setValue(drum.group()); m_ui.DrumsetupPanDial->setValue(drum.pan()); m_ui.DrumsetupReverbDial->setValue(drum.reverb()); m_ui.DrumsetupChorusDial->setValue(drum.chorus()); m_ui.DrumsetupNoteOffCheck->setValue(drum.noteOff()); } } } } void qxgeditMainForm::drumsetupResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; const int iDrumset = m_ui.DrumsetupCombo->currentIndex(); if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "DRUM SETUP / %1.\n\n" "Are you sure?").arg(m_ui.DrumsetupCombo->currentText()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } XGParam *pParam = m_pMasterMap->find_param(0x00, 0x00, 0x7d); if (pParam) pParam->set_value_update(iDrumset); } // Switch the current USERVOICE section... void qxgeditMainForm::uservoiceComboActivated ( int iUser ) { if (m_pMasterMap) { m_pMasterMap->USERVOICE.set_current_key(iUser); if (m_pMasterMap->user_dirty_1(iUser)) { m_pMasterMap->send_user(iUser); m_pMasterMap->set_user_dirty_1(iUser, false); } stabilizeForm(); } } void qxgeditMainForm::uservoiceElementComboActivated ( int iElem ) { if (m_iUservoiceElementUpdate > 0) return; ++m_iUservoiceElementUpdate; if (m_pMasterMap) { int iCurrentElem = m_pMasterMap->USERVOICE.current_element(); if (m_ui.UservoiceElementDial->value() & (iElem + 1)) { m_pMasterMap->USERVOICE.set_current_element(iElem); } else { m_ui.UservoiceElementCombo->setCurrentIndex(iCurrentElem); } stabilizeForm(); } --m_iUservoiceElementUpdate; } void qxgeditMainForm::uservoiceResetButtonClicked (void) { if (m_pMasterMap == nullptr) return; const int iUser = m_ui.UservoiceCombo->currentIndex(); if (m_pOptions && m_pOptions->bConfirmReset) { if (QMessageBox::warning(this, tr("Warning"), tr("About to reset all parameters to default:\n\n" "USER VOICE / %1.\n\n" "Are you sure?").arg(m_ui.UservoiceCombo->currentText()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) return; } m_pMasterMap->reset_user(iUser); stabilizeForm(); } void qxgeditMainForm::uservoiceSendButtonClicked (void) { if (m_pMasterMap) { const int iUser = m_ui.UservoiceCombo->currentIndex(); m_pMasterMap->send_user(iUser); m_pMasterMap->set_user_dirty_1(iUser, false); stabilizeForm(); } } void qxgeditMainForm::uservoiceAutoSendCheckToggled ( bool bAuto ) { if (m_pMasterMap) m_pMasterMap->set_auto_send(bAuto); } void qxgeditMainForm::uservoiceElementChanged ( unsigned short iElems ) { #ifdef CONFIG_DEBUG qDebug("qxgeditMainForm::uservoiceElementChanged(%u)", iElems); #endif if (m_pMasterMap) { int iCurrentElem = m_pMasterMap->USERVOICE.current_element(); if ((iElems & (iCurrentElem + 1)) == 0) { iCurrentElem = iElems - 1; m_ui.UservoiceElementCombo->setCurrentIndex(iCurrentElem); m_pMasterMap->USERVOICE.set_current_element(iCurrentElem); stabilizeForm(); } } } // Main dirty flag raiser. void qxgeditMainForm::contentsChanged (void) { m_iDirtyCount++; stabilizeForm(); } // Check whether randomize current parameter page view is possible. bool qxgeditMainForm::isRandomizable (void) const { if (m_pMasterMap == nullptr) return false; switch (m_ui.MainTabWidget->currentIndex()) { case 0: // SYSTEM / EFFECT page... switch (m_ui.SystemEffectToolBox->currentIndex()) { case 1: // REVERB section... case 2: // CHORUS section... case 3: // VARIATION section... return true; default: break; } break; case 1: // MULTI PART page... case 2: // DRUM SETUP page... case 3: // USER VOICE page... return true; default: break; } return false; } //------------------------------------------------------------------------- // qxgeditMainForm -- Uservoice preset slot handlers. void qxgeditMainForm::uservoiceLoadPresetFile ( const QString& sFilename ) { // Open the source file... QFile file(sFilename); if (!file.open(QIODevice::ReadOnly)) return; // Tell the world we'll take some time... QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const int iUser = m_ui.UservoiceCombo->currentIndex(); qxgeditXGMasterMap::SysexData sysex_data; const unsigned short len = 0x188; // = 392 bytes unsigned char data[len]; if (file.read((char *) data, len)) { // Make sure it's a QS300 SysEx bulk dump... if (data[1] == 0x43 && data[3] == 0x4b && data[6] == 0x11) { // HACK! Correct checksum... data[7] = iUser; unsigned char cksum = 0; for (unsigned short i = 4; i < len - 2; ++i) { cksum += data[i]; cksum &= 0x7f; } data[len - 2] = 0x80 - cksum; m_pMasterMap->add_sysex_data(sysex_data, data, len); } } file.close(); const bool bResult = m_pMasterMap->set_sysex_data(sysex_data); // Deferred QS300 Bulk Dump feedback... if (bResult) { m_pMasterMap->set_user_dirty_2(iUser, false); if (m_pMasterMap->auto_send()) { m_pMasterMap->send_user(iUser); m_pMasterMap->set_user_dirty_1(iUser, false); } } // We're formerly done. QApplication::restoreOverrideCursor(); stabilizeForm(); // Any late warning? if (!bResult) { // Failure (maybe wrong preset)... QMessageBox::critical(this, tr("Error"), tr("Preset could not be loaded:\n\n" "\"%1\".\n\n" "Sorry.").arg(sFilename), QMessageBox::Cancel); } } void qxgeditMainForm::uservoiceSavePresetFile ( const QString& sFilename ) { // Open the target file... QFile file(sFilename); if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) return; // Tell the world we'll take some time... QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const int iUser = m_ui.UservoiceCombo->currentIndex(); // (QS300) USER VOICE Bulk Dumps, whether dirty... XGUserVoiceSysex sysex(iUser); file.write((const char *) sysex.data(), sysex.size()); file.close(); // Just make the preset dirty... m_pMasterMap->set_user_dirty_2(iUser, false); // We're formerly done. QApplication::restoreOverrideCursor(); stabilizeForm(); } //------------------------------------------------------------------------- // qxgeditMainForm -- Messages window form handlers. // Messages output methods. void qxgeditMainForm::showMessage( const QString& s ) { statusBar()->showMessage(s, 3000); } void qxgeditMainForm::showMessageError( const QString& s ) { QMessageBox::critical(this, tr("Error"), s, QMessageBox::Ok); } // end of qxgeditMainForm.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditPitch.h0000644000000000000000000000013214772452451015644 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditPitch.h0000644000175000001440000000515014772452451015635 0ustar00rncbcusers// qxgeditPitch.h // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __qxgeditPitch_h #define __qxgeditPitch_h #include //---------------------------------------------------------------------------- // qxgeditPitch -- Custom widget class qxgeditPitch : public QFrame { Q_OBJECT public: // Constructor. qxgeditPitch(QWidget *pParent = nullptr); // Destructor. ~qxgeditPitch(); // Parameter getters. unsigned short attackTime() const; unsigned short attackLevel() const; unsigned short releaseTime() const; unsigned short releaseLevel() const; public slots: // Parameter setters. void setAttackTime(unsigned short iAttackTime); void setAttackLevel(unsigned short iAttackLevel); void setReleaseTime(unsigned short iReleaseTime); void setReleaseLevel(unsigned short iReleaseLevel); signals: // Parameter change signals. void attackTimeChanged(unsigned short iAttackTime); void attackLevelChanged(unsigned short iAttackLevel); void releaseTimeChanged(unsigned short iReleaseTime); void releaseLevelChanged(unsigned short iReleaseLevel); protected: // Draw canvas. void paintEvent(QPaintEvent *); // Draw rectangular point. QRect nodeRect(int iNode) const; int nodeIndex(const QPoint& pos) const; void dragNode(const QPoint& pos); // Mouse interaction. void mousePressEvent(QMouseEvent *pMouseEvent); void mouseMoveEvent(QMouseEvent *pMouseEvent); void mouseReleaseEvent(QMouseEvent *pMouseEvent); private: // Instance state. unsigned short m_iAttackTime; unsigned short m_iAttackLevel; unsigned short m_iReleaseTime; unsigned short m_iReleaseLevel; // Draw state. QPolygon m_poly; // Drag state. int m_iDragNode; QPoint m_posDrag; }; #endif // __qxgeditPitch_h // end of qxgeditPitch.h qxgedit-1.0.1/src/PaxHeaders/qxgeditDial.cpp0000644000000000000000000000013214772452451016001 xustar0030 mtime=1743410473.475607941 30 atime=1743410473.475374071 30 ctime=1743410473.475607941 qxgedit-1.0.1/src/qxgeditDial.cpp0000644000175000001440000001220114772452451015765 0ustar00rncbcusers// qxgeditDial.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditDial.h" #include "qxgeditKnob.h" #include "qxgeditSpin.h" #include "qxgeditDrop.h" #include "XGParam.h" #include #include //------------------------------------------------------------------------- // qxgeditDial - Custom composite widget. // // Constructor. qxgeditDial::qxgeditDial ( QWidget *pParent ) : XGParamWidget (pParent) { m_pLabel = new QLabel(); m_pKnob = new qxgeditKnob(); m_pSpin = new qxgeditSpin(); m_pDrop = new qxgeditDrop(); m_iBusy = 0; m_pLabel->setAlignment(Qt::AlignCenter); m_pKnob->setSingleStep(7); m_pKnob->setNotchesVisible(true); m_pSpin->setAlignment(Qt::AlignCenter); int iMaximumHeight = QFontMetrics(QWidget::font()).lineSpacing() + 2; m_pSpin->setMaximumHeight(iMaximumHeight); m_pDrop->setMaximumHeight(iMaximumHeight); QVBoxLayout *pVBoxLayout = new QVBoxLayout(); pVBoxLayout->setContentsMargins(0, 0, 0, 0); pVBoxLayout->setSpacing(0); pVBoxLayout->addWidget(m_pLabel); pVBoxLayout->addWidget(m_pKnob); pVBoxLayout->addWidget(m_pSpin); pVBoxLayout->addWidget(m_pDrop); QWidget::setLayout(pVBoxLayout); setMaximumSize(QSize(56, 76)); QObject::connect(m_pKnob, SIGNAL(valueChanged(int)), SLOT(knobValueChanged(int))); QObject::connect(m_pSpin, SIGNAL(valueChanged(unsigned short)), SLOT(spinValueChanged(unsigned short))); QObject::connect(m_pDrop, SIGNAL(valueChanged(unsigned short)), SLOT(dropValueChanged(unsigned short))); // m_pDrop->hide(); } // Destructor. qxgeditDial::~qxgeditDial (void) { } // Special value text accessor. void qxgeditDial::setSpecialValueText ( const QString& sText ) { m_pSpin->setSpecialValueText(sText); } QString qxgeditDial::specialValueText (void) const { return m_pSpin->specialValueText(); } // Nominal value accessors. void qxgeditDial::reset_value (void) { XGParam *pParam = param(); if (pParam) pParam->set_value_update(pParam->def()); } void qxgeditDial::set_value_update ( unsigned short iValue ) { XGParam *pParam = param(); if (pParam) pParam->set_value_update(iValue); } void qxgeditDial::set_value ( unsigned short iValue, Observer *pSender ) { if (m_iBusy > 0) return; ++m_iBusy; if (m_pSpin->param()) { m_pSpin->setValue(iValue, pSender); m_pKnob->setValue(int(m_pSpin->value())); emit valueChanged(m_pSpin->value()); } else if (m_pDrop->param()) { m_pDrop->setValue(iValue, pSender); m_pKnob->setValue(int(m_pDrop->value())); emit valueChanged(m_pDrop->value()); } --m_iBusy; } unsigned short qxgeditDial::value (void) const { if (m_pSpin->param()) return m_pSpin->value(); else if (m_pDrop->param()) return m_pDrop->value(); return 0; } // Specialty parameter accessors. void qxgeditDial::set_param ( XGParam *pParam, Observer *pSender ) { if (m_iBusy > 0) return; ++m_iBusy; if (pParam && pParam->name()) { QWidget::setEnabled(true); m_pLabel->setText(pParam->label()); m_pKnob->setMinimum(int(pParam->min())); m_pKnob->setMaximum(int(pParam->max())); m_pKnob->setDefaultValue(int(pParam->def())); m_pKnob->setValue(int(pParam->value())); if (pParam->gets(pParam->min())) { m_pSpin->setParam(nullptr); m_pSpin->hide(); m_pDrop->setParam(pParam, pSender); m_pDrop->show(); } else { m_pSpin->setParam(pParam, pSender); m_pSpin->show(); m_pDrop->setParam(nullptr); m_pDrop->hide(); } QWidget::setToolTip(pParam->text()); emit valueChanged(pParam->value()); } else { QWidget::setEnabled(false); m_pLabel->clear(); m_pSpin->setParam(nullptr); m_pSpin->show(); m_pDrop->setParam(nullptr); m_pDrop->hide(); } --m_iBusy; } XGParam *qxgeditDial::param (void) const { if (m_pSpin->param()) return m_pSpin->param(); else if (m_pDrop->param()) return m_pDrop->param(); else return nullptr; } // Value settler public slot. void qxgeditDial::setValue ( unsigned short iValue ) { set_value(iValue, observer()); } // Internal widget slots. void qxgeditDial::knobValueChanged ( int iKnobValue ) { setValue(iKnobValue); } void qxgeditDial::spinValueChanged ( unsigned short iSpinValue ) { setValue(iSpinValue); } void qxgeditDial::dropValueChanged ( unsigned short iDropValue ) { setValue(iDropValue); } // end of qxgeditDial.cpp qxgedit-1.0.1/src/PaxHeaders/XGParam.h0000644000000000000000000000013214772452451014506 xustar0030 mtime=1743410473.474221551 30 atime=1743410473.474221551 30 ctime=1743410473.474221551 qxgedit-1.0.1/src/XGParam.h0000644000175000001440000003137214772452451014504 0ustar00rncbcusers// XGParam.h // /**************************************************************************** Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #ifndef __XGParam_h #define __XGParam_h #include "XGParamObserver.h" #include #include // Helper prototypes. const char *getsnote(unsigned short c); //------------------------------------------------------------------------- // Forward declarations (XGParam internals) // typedef struct _XGNormalVoiceGroup XGNormalVoiceGroup; typedef struct _XGNormalVoiceItem XGNormalVoiceItem; typedef struct _XGDrumKitItem XGDrumKitItem; typedef struct _XGDrumVoiceItem XGDrumVoiceItem; typedef struct _XGEffectParamItem XGEffectParamItem; typedef struct _XGEffectItem XGEffectItem; typedef struct _XGParamItem XGParamItem; typedef struct _XGRpnParamItem XGRpnParamItem; //------------------------------------------------------------------------- // class XGInstrument - XG Instrument/Normal Voice Group descriptor. // class XGInstrument { public: // Constructor. XGInstrument(unsigned short id); // Descriptor acessor. const XGNormalVoiceGroup *group() const; // Instrument name. const char *name() const; // Number of items. unsigned short size() const; // Voice index finder. int find_voice(unsigned short bank, unsigned short prog) const; // Instrument list size. static unsigned short count(); private: // Parameter descriptor. const XGNormalVoiceGroup *m_group; }; //------------------------------------------------------------------------- // class XGNormalVoice - XG Normal Voice descriptor. // class XGNormalVoice { public: // Constructor. XGNormalVoice(XGInstrument *instr, unsigned short id); // Voice properties accessors. unsigned short bank() const; unsigned short prog() const; const char *name() const; unsigned short elem() const; private: // Parameter descriptor. const XGNormalVoiceItem *m_item; }; //------------------------------------------------------------------------- // class XGDrumKit - XG Drum Kit descriptor. // class XGDrumKit { public: // Constructor. XGDrumKit(unsigned short id); // Descriptor acessor. const XGDrumKitItem *item() const; // Drum Kit property accessors. unsigned short bank() const; unsigned short prog() const; const char *name() const; unsigned short size() const; // Voice index finder. int find_voice(unsigned short key) const; // Drum Kit list size. static unsigned short count(); private: // Parameter descriptor. const XGDrumKitItem *m_item; }; //------------------------------------------------------------------------- // class XGDrumVoice - XG Drum Voice descriptor. // class XGDrumVoice { public: // Constructor. XGDrumVoice(XGDrumKit *drumkit, unsigned short id); // Voice properties accessors. unsigned short note() const; const char *name() const; // Default values accessors. unsigned short level() const; unsigned short group() const; unsigned short pan() const; unsigned short reverb() const; unsigned short chorus() const; unsigned short noteOff() const; private: // Parameter descriptor. const XGDrumVoiceItem *m_key; }; //------------------------------------------------------------------------- // class XGParam - XG Generic parameter descriptor. // class XGParam { public: // Constructor. XGParam(unsigned short high, unsigned short mid, unsigned short low); // Virtual destructor. virtual ~XGParam(); // Address acessors. unsigned short high() const; unsigned short mid() const; unsigned short low() const; // Number of bytes needed to encode subject. unsigned short size() const; // Virtual accessors. virtual const char *name() const; virtual unsigned short min() const; virtual unsigned short max() const; virtual unsigned short def() const; virtual float getv(unsigned short u) const; virtual unsigned short getu(float v) const; virtual const char *gets(unsigned short u) const; virtual const char *unit() const; // Decode param value from raw 7bit data. void set_data_value(unsigned char *data, unsigned short u) const; unsigned short data_value(unsigned char *data) const; // Decode param value from raw 2byte, 4bit data (eg. DETUNE). void set_data_value2(unsigned char *data, unsigned short u) const; unsigned short data_value2(unsigned char *data) const; // Value accessors. void set_value_update(unsigned short u, XGParamObserver *sender = nullptr); void set_value(unsigned short u, XGParamObserver *sender = nullptr); unsigned short value() const; // Virtual reset (to default). virtual void reset(XGParamObserver *sender = nullptr); // Busy flag predicate. bool busy() const; // Observers reset notification. void notify_reset(XGParamObserver *sender = nullptr); // Observers update notification. void notify_update(XGParamObserver *sender = nullptr); // Observer list accessors. void attach(XGParamObserver *observer); void detach(XGParamObserver *observer); const QList& observers() const; // Textual (name parsed) representations. QString label() const; QString text() const; // Randomizers (p = percent from value/def). void randomize_value(float p = 20.0f); void randomize_def(float p = 20.0f); protected: // Value randomizer (p = percent from v). void randomize(int u, float p); // Parameter descriptor. const XGParamItem *m_param; // Parameter state. unsigned short m_value; private: // Parameter address. unsigned short m_high; unsigned short m_mid; unsigned short m_low; // Parameter subject/observer stuff; bool m_busy; QList m_observers; }; //------------------------------------------------------------------------- // class XGEffectParam - XG Effect parameter descriptor. // class XGEffectParam : public XGParam { public: // Constructor. XGEffectParam(unsigned short high, unsigned short mid, unsigned short low, unsigned short etype); // Sub-address accessors. unsigned short etype() const; // Virtual accessors. const char *name() const; unsigned short min() const; unsigned short max() const; unsigned short def() const; float getv(unsigned short u) const; unsigned short getu(float v) const; const char *gets(unsigned short u) const; const char *unit() const; private: // Parameter sub-type. unsigned short m_etype; // Parameter sub-descriptor. const XGEffectParamItem *m_eparam; }; //------------------------------------------------------------------------- // class XGDataParam - XG Data parameter descriptor. // class XGDataParam : public XGParam { public: // Constructor. XGDataParam(unsigned short high, unsigned short mid, unsigned short low); // Destructor. ~XGDataParam(); // Data accessors. void set_data( unsigned char *data, unsigned short len, XGParamObserver *sender = nullptr); unsigned char *data() const; // Virtual reset (to default). void reset(XGParamObserver *sender = nullptr); private: // Parameter sub-descriptor. unsigned char *m_data; }; //------------------------------------------------------------------------- // class XGParamKey - XG Parameter map key. // class XGParamKey { public: // Constructor helper. XGParamKey(unsigned short high, unsigned short mid, unsigned short low) : m_high(high), m_mid(mid), m_low(low) {} XGParamKey(XGParam *param) : m_high(param->high()), m_mid(param->mid()), m_low(param->low()) {} // Key accessors. unsigned short high() const { return m_high; } unsigned short mid() const { return m_mid; } unsigned short low() const { return m_low; } // Map key comparator. bool operator< ( const XGParamKey& key ) const { if (m_high != key.high()) return (m_high < key.high()); else if (m_mid != key.mid()) return (m_mid < key.mid()); else return (m_low < key.low()); } private: // Key members. unsigned short m_high; unsigned short m_mid; unsigned short m_low; }; //------------------------------------------------------------------------- // class XGParamSet - XG Parameter map. // class XGParamSet : public QHash {}; //------------------------------------------------------------------------- // class XGParamMap - XG Parameter mapper. // class XGParamMap : public QMap { public: // Constructor. XGParamMap(); // Destructor. ~XGParamMap(); // Append method. void add_param(XGParam *param, unsigned short key); // Map finders. XGParam *find_param(unsigned short id); // Key param accessors. void set_key_param(XGParam *param); XGParam *key_param() const; // Key value accessors. void set_current_key(unsigned short key); unsigned short current_key () const; // Param set/factory method. XGParamSet *find_paramset(unsigned short id); // Local observers notify (key change). void notify_reset(); // Key/type name stuff. typedef QMap Keys; const Keys& keys() const; void add_key(unsigned short key, const QString& name); // Special element stride settings (USERVOICE, QS300). void set_elements(unsigned short elements); unsigned short elements() const; // Element key value accessors. void set_current_element(unsigned short element); unsigned short current_element () const; // All parameter reset (to default) void reset(XGParamObserver *sender = nullptr); // All parameter randomizer (p = percent from value/def). void randomize_value(int p = 100); void randomize_def(int p = 100); protected: // Local observer. class Observer : public XGParamObserver { public: // Constructor. Observer(XGParamMap *map) : XGParamObserver(nullptr), m_map(map) {} protected: // Observer reset/updater. void reset() { m_map->notify_reset(); } // Observer updater. void update() { reset(); } private: // Members. XGParamMap *m_map; }; private: // Instance variables. XGParam *m_key_param; unsigned short m_key; // Key param observer. Observer *m_observer; // Key names registry. Keys m_keys; // Special element stride settings (USERVOICE, QS300). unsigned short m_elements; unsigned short m_element; }; //------------------------------------------------------------------------- // class XGRpnParamKey - XG (N)RPN Parameter hash key. // class XGRpnParamKey { public: // Constructor helper. XGRpnParamKey(unsigned char channel, unsigned short param) : m_channel(channel), m_param(param) {} // Key accessors. unsigned char channel() const { return m_channel; } unsigned short param() const { return m_param; } // Map key comparator. bool operator< ( const XGRpnParamKey& key ) const { if (m_channel != key.channel()) return (m_channel < key.channel()); else return (m_channel < key.param()); } private: // Key members. unsigned char m_channel; unsigned short m_param; }; //------------------------------------------------------------------------- // class XGRpnParamMap - XG (N)RPN Parameter map. // class XGRpnParamMap : public QMap {}; //------------------------------------------------------------------------- // class XGParamMaster - XG Parameter master state database. // class XGParamMasterMap : public QMultiMap { public: // Constructor. XGParamMasterMap(); // Destructor. ~XGParamMasterMap(); // Pseudo-singleton accessor. static XGParamMasterMap *getInstance(); // Parameter group-maps. XGParamMap SYSTEM; XGParamMap REVERB; XGParamMap CHORUS; XGParamMap VARIATION; XGParamMap MULTIPART; XGParamMap DRUMSETUP; XGParamMap USERVOICE; // master append method void add_param(XGParam *param); // Add widget to map. void add_param_map(XGParam *param, XGParamMap *map); // Master map finders. XGParam *find_param( unsigned short high, unsigned short mid, unsigned short low) const; XGParam *find_param( const XGParamKey& key, unsigned short etype = 0) const; // Find map from param. XGParamMap *find_param_map(XGParam *param) const; // NRPN parameter map. XGRpnParamMap NRPN; private: // Instance variables. QHash m_params_map; // Pseudo-singleton reference. static XGParamMasterMap *g_pParamMasterMap; }; #endif // __XGParam_h // end of XGParam.h qxgedit-1.0.1/src/PaxHeaders/XGParamWidget.cpp0000644000000000000000000000013214772452451016205 xustar0030 mtime=1743410473.474607941 30 atime=1743410473.474607941 30 ctime=1743410473.474607941 qxgedit-1.0.1/src/XGParamWidget.cpp0000644000175000001440000000705314772452451016202 0ustar00rncbcusers// XGParamWidget.cpp // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "XGParamWidget.h" #ifdef XGPARAM_WIDGET_MAP #include #include //------------------------------------------------------------------------- // class XGParamWidgetMap - XGParam/Widget cross-map. // // Pseudo-singleton reference. XGParamWidgetMap *XGParamWidgetMap::g_pParamWidgetMap = nullptr; // Pseudo-singleton accessor (static). XGParamWidgetMap *XGParamWidgetMap::getInstance (void) { return g_pParamWidgetMap; } // Constructor. XGParamWidgetMap::XGParamWidgetMap(void) { // Pseudo-singleton set. g_pParamWidgetMap = this; } // Destructor. XGParamWidgetMap::~XGParamWidgetMap(void) { // Pseudo-singleton reset. g_pParamWidgetMap = nullptr; } // Add widget to map. void XGParamWidgetMap::add_widget ( QWidget *widget, XGParamMap *map, unsigned short id ) { XGParamInst inst(map, id); m_widget_map.insert(widget, inst); m_params_map.insert(inst, widget); } void XGParamWidgetMap::add_widget ( QWidget *widget, XGParam *param ) { XGParamMasterMap *pMasterMap = XGParamMasterMap::getInstance(); if (pMasterMap == nullptr) return; XGParamMap *map = pMasterMap->find_param_map(param); if (map == nullptr) return; add_widget(widget, map, param->low()); } void XGParamWidgetMap::add_widget ( QWidget *widget, const XGParamKey& key ) { XGParamMasterMap *pMasterMap = XGParamMasterMap::getInstance(); if (pMasterMap == nullptr) return; XGParam *param = pMasterMap->find_param(key); if (param == nullptr) return; add_widget(widget, param); } // State parameter lookup. XGParam *XGParamWidgetMap::find_param ( QWidget *widget ) const { XGParam *param = nullptr; if (m_widget_map.contains(widget)) param = m_widget_map.value(widget).param(); return param; } // Widget lookup. QWidget *XGParamWidgetMap::find_widget ( XGParamMap *map, unsigned id ) const { QWidget *widget = nullptr; XGParamInst inst(map, id); if (m_params_map.contains(inst)) widget = m_params_map.value(inst); return widget; } QWidget *XGParamWidgetMap::find_widget ( XGParam *param ) const { XGParamMasterMap *pMasterMap = XGParamMasterMap::getInstance(); if (pMasterMap == nullptr) return nullptr; XGParamMap *map = pMasterMap->find_param_map(param); if (map == nullptr) return nullptr; return find_widget(map, param->low()); }; QWidget *XGParamWidgetMap::find_widget ( const XGParamKey& key ) const { XGParamMasterMap *pMasterMap = XGParamMasterMap::getInstance(); if (pMasterMap == nullptr) return nullptr; XGParam *param = pMasterMap->find_param(key); if (param == nullptr) return nullptr; return find_widget(param); } #endif // XGPARAM_WIDGET_MAP // end of XGParamWidget.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditOptionsForm.ui0000644000000000000000000000013214772452451017242 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditOptionsForm.ui0000644000175000001440000003200014772452451017225 0ustar00rncbcusers rncbc aka Rui Nuno Capela qxgedit - Qt XG Editor. Copyright (C) 2005-2023, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. qxgeditOptionsForm 0 0 360 320 Options :/images/qxgedit.svg true false 0 &General Whether to ask for confirmation on parameter reset Confirm parameter &resets Qt::Horizontal 8 20 Whether to ask for confirmation on removals &Confirm removals Whether to show the complete directory path of loaded session files Show complete &path of session files &Number of recent files: MaxRecentFilesSpinBox The maximum number of recent files to keep in menu 0 20 5 &Randomize factor: RandomizePercentSpinBox Randomizer deviation from current value true % 1 0.1 100.0 0.1 20.0 &Base font size: BaseFontSizeComboBox Base application font size (pt.) true (default) 6 7 8 9 10 11 12 &Widget style theme: StyleThemeComboBox Custom widget style theme false (default) &Color palette theme: ColorThemeComboBox Custom color palette theme false (default) Wonton Soup KXStudio 22 22 24 24 Qt::TabFocus Manage custom color palette themes ... Qt::Vertical 20 8 &MIDI &Inputs: MidiInputListView 320 60 MIDI Readable clients / Output ports QAbstractItemView::ExtendedSelection true &Outputs: MidiOutputListView 320 60 MIDI Writable clients / Input ports QAbstractItemView::ExtendedSelection true Qt::Vertical 20 0 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok OptionsTabWidget ConfirmResetCheckBox ConfirmRemoveCheckBox CompletePathCheckBox MaxRecentFilesSpinBox RandomizePercentSpinBox BaseFontSizeComboBox StyleThemeComboBox ColorThemeComboBox MidiInputListView MidiOutputListView ColorThemeToolButton DialogButtonBox qxgedit-1.0.1/src/PaxHeaders/man10000644000000000000000000000013214772452451013615 xustar0030 mtime=1743410473.475322864 30 atime=1743410473.475031307 30 ctime=1743410473.475322864 qxgedit-1.0.1/src/man1/0000755000175000001440000000000014772452451013662 5ustar00rncbcusersqxgedit-1.0.1/src/man1/PaxHeaders/qxgedit.10000644000000000000000000000013214772452451015421 xustar0030 mtime=1743410473.475031307 30 atime=1743410473.475031307 30 ctime=1743410473.475031307 qxgedit-1.0.1/src/man1/qxgedit.10000644000175000001440000000110314772452451015404 0ustar00rncbcusers.TH QXGEDIT "1" "June 17, 2014" .SH NAME qxgedit \- Qt XG Editor .SH SYNOPSIS .B qxgedit [\fIoptions\fR] [\fIsyx-file\fR] .SH DESCRIPTION This manual page documents briefly the .B qxgedit command. .PP \fBQXGEdit\fP is a Qt GUI for editing MIDI System Exclusive files for XG devices (eg. Yamaha DB50XG). .SH OPTIONS .HP \fB\-h\fR, \fB\-\-help\fR .IP Show help about command line options .HP \fB\-v\fR, \fB\-\-version\fR .IP Show version information .SH FILES Configuration settings are stored in ~/.config/rncbc.org/QXGEdit.conf .SH AUTHOR QXGEdit was written by Rui Nuno Capela. qxgedit-1.0.1/src/man1/PaxHeaders/qxgedit.fr.10000644000000000000000000000013214772452451016027 xustar0030 mtime=1743410473.475322864 30 atime=1743410473.475031307 30 ctime=1743410473.475322864 qxgedit-1.0.1/src/man1/qxgedit.fr.10000644000175000001440000000156014772452451016021 0ustar00rncbcusers.TH QXGEDIT "1" "Juin 17, 2014" .SH NOM qxgedit \- éditeur XG en Qt .SH SYNOPSIS .B qxgedit [\fIoptions\fR] [\fIfichier-syx\fR] .SH DESCRIPTION Cette page de manuel documente rapidement la commande .B qxgedit . .PP \fBQXGEdit\fP est une interface graphique en Qt pour l'édition des fichiers MIDI System Exclusive pour les périphériques XG (comme le Yamaha DB50XG). .SH OPTIONS .HP \fB\-h\fR, \fB\-\-help\fR .IP Affiche de l'aide à propos des options de ligne de commande .HP \fB\-v\fR, \fB\-\-version\fR .IP Affiche des informations de version .SH FICHIERS Les paramètres de configuration sont stockés dans ~/.config/rncbc.org/QXGEdit.conf .SH AUTEUR QXGEdit a été écrit par Rui Nuno Capela. .PP La version française de cette page de manuel a été traduite par Olivier Humbert , pour le projet LibraZiK (mais peut être utilisée par d'autres). qxgedit-1.0.1/src/PaxHeaders/qxgeditScale.cpp0000644000000000000000000000013214772452451016157 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditScale.cpp0000644000175000001440000002111514772452451016147 0ustar00rncbcusers// qxgeditScale.cpp // /**************************************************************************** Copyright (C) 2005-2020, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditScale.h" #include #include //---------------------------------------------------------------------------- // qxgeditScale -- Custom widget // Constructor. qxgeditScale::qxgeditScale ( QWidget *pParent ) : QFrame(pParent), m_iBreak1(0), m_iBreak2(0), m_iBreak3(0), m_iBreak4(0), m_iOffset1(0), m_iOffset2(0), m_iOffset3(0), m_iOffset4(0), m_poly(6), m_iDragNode(-1) { setMouseTracking(true); setMinimumSize(QSize(160, 80)); QFrame::setFrameShape(QFrame::Panel); QFrame::setFrameShadow(QFrame::Sunken); } // Destructor. qxgeditScale::~qxgeditScale (void) { } // Parameter accessors. void qxgeditScale::setBreak1 ( unsigned short iBreak1 ) { if (iBreak1 > 127 - 3) iBreak1 = 127 - 3; if (m_iBreak1 != iBreak1) { m_iBreak1 = iBreak1; if (iBreak1 >= m_iBreak2) setBreak2(iBreak1 + 1); else update(); emit break1Changed(break1()); } } unsigned short qxgeditScale::break1 (void) const { return m_iBreak1; } void qxgeditScale::setBreak2 ( unsigned short iBreak2 ) { if (iBreak2 > 127 - 2) iBreak2 = 127 - 2; else if (iBreak2 < 1) iBreak2 = 1; if (m_iBreak2 != iBreak2) { m_iBreak2 = iBreak2; if (m_iBreak1 >= iBreak2) setBreak1(iBreak2 - 1); else if (iBreak2 >= m_iBreak3) setBreak3(iBreak2 + 1); else update(); emit break2Changed(break2()); } } unsigned short qxgeditScale::break2 (void) const { return m_iBreak2; } void qxgeditScale::setBreak3 ( unsigned short iBreak3 ) { if (iBreak3 > 127 - 1) iBreak3 = 127 - 1; else if (iBreak3 < 2) iBreak3 = 2; if (m_iBreak3 != iBreak3) { m_iBreak3 = iBreak3; if (m_iBreak2 >= iBreak3) setBreak2(iBreak3 - 1); else if (iBreak3 >= m_iBreak4) setBreak4(iBreak3 + 1); else update(); emit break3Changed(break3()); } } unsigned short qxgeditScale::break3 (void) const { return m_iBreak3; } void qxgeditScale::setBreak4 ( unsigned short iBreak4 ) { if (iBreak4 > 127) iBreak4 = 127; else if (iBreak4 < 3) iBreak4 = 3; if (m_iBreak4 != iBreak4) { m_iBreak4 = iBreak4; if (m_iBreak3 >= iBreak4) setBreak3(iBreak4 - 1); else update(); emit break4Changed(break4()); } } unsigned short qxgeditScale::break4 (void) const { return m_iBreak4; } void qxgeditScale::setOffset1 ( unsigned short iOffset1 ) { if (m_iOffset1 != iOffset1) { m_iOffset1 = iOffset1; update(); emit offset1Changed(offset1()); } } unsigned short qxgeditScale::offset1 (void) const { return m_iOffset1; } void qxgeditScale::setOffset2 ( unsigned short iOffset2 ) { if (m_iOffset2 != iOffset2) { m_iOffset2 = iOffset2; update(); emit offset2Changed(offset2()); } } unsigned short qxgeditScale::offset2 (void) const { return m_iOffset2; } void qxgeditScale::setOffset3 ( unsigned short iOffset3 ) { if (m_iOffset3 != iOffset3) { m_iOffset3 = iOffset3; update(); emit offset3Changed(offset3()); } } unsigned short qxgeditScale::offset3 (void) const { return m_iOffset3; } void qxgeditScale::setOffset4 ( unsigned short iOffset4 ) { if (m_iOffset4 != iOffset4) { m_iOffset4 = iOffset4; update(); emit offset4Changed(offset4()); } } unsigned short qxgeditScale::offset4 (void) const { return m_iOffset4; } // Draw curve. void qxgeditScale::paintEvent ( QPaintEvent *pPaintEvent ) { QPainter painter(this); const int h = height(); const int w = width(); const int h2 = h >> 1; const int x1 = 6 + int((m_iBreak1 * (w - 12)) >> 7); const int x2 = 6 + int((m_iBreak2 * (w - 12)) >> 7); const int x3 = 6 + int((m_iBreak3 * (w - 12)) >> 7); const int x4 = 6 + int((m_iBreak4 * (w - 12)) >> 7); const int y1 = h2 - ((int(m_iOffset1) - 64) * (h - 12) >> 7); const int y2 = h2 - ((int(m_iOffset2) - 64) * (h - 12) >> 7); const int y3 = h2 - ((int(m_iOffset3) - 64) * (h - 12) >> 7); const int y4 = h2 - ((int(m_iOffset4) - 64) * (h - 12) >> 7); m_poly.putPoints(0, 6, 0, y1, x1, y1, x2, y2, x3, y3, x4, y4, w, y4); const QPalette& pal = palette(); const bool bDark = (pal.window().color().value() < 0x7f); const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow); if (bDark) painter.fillRect(0, 0, w, h, pal.dark().color()); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(bDark ? Qt::gray : Qt::darkGray); const QPen oldpen(painter.pen()); QPen dotpen(oldpen); dotpen.setStyle(Qt::DotLine); painter.setPen(dotpen); painter.drawLine(0, h2, w, h2); painter.setPen(oldpen); painter.drawPolyline(m_poly); painter.setBrush(rgbLite); // pal.midlight().color() painter.drawRect(nodeRect(1)); painter.drawRect(nodeRect(2)); painter.drawRect(nodeRect(3)); painter.drawRect(nodeRect(4)); #ifdef CONFIG_DEBUG_0 painter.drawText(QFrame::rect(), Qt::AlignTop|Qt::AlignHCenter, tr("Break (%1,%2,%3,%4) Offset(%5,%6,%7,%8)") .arg(int(break1())) .arg(int(break2())) .arg(int(break3())) .arg(int(break4())) .arg(int(offset1()) - 64) .arg(int(offset2()) - 64) .arg(int(offset3()) - 64) .arg(int(offset4()) - 64)); #endif painter.setRenderHint(QPainter::Antialiasing, false); painter.end(); QFrame::paintEvent(pPaintEvent); } // Draw rectangular point. QRect qxgeditScale::nodeRect ( int iNode ) const { const QPoint& pos = m_poly.at(iNode); return QRect(pos.x() - 4, pos.y() - 4, 8, 8); } int qxgeditScale::nodeIndex ( const QPoint& pos ) const { if (nodeRect(4).contains(pos)) return 4; // Break4/Offset4 if (nodeRect(3).contains(pos)) return 3; // Break3/Offset3 if (nodeRect(2).contains(pos)) return 2; // Break2/Offset2 if (nodeRect(1).contains(pos)) return 1; // Break1/Offset1 return -1; } void qxgeditScale::dragNode ( const QPoint& pos ) { unsigned short *piBreak = nullptr; unsigned short *piOffset = nullptr; switch (m_iDragNode) { case 1: // Break1/Offset1 piBreak = &m_iBreak1; piOffset = &m_iOffset1; break; case 2: // Break2/Offset2 piBreak = &m_iBreak2; piOffset = &m_iOffset2; break; case 3: // Break3/Offset3 piBreak = &m_iBreak3; piOffset = &m_iOffset3; break; case 4: // Break4/Offset4 piBreak = &m_iBreak4; piOffset = &m_iOffset4; break; } if (piBreak && piOffset) { int iBreak = int(*piBreak) + ((pos.x() - m_posDrag.x()) << 7) / width(); int iOffset = int(*piOffset) + ((m_posDrag.y() - pos.y()) << 7) / height(); if (iBreak < 0) iBreak = 0; else if (iBreak > 127) iBreak = 127; if (iOffset < 0) iOffset = 0; else if (iOffset > 127) iOffset = 127; if (*piBreak != (unsigned short) iBreak || *piOffset != (unsigned short) iOffset) { m_posDrag = pos; switch (m_iDragNode) { case 1: // Break1/Offset1 setBreak1(iBreak); setOffset1(iOffset); break; case 2: // Break2/Offset2 setBreak2(iBreak); setOffset2(iOffset); break; case 3: // Break3/Offset3 setBreak3(iBreak); setOffset3(iOffset); break; case 4: // Break4/Offset4 setBreak4(iBreak); setOffset4(iOffset); break; } } } else if (nodeIndex(pos) >= 0) { setCursor(Qt::PointingHandCursor); } else { unsetCursor(); } } // Mouse interaction. void qxgeditScale::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (pMouseEvent->button() == Qt::LeftButton) { const QPoint& pos = pMouseEvent->pos(); const int iDragNode = nodeIndex(pos); if (iDragNode >= 0) { setCursor(Qt::SizeAllCursor); m_iDragNode = iDragNode; m_posDrag = pos; } } QFrame::mousePressEvent(pMouseEvent); } void qxgeditScale::mouseMoveEvent ( QMouseEvent *pMouseEvent ) { dragNode(pMouseEvent->pos()); } void qxgeditScale::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) { QFrame::mouseReleaseEvent(pMouseEvent); dragNode(pMouseEvent->pos()); if (m_iDragNode >= 0) { m_iDragNode = -1; unsetCursor(); } } // end of qxgeditScale.cpp qxgedit-1.0.1/src/PaxHeaders/qxgeditSpin.cpp0000644000000000000000000000013214772452451016041 xustar0030 mtime=1743410473.476607941 30 atime=1743410473.476607941 30 ctime=1743410473.476607941 qxgedit-1.0.1/src/qxgeditSpin.cpp0000644000175000001440000001412214772452451016031 0ustar00rncbcusers// qxgeditSpin.cpp // /**************************************************************************** Copyright (C) 2005-2019, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include "qxgeditAbout.h" #include "qxgeditSpin.h" #include "XGParam.h" #include #include //------------------------------------------------------------------------- // qxgeditSpin - Instance spin-box widget class. // // Constructor. qxgeditSpin::qxgeditSpin ( QWidget *pParent ) : QAbstractSpinBox(pParent), m_pParam(nullptr) { QAbstractSpinBox::setAccelerated(true); QObject::connect(this, SIGNAL(editingFinished()), SLOT(editingFinishedSlot())); QObject::connect(QAbstractSpinBox::lineEdit(), SIGNAL(textChanged(const QString&)), SLOT(valueChangedSlot(const QString&))); } // Destructor. qxgeditSpin::~qxgeditSpin (void) { } // Mark that we got actual value. void qxgeditSpin::showEvent ( QShowEvent */*pShowEvent*/ ) { if (m_pParam) { QAbstractSpinBox::lineEdit()->setText(textFromValue(m_pParam->value())); QAbstractSpinBox::interpretText(); } } // Nominal value accessors. void qxgeditSpin::setValue ( unsigned short iValue, XGParamObserver *pSender ) { if (m_pParam == nullptr) return; int iCursorPos = QAbstractSpinBox::lineEdit()->cursorPosition(); if (iValue < m_pParam->min()) iValue = m_pParam->min(); if (iValue > m_pParam->max() && m_pParam->max() > m_pParam->min()) iValue = m_pParam->max(); bool bValueChanged = (iValue != m_pParam->value()); m_pParam->set_value(iValue, pSender); QPalette pal; if (QAbstractSpinBox::isEnabled() && iValue != m_pParam->def()) { const QColor& rgbBase = (pal.window().color().value() < 0x7f ? QColor(Qt::darkYellow).darker() : QColor(Qt::yellow).lighter()); pal.setColor(QPalette::Base, rgbBase); // pal.setColor(QPalette::Text, Qt::black); } QAbstractSpinBox::setPalette(pal); if (QAbstractSpinBox::isVisible()) { QAbstractSpinBox::lineEdit()->setText(textFromValue(iValue)); QAbstractSpinBox::interpretText(); } if (bValueChanged) emit valueChanged(iValue); QAbstractSpinBox::lineEdit()->setCursorPosition(iCursorPos); } unsigned short qxgeditSpin::value (void) const { if (QAbstractSpinBox::isVisible()) { return valueFromText(QAbstractSpinBox::text()); } else { return (m_pParam ? m_pParam->value() : 0); } } // Specialty functors setters. void qxgeditSpin::setParam ( XGParam *pParam, XGParamObserver *pSender ) { m_pParam = pParam; QAbstractSpinBox::setPalette(QPalette()); if (m_pParam) setValue(m_pParam->value(), pSender); } XGParam *qxgeditSpin::param (void) const { return m_pParam; } // Inherited/override methods. QValidator::State qxgeditSpin::validate ( QString& sText, int& iPos ) const { #ifdef CONFIG_DEBUG_0 qDebug("qxgeditSpin[%p]::validate(\"%s\", %d)", this, sText.toUtf8().constData(), iPos); #endif if (iPos == 0) return QValidator::Acceptable; const QChar& ch = sText[iPos - 1]; if (ch == '.' || ch == '-' || ch.isDigit()) return QValidator::Acceptable; else return QValidator::Invalid; } void qxgeditSpin::fixup ( QString& sText ) const { #ifdef CONFIG_DEBUG_0 qDebug("qxgeditSpin[%p]::fixup(\"%s\")", this, sText.toUtf8().constData()); #endif sText = textFromValue(m_pParam ? m_pParam->value() : 0); } void qxgeditSpin::stepBy ( int iSteps ) { #ifdef CONFIG_DEBUG_0 qDebug("qxgeditSpin[%p]::stepBy(%d)", this, iSteps); #endif int iCursorPos = QAbstractSpinBox::lineEdit()->cursorPosition(); int iValue = int(value()) + iSteps; if (iValue < 0) iValue = 0; setValue(iValue); QAbstractSpinBox::lineEdit()->setCursorPosition(iCursorPos); } QAbstractSpinBox::StepEnabled qxgeditSpin::stepEnabled (void) const { StepEnabled flags = StepNone; unsigned short iValue = value(); if (m_pParam) { if (iValue < m_pParam->max() || m_pParam->min() >= m_pParam->max()) flags |= StepUpEnabled; if (iValue > m_pParam->min()) flags |= StepDownEnabled; } return flags; } // Value/text format converters. unsigned short qxgeditSpin::valueFromText ( const QString& sText ) const { if (m_pParam == nullptr) return sText.toUShort(); const QString& sSpecialValueText = specialValueText(); if (!sSpecialValueText.isEmpty() && sText == sSpecialValueText) return m_pParam->min(); float fValue = 0.0f; if (sText.indexOf('k') >= 0) fValue = QString(sText).remove('k').toFloat() * 1000.0f; else fValue = sText.toFloat(); return m_pParam->getu(fValue); } QString qxgeditSpin::textFromValue ( unsigned short iValue ) const { if (m_pParam == nullptr) return QString::number(iValue); const QString& sSpecialValueText = specialValueText(); if (!sSpecialValueText.isEmpty() && iValue == m_pParam->min()) return sSpecialValueText; float fValue = m_pParam->getv(iValue); if (fValue >= 1000.0f) { fValue /= 1000.0f; return QString::number(fValue) + 'k'; } else { return QString::number(fValue); } } // Pseudo-fixup slot. void qxgeditSpin::editingFinishedSlot (void) { #ifdef CONFIG_DEBUG_0 qDebug("qxgeditSpin[%p]::editingFinishedSlot()", this); #endif // Kind of final fixup. setValue(value()); } // Textual value change notification. void qxgeditSpin::valueChangedSlot ( const QString& sText ) { #ifdef CONFIG_DEBUG_0 qDebug("qxgeditSpin[%p]::valueChangedSlot(\"%s\")", this, sText.toUtf8().constData()); #endif // Forward this... emit valueChanged(sText); } // end of qxgeditSpin.cpp