├── .github └── FUNDING.yml ├── .gitignore ├── .gitmodules ├── 3rdparty └── CMakeLists.txt ├── CMakeLists.txt ├── LICENSE ├── MANIFEST.md ├── README.md ├── docs ├── README.md ├── applying.md ├── blades.md ├── com-ports.md ├── configfile.md ├── faq.md ├── firstsetup.md ├── general.md ├── linux-build.md ├── pconfs.md ├── presets.md └── props.md ├── init.sh ├── mingw-tc.cmake ├── resources ├── CMakeLists.txt ├── bin │ ├── Linux │ │ └── arduino-cli │ ├── Win32 │ │ ├── arduino-cli.exe │ │ ├── proffie-dfu-setup.exe │ │ └── windowMode.exe │ └── macOS │ │ └── arduino-cli ├── component-icons │ ├── led.png │ ├── led.svg │ ├── pixel.png │ ├── pixel.svg │ ├── proffieboardv1.png │ ├── proffieboardv1.svg │ ├── proffieboardv2.png │ ├── proffieboardv2.svg │ ├── proffieboardv3.png │ ├── proffieboardv3.svg │ ├── resistor.png │ ├── resistor.svg │ ├── rfid.png │ └── rfid.svg ├── i18n │ └── es │ │ ├── proffieconfig.mo │ │ └── proffieconfig.po ├── icons │ ├── blade.png │ ├── blade.svg │ ├── chip.png │ ├── chip.svg │ ├── edit.png │ ├── edit.svg │ ├── icon.icns │ ├── icon.ico │ ├── icon.png │ ├── icon.svg │ ├── import.png │ ├── import.svg │ ├── led.png │ ├── led.svg │ ├── new.png │ ├── new.svg │ ├── old │ │ ├── icon-small.xpm │ │ ├── icon.icns │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── icon.svg │ │ └── icon.xpm │ ├── presets.png │ ├── presets.svg │ ├── props.png │ ├── props.svg │ ├── reload.png │ ├── reload.svg │ ├── serial_monitor.png │ ├── serial_monitor.svg │ ├── settings.png │ ├── settings.svg │ ├── sound.png │ ├── sound.svg │ ├── wiring.png │ └── wiring.svg ├── props │ ├── BC.pconf │ ├── caiwyn.pconf │ ├── fett263.pconf │ ├── sa22c.pconf │ ├── sabersense.pconf │ └── shtok.pconf └── templates │ ├── proffieconfig.po │ └── resource.rc.in ├── screenshots ├── editor-bladearrays.png ├── editor-bladeawareness.png ├── editor-general.png ├── editor-presetsstyles.png ├── editor-propfile-fett263.png └── mainmenu.png └── src ├── CMakeLists.txt ├── Common.cmake ├── components ├── Component.cmake ├── app │ ├── CMakeLists.txt │ ├── app.cpp │ ├── app.h │ └── windowids.h ├── log │ ├── CMakeLists.txt │ ├── branch.cpp │ ├── branch.h │ ├── context.cpp │ ├── context.h │ ├── logger.cpp │ ├── logger.h │ ├── message.cpp │ ├── message.h │ └── severity.h ├── pconf │ ├── CMakeLists.txt │ ├── pconf.cpp │ └── pconf.h ├── ui │ ├── CMakeLists.txt │ ├── controls.cpp │ ├── controls.h │ ├── frame.cpp │ ├── frame.h │ ├── message.cpp │ ├── message.h │ ├── movable.cpp │ ├── movable.h │ ├── plaque.cpp │ └── plaque.h └── utils │ ├── CMakeLists.txt │ ├── clone.h │ ├── color.h │ ├── crypto.cpp │ ├── crypto.h │ ├── defer.h │ ├── image.cpp │ ├── image.h │ ├── paths.cpp │ ├── paths.h │ ├── position.h │ ├── theme.cpp │ ├── theme.h │ ├── trace.cpp │ ├── trace.h │ ├── types.h │ ├── undo.cpp │ └── undo.h ├── launcher ├── CMakeLists.txt ├── main.cpp ├── routines.cpp ├── routines.h └── update │ ├── changelog.cpp │ ├── changelog.h │ ├── install.cpp │ ├── install.h │ ├── pulldata.cpp │ ├── pulldata.h │ ├── update.cpp │ └── update.h ├── proffieconfig ├── CMakeLists.txt ├── core │ ├── appstate.cpp │ ├── appstate.h │ ├── config │ │ ├── configuration.cpp │ │ ├── configuration.h │ │ ├── propfile.cpp │ │ ├── propfile.h │ │ ├── settings.cpp │ │ └── settings.h │ ├── defines.h │ └── utilities │ │ ├── misc.cpp │ │ ├── misc.h │ │ ├── progress.cpp │ │ └── progress.h ├── editor │ ├── dialogs │ │ ├── bladearraydlg.cpp │ │ ├── bladearraydlg.h │ │ ├── customoptionsdlg.cpp │ │ └── customoptionsdlg.h │ ├── editorwindow.cpp │ ├── editorwindow.h │ └── pages │ │ ├── bladespage.cpp │ │ ├── bladespage.h │ │ ├── generalpage.cpp │ │ ├── generalpage.h │ │ ├── presetspage.cpp │ │ ├── presetspage.h │ │ ├── propspage.cpp │ │ └── propspage.h ├── main.cpp ├── mainmenu │ ├── dialogs │ │ ├── addconfig.cpp │ │ ├── addconfig.h │ │ ├── props.cpp │ │ └── props.h │ ├── mainmenu.cpp │ └── mainmenu.h ├── onboard │ ├── onboard.cpp │ ├── onboard.h │ └── pages │ │ ├── dependencypage.cpp │ │ ├── overviewpage.cpp │ │ └── welcomepage.cpp └── tools │ ├── arduino.cpp │ ├── arduino.h │ ├── serialmonitor.cpp │ └── serialmonitor.h └── upgen ├── CMakeLists.txt └── main.cpp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ryancog] 4 | 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build*/* 2 | *.o 3 | 4 | Makefile* 5 | !ProffieConfig.pro 6 | .* 7 | !.gitignore 8 | 9 | .DS_Store 10 | 11 | deploy/ 12 | staging/ 13 | /upgen 14 | 15 | # For CMake-generated shared lib export headers 16 | export.h 17 | 18 | CMakeLists.txt.user* 19 | CMakeCache.txt 20 | CMakeFiles 21 | CMakeScripts 22 | Testing 23 | 24 | cmake_install.cmake 25 | install_manifest.txt 26 | compile_commands.json 27 | CTestTestfile.cmake 28 | _deps 29 | CMakeUserPresets.json 30 | 31 | .DS_Store 32 | 33 | *.bak 34 | *.log 35 | 36 | playground/ 37 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "resources/StyleEditor"] 2 | path = resources/StyleEditor 3 | url = https://github.com/profezzorn/ProffieOS-StyleEditor 4 | branch = master 5 | [submodule "resources/ProffieOS"] 6 | path = resources/ProffieOS 7 | url = https://github.com/profezzorn/ProffieOS 8 | branch = v7.x 9 | 10 | [submodule "3rdparty/wxWidgets"] 11 | path = 3rdparty/wxWidgets 12 | url = https://github.com/wxWidgets/wxWidgets 13 | [submodule "3rdparty/tomcrypt"] 14 | path = 3rdparty/tomcrypt 15 | url = https://github.com/ryancog/libtomcrypt 16 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, The All-In-One Proffieboard Management Utility! 2 | 3 | cmake_minimum_required(VERSION 3.20) 4 | set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum OS X deployment version" FORCE) 5 | # set(CMAKE_OSX_ARCHITECTURES arm64;x86_64 CACHE) 6 | 7 | project(ProffieConfig VERSION 1.7.13) 8 | add_compile_definitions(BUILD_SYSTEM_VERSION=${VERSION}) 9 | 10 | if (NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL Linux OR CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)) 11 | # Rip Windows 12 | message(FATAL_ERROR "Building on this platform is not supported.") 13 | endif() 14 | 15 | if (CMAKE_SYSTEM_NAME STREQUAL Windows) 16 | message(NOTICE "Configuring as cross-compile for Windows.") 17 | else() 18 | message(NOTICE "Configuring as native build for ${CMAKE_HOST_SYSTEM_NAME}...") 19 | endif() 20 | 21 | set(CMAKE_CXX_STANDARD 20) 22 | set(CMAKE_CXX_STANDARD_REQUIRED true) 23 | 24 | if (NOT CMAKE_BUILD_TYPE) 25 | set(CMAKE_BUILD_TYPE Debug) 26 | endif() 27 | 28 | include_directories("${CMAKE_CURRENT_LIST_DIR}/components") 29 | 30 | # MinGW requires manual installation of plugin for LTO. 31 | # See: https://stackoverflow.com/a/32461766 32 | # This generally causes issues though... 33 | # set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) 34 | set(CMAKE_REPRODUCIBLE_BUILD ON) 35 | 36 | cmake_path(GET CMAKE_CURRENT_BINARY_DIR FILENAME BUILD_NAME) 37 | set(INSTALL_DIR ${CMAKE_CURRENT_LIST_DIR}/deploy/${BUILD_NAME}) 38 | 39 | if (CMAKE_BUILD_TYPE STREQUAL Release) 40 | if (CMAKE_SYSTEM_NAME STREQUAL Darwin) 41 | set(REL_COMP_FLAGS "") 42 | set(REL_LINK_FLAGS "") 43 | set(PLATFORM_SHORTNAME macOS) 44 | elseif (CMAKE_SYSTEM_NAME STREQUAL Linux) 45 | set(REL_COMP_FLAGS "-s -ffunction-sections -fdata-sections") 46 | set(REL_LINK_FLAGS "-Wl,--gc-sections -Wl,--strip-all -Wl,--as-needed") 47 | set(PLATFORM_SHORTNAME linux) 48 | elseif (CMAKE_SYSTEM_NAME STREQUAL Windows) 49 | set(REL_COMP_FLAGS "-s -ffunction-sections -fdata-sections") 50 | set(REL_LINK_FLAGS "-Wl,--gc-sections -Wl,--strip-all -Wl,--as-needed") 51 | set(PLATFORM_SHORTNAME win32) 52 | endif() 53 | if (CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL Windows) 54 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REL_COMP_FLAGS} -fno-record-gcc-switches") 55 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REL_COMP_FLAGS} -fno-record-gcc-switches") 56 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${REL_LINK_FLAGS} -Wl,--build-id=none -Wl,--no-insert-timestamp") 57 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${REL_LINK_FLAGS} -Wl,--build-id=none -Wl,--no-insert-timestamp") 58 | endif() 59 | 60 | set(INSTALL_ITEM_DIR ${CMAKE_CURRENT_LIST_DIR}/staging/${PLATFORM_SHORTNAME}) 61 | else() 62 | set(INSTALL_ITEM_DIR ${INSTALL_DIR}/items) 63 | endif() 64 | 65 | if (CMAKE_BUILD_TYPE STREQUAL Debug AND CMAKE_SYSTEM_NAME STREQUAL Windows) 66 | set(INSTALL_BIN_DIR ${INSTALL_ITEM_DIR}/bin) 67 | set(INSTALL_COMPONENTS_DIR ${INSTALL_BIN_DIR}) 68 | set(INSTALL_LIB_DIR ${INSTALL_BIN_DIR}) 69 | set(INSTALL_RESOURCE_DIR ${INSTALL_ITEM_DIR}/resources) 70 | else() 71 | set(INSTALL_BIN_DIR ${INSTALL_ITEM_DIR}/bin) 72 | set(INSTALL_COMPONENTS_DIR ${INSTALL_ITEM_DIR}/components) 73 | set(INSTALL_LIB_DIR ${INSTALL_ITEM_DIR}/lib) 74 | set(INSTALL_RESOURCE_DIR ${INSTALL_ITEM_DIR}/resources) 75 | endif() 76 | 77 | if (CMAKE_BUILD_TYPE STREQUAL Debug) 78 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 79 | message("Binary Dir: ${CMAKE_BINARY_DIR}") 80 | install(FILES ${CMAKE_BINARY_DIR}/compile_commands.json DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) 81 | add_compile_definitions(APP_DEPLOY_PATH="${INSTALL_ITEM_DIR}") 82 | if (NOT CMAKE_SYSTEM_NAME STREQUAL Windows) 83 | add_compile_options(-fsanitize=address) 84 | add_link_options(-fsanitize=address) 85 | endif() 86 | endif() 87 | 88 | add_subdirectory(3rdparty) 89 | add_subdirectory(resources) 90 | add_subdirectory(src) 91 | # add_subdirectory(tests EXCLUDE_FROM_ALL) 92 | 93 | -------------------------------------------------------------------------------- /MANIFEST.md: -------------------------------------------------------------------------------- 1 | # Manifest Formatting 2 | 3 | The manifest is a pconf file, with the following sections 4 | 5 | MESSAGE includes relevant version label (launcher version) w/ <=> 6 | - May contain "FATAL" marker to indicate the launcher can no longer be used for updating. 7 | - CONTENT includes message to display 8 | 9 | Every included individual item is listed: 10 | - EXEC: Executable Binary 11 | - LIB: Base Library 12 | - COMP: Component Library 13 | - RSRC: Resource File 14 | 15 | Each individual item specifies path relative to base for respective item type. 16 | - PATH_macOS, PATH_Linux, and PATH_Win32 17 | - HIDDEN may be flagged to hide the item in changelog 18 | Versions are listed with hash (HASH_macOS, HASH_Linux, and HASH_Win32) for each platform. 19 | Each version may also contain: 20 | - FIX: entries w/ bugfixes 21 | - CHANGE: entries w/ behavior changes/updates 22 | - FEAT: entries w/ new features added 23 | 24 | BUNDLE lists all files which make up a complete version bundle 25 | - Files listed in the form: TYPE("NAME"): "VERSION" 26 | - NOTE entry may be added for general release messages 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ProffieConfig 2 | 3 | 4 | 5 | All-In-One ProffieBoard Management Utility. 6 | 7 | Incorporates extensive configuration generation, compiling and applying changes to the ProffieBoard, the Serial Monitor, handles driver installation, and some sanity checks for good measure; All without the Arduino IDE. 8 | 9 | Using this tool, there is no need for dealing with the Arduino IDE, Zadig, etc. in an attempt to make using a Proffieboard as beginner-friendly as possible, while still retaining as much of the powerful customization which makes Proffie so popular. 10 | 11 | ## Getting Started 12 | 13 | Head over to the [latest ProffieConfig release](https://github.com/ryancog/ProffieConfig/releases/latest), grab either the macOS or Windows (Win32) version, and run it! 14 | 15 | ProffieConfig will complete its installation and guide you through the setup and all of its features, so whether you're a first-time proffieboard user or have been around the block a few times, you'll be ready before you know it! 16 | 17 | ***NOTE:** ProffieConfig is relatively new software, and because I do not pay for an Apple Developer License or Microsoft Developer account I cannot "sign" the application, chances are something will tell you the program is unknown or "dangerous." See the info below about how you can address this if it comes up:* 18 | - ***macOS:** Please visit this Apple Support page to read about macOS' security and how to launch unsigned apps [here](https://support.apple.com/en-us/102445)* 19 | - ***Windows:** A SmartScreen dialog may pop up warning about the program origins, clicking "More Info..." and then "Run Anyways" should allow you to open the app.* 20 | 21 | *The Chrome browser (and Chromium-based browsers) may block the program, which requires you to visit the "Show All Downloads" page to "keep" the file.* 22 | 23 | 24 | ## To-Do (Non-Exhaustive) 25 | - Expand pre-checker capabilities (ongoing) 26 | - Implement interface for `using` syntax (not just the ability to parse) 27 | - Add blade nicknames 28 | - Update power pin selection to new list style for blade awareness 29 | - Add support for `DimBlade()` 30 | - Add progress percentage while applying 31 | - Add config percentage of usage 32 | - Add warnings for soft config fails. 33 | - Take over the world ;) 34 | 35 | ## Additional Info 36 | 37 | - [COM ports >= 10 causing issues?](docs/com-ports.md) 38 | - [Creating/Editing ProffieConfig's `pconf` files](docs/pconfs.md) 39 | - [Building ProffieConfig for Linux](docs/linux-build.md) 40 | 41 | ## Gallery 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # ProffieConfig Documenation 2 | 3 | Welcome to the ProffieConfig documenation files! Below you'll find several sections related to using the app. 4 | 5 | - [First-Time Setup](/docs/firstsetup.md) 6 | - [General Page](/docs/general.md) 7 | - [Prop File Page](/docs/props.md) 8 | - [Blades Page](/docs/blades.md) 9 | - [Presets Page](/docs/presets.md) 10 | - [Applying Config](/docs/applying.md) 11 | 12 | ## [FAQ](/docs/faq.md) 13 | - [What is a Config File?](/docs/faq.md#what-is-a-config-file) 14 | - [Where do I get blade styles?](/docs/faq.md#where-do-i-get-blade-styles) 15 | - [What if my board doesn't show up?](/docs/faq.md#what-if-my-board-doesnt-show-up) 16 | -------------------------------------------------------------------------------- /docs/applying.md: -------------------------------------------------------------------------------- 1 | # Applying Config to Proffieboard 2 | 3 | First, be sure you've completed the [first-time setup](/docs/firstsetup.md), then proceed with the instructions below. 4 | 5 | - Plug your proffieboard into your computer, and then press "Refresh..." 6 | - Select the port your board is connected to from the "Select Device..." drop down. If you only have one proffieboard plugged in, this will likely be the only option listed. 7 | - Ensure you've selected the correct board version in "General" as the one you have plugged in. 8 | - Click "Apply to Board..." and wait for the changes to be made. This process can take a while, don't panic if it appears to be stuck for around a minute, give it some time to complete. 9 | 10 | If your board isn't showing up, and/or if you accidentally disconnected it during the application process, review ["What if my board doesn't show up?"](/docs/faq.md#what-if-my-board-doesnt-show-up) 11 | 12 | ## That's It! 13 | 14 | Still have questions? Check out the [FAQ](/docs/faq.md). 15 | -------------------------------------------------------------------------------- /docs/blades.md: -------------------------------------------------------------------------------- 1 | # Blades Page 2 | 3 | This is where any blade or LED on your saber will be configured, including any accent LEDs. 4 | 5 | # Blades 6 | 7 | This is a list of all blades currently set up for your saber, regardless of type. There must be at least one blade at all times. 8 | 9 | Clicking "+" will add a new blade, clicking "-" will remove the currently-selected blade. 10 | 11 | # SubBlades 12 | 13 | This is a list, in the case of WS281X blades, where any created subblades will be displayed for configuration. If there are any, there must be at least two (otherwise there's no point). 14 | 15 | SubBlades can only be used with WS281X blades due to their nature. 16 | 17 | Clicking "+" will add a new subblade, clicking "-" will remove the currently-selected subblade. If there are only two subblades, "-" will remove both, but this will not remove the parent blade or its configuration. 18 | 19 | # Blade Type 20 | 21 | The drop-down selects a blade's type, which can be one of the following: 22 | 23 | - **"WS281X (RGB)"**: This will be used for most WS281X blades (which use Red, Green, and Blue channels), if your blade has LEDs going up along the inside of the blade, chances are you should choose this type; it supports the follow options. 24 | - "Color Order": Most of the time this will be "GRB," only change this if you know your color order is different (rare). 25 | - "Blade Data Pin": Which pin your blade is connected to on the Proffieboard, uses the names found on [the pin table](https://fredrik.hubbe.net/lightsaber/v6/), if you're using a pin not in the dropdown (e.g. one of the Free pins on the V3), you can type in your own pin to use in this box. 26 | - "Number of Pixels": The number of LEDs in your blade (if using subblades, this is the total number of LEDs for the whole blade, not for one subblade or another) 27 | - **"WS281X (RGBW)"**: On certain WS281X blades, there is an additional white LED which allows for purer white color. If you have a blade which supports this, choose this type; it supports the options of "WS281X (RGB)" with the following differences: 28 | - "Color Order": Has an additional "W" placed in the order to represent that channel. Most of the time this will be "GRBW," only change this if you know your color is different. 29 | - "Use RGB with White": If this is enabled, whenever "White" is displayed on the blade, the White channel **and** the RGB channels will be turned on. This can make the blade brighter, but at the cost of battery life and a "pure" white color. 30 | - **"Tri-LED Star"**: If you have a "baselit" type saber, chances are this is what you'll want. *Power Pins are assigned in order of LED* 31 | - "LED *x* Color": For each LED on your Star, choose a color. 32 | - "Resistance": For each LED on your star, enter in the Ohm value used on the LED. This isn't critical, but will help account for differences in brightness when color mixing. 33 | - **"Quad-LED Star"**: If you have a baselit saber with white (or another color) you probably have a quad-star. The options remain the same, simply with a forth LED to set up. 34 | - **"Single Color"**: If you have a normal type LED (single diode) or something similar, you can use the MOSFETs to control it with a Single Color option. (PWM direct-driven LED config is planned) 35 | 36 | **A note on SubBlades:** The numbering is somewhat unintuitive. Numbering for subblades starts at 0. If I have a strip of 10 leds which I want to split into two subblades of 5, I would set the first subblade to start at 0 and end at 4, then for the second one to start at 5 and end at 9 (Even though the blade is 10 LEDs long, your subblade should stop at a number 1 less). This may be changed in the future... 37 | 38 | ## Power Pins 39 | 40 | Each blade you setup should have Power Pins selected, though the selection process varies by blade type. This should follow the pins you've soldered to, but here's a quick reference, and a quick explanation. 41 | 42 | For WS281X blades, most of the time you should have at least two pads for full-length blades. Small accent strips can use just one. If you have seperate WS281X blades (Subblades by their nature share power pins) they can share pins (assuming they physically use the same pads), but this comes at the cost of having all the LEDs the pins are connected to turned on, even if they're not being used. With WS281X blades, the power draw while off is non-negligible, so while you might want to share power pins for maybe quillions on a crossguard, it is ill-advised to have an accent share power pins with a blade, as that means the blade would be kept on for as long as the accent is, likely greatly increasing power draw. 43 | 44 | For In-Hilt LED blades and Single Color blades, the number of power pins should equal the number of LEDs you're configuring. The power pins are configured in LED order, and while you can select more than the number of LEDs you're setting up, only the first will apply. For example, if I'm setting up a Tri-LED Star, and I select pins 2, 3, 4, and 5, LED 1 will use Power Pin 2, LED 2 will use Pin 3, LED 3 will use Pin 4, and 5 will not be used, despite being selected. Similarly, if I have a Single-Color LED, only the first numerical Pin will be used, so if I had 3,4, and 5 selected, only 3 would be used. 45 | 46 | ## That's It! 47 | 48 | Next Up: [Preset Page](/docs/presets.md). 49 | -------------------------------------------------------------------------------- /docs/com-ports.md: -------------------------------------------------------------------------------- 1 | # Com Ports >= 10 Fail to Upload normally (Require Bootloader Mode) 2 | 3 | This issue should be fixed as of v1.7.11. If you encounter it, **please let me know!** 4 | --- 5 | 6 | @TheTomas from the r/lightsabers Discord has discovered a wonderfully annoying little issue. I've not yet fully investigated, but it seems to be either a glaring oversight somewhere in my code (EDIT: it was an oversight in my knowledge of Win32) ~~(possible, but I don't think so)~~, or something really stupid in the Windows API (EDIT: Arguably, this is also true). You're not here to hear me rant though, so I digress. 7 | 8 | If your proffieboard ends up using a `COM` port >= 10 (e.g. `COM10`, `COM11`, etc.), then it seems (on some computers at least), a normal upload will not work, and you'll get the error "Could not connect to proffieboard for upload." 9 | 10 | There are two workarounds: 11 | - Manually enter bootloader mode 12 | - Change com port number 13 | 14 | The former is the easier. Simply reboot the board into bootloader mode (You can do this via holding the `BOOT` button then pressing `RESET`, or by typing `RebootDFU` into the Serial Monitor), and then uploading using the `BOOTLOADER RECOVERY` option. 15 | 16 | Alternatively, and credit for this goes to @TheTomas, you can find the proffieboard in your Device Manager underneath the "COM & LPT Ports" section. There you should find an option for "Port Settings," then "Advanced," and from there you should be able to choose a new port number, with those in use (and thus the ones to avoid) being marked as such. 17 | 18 | ![image](https://github.com/user-attachments/assets/853084e1-a1e7-4ac5-926d-8d1dfa0711da) 19 | -------------------------------------------------------------------------------- /docs/configfile.md: -------------------------------------------------------------------------------- 1 | # The Config File 2 | 3 | With ProffieConfig, you shouldn't need to deal with ProffieOS config files for the large majority of operation, but there may be some cases in which doing so is necessary. 4 | 5 | ProffieConfig allows you to import, export, and verify configuration files. 6 | 7 | ## Import 8 | 9 | Although a dialog is presented on first run, it may be desired to import a new/different config file instead. To do this, go to File->Import Config... and select the file to import. Provided the config file uses supported features, it will be sucessfully imported. 10 | 11 | ***NOTE: Importing a config file with PERMENANTLY ERASE the current open configuration and setings in ProffieConfig. If you want to save your current configuration file, be sure to export it before importing a new one!*** 12 | 13 | ## Export 14 | 15 | File->Export Config... will export the generated ProffieOS config file created by ProffieConfig, which can be used if you're ready to delve into advanced customization, or if it's requested for debugging. 16 | 17 | This file can be exported anywhere, doing so has no effect on the configuration in ProffieConfig, which will remain loaded/saved. 18 | 19 | ## Verify 20 | 21 | Sometimes it may be desirable to test and ensure there is nothing conflicting or erroneous in a config while working on it, but you may not want to have to plug in the board and try applying the configuration just to test. In this case, running "Verify Config..." will run the same steps as there would be when applying changes, but it can be done without a board conneted, and if it is, it will not apply the changes yet. 22 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # ProffieConfig FAQ 2 | 3 | ## What is a config file? 4 | 5 | The ProffieOS config file is what holds all the information about your saber setup. It contains (mostly) all the settings you configure within ProffieConfig, and then some. 6 | 7 | The code for your styles, the layout/setup of your blades, the the options you choose for things like volume, the prop options, etc. all get stored in the config file, which is then read when the ProffieOS code is compiled (fancy computer term for "turned into a program," in this case, for the Proffieboard to run). 8 | 9 | ## Where do I get blade styles? 10 | 11 | - If you have an existing config, try importing it into ProffieConfig! That's the easiest way to import all your settings, including the blade styles. 12 | - Some sound fonts you buy may have a blade style included with them, see if yours does. 13 | - For some very cool, premade, but highly customizable bladestyles, check out [Fett263's Style Library](https://fett263.com/fett263-proffieOS7-style-library.html). 14 | - For advanced use, the [ProffieOS Style Editor](https://profezzorn.github.io/ProffieOS-StyleEditor/style_editor.html) offers unparalleled customization, but has a very steep learning curve and requires quite a bit of effort to get going. 15 | 16 | ## What if my board doesn't show up? 17 | 18 | If your Proffieboard isn't showing up in the device drop down, please make sure you've run the [first-time setup](/docs/firstsetup.md). 19 | 20 | If the Proffieboard is unresponsive or it was accidentally unplugged during configuration application, locate the [boot and reset buttons](https://fredrik.hubbe.net/lightsaber/v6/pinout.svg) on the Proffieboard. Now, with the board plugged into your computer, hold BOOT, push on RESET, release BOOT, and try refreshing again. You should see an entry labeled "BOOTLOADER" and will be able to reapply your config and be back off to the races! 21 | 22 | If it's still not showing up, try a different USB cable. Sometimes they *do* go bad, but it's also very common to have a USB cable which only provides power, and is not intended/will not work for connecting devices. 23 | 24 | ## Still Need Help? 25 | 26 | [Open an issue](https://github.com/ryryog25/ProffieConfig/issues/new) to get support. 27 | -------------------------------------------------------------------------------- /docs/firstsetup.md: -------------------------------------------------------------------------------- 1 | # First-Time Setup 2 | 3 | When you [download ProffieConfig](https://github.com/ryryog25/ProffieConfig/releases/latest), there's a few steps you'll need to complete to get up and running. 4 | 5 | If you're on macOS, you'll get an app which you can move to wherever is convenient. 6 | If you're on Windows, you can move the folder to any location, however the folder must stay together (`ProffieConfig.exe` must stay beside `resources` folder) 7 | 8 | ## Config File 9 | Open up the application. When you run it for the first time you'll get a pop-up asking if you'd like to import an existing configuration file. 10 | 11 | If you bought your saber from someone who included a config file on the SD card, you have a config file from another saber, or if you have one you have created previously, go ahead and import that file (`File->Import Config...`), and ProffieConfig will automatically update accordingly. From here on out, you won't need that file anymore, the information is handled seperatetly within ProffieConfig, just be sure to hit save. ;) 12 | 13 | If you don't have a config file, you can decline and an empty configuration will be loaded. 14 | 15 | ## Install Dependencies 16 | 17 | Once you're at the main ProffieConfig window, select `File->Install Dependencies...` to automatically install any drivers or other software needed for ProffieConfig to function. This step can take a while depending on your internet connection since certain components will need to be downloaded. 18 | Once you're done, you won't have to do this again, and ProffieConfig will be ready to work. 19 | 20 | ## Done! 21 | 22 | Continue reading to learn about how to use ProffieConfig! 23 | 24 | Next Up: [General Page](/docs/general.md) 25 | -------------------------------------------------------------------------------- /docs/general.md: -------------------------------------------------------------------------------- 1 | # General Page 2 | 3 | The General Page is the first page you'll be greeted by when you open the ProffieConfig editor, and it's where several important settings live. 4 | 5 | ## Board Setup 6 | 7 | Here, select the version of Proffieboard you have from the dropdown. This can easily be changed, but it has to match the board you choose to apply the configuration to later. 8 | 9 | There's two other options here: "Enable Mass Storage" and "Enable WebUSB" 10 | 11 | **"Enable Mass Storage"** allows you to access the contents of your SD card (to add/remove/change files) when plugging in your Proffieboard with a USB cable, instead of needing to remove the SD card from the board, and plug it directly into your computer. 12 | 13 | **"Enable WebUSB"** enables a feature where, if your board is connected via USB to your computer, you can access the [ProffieOS Workbench](https://pod.hubbe.net/tools/workbench.html). 14 | 15 | ## Options 16 | 17 | - **"Number of Buttons"**: The number of buttons connected to your saber. This assumes you've connected your buttons to the respective Button1, Button2, and/or Button3 pads. 18 | - **"Max Volume"**: This setting is an arbitrary value for setting the maximum volume of your saber (you can raise and lower the volume up to this value while using the saber). Generally, 2000 is a good value for most speakers, though it may be possible to increase this value for certain speakers. Caution should be used when increasing the volume, as too high of a volume may damage your speaker. Lower volumes can be set based on preference. 19 | - **"Clash Threshold"**: This sets the intensity of impact that must be experienced by the saber to trigger a clash effect. The value is measured in Gs, and can be modified to user preference. 20 | - **"PLI Timeout"**: This sets the amount of time a PLI will remain active on the saber after the last interaction, assuming one is connected, measured in minutes. 21 | - **"Idle Timeout"**: This sets the amount of time any accent LEDs and OLED animations will remain active on the saber after the last interaction, measured in minutes. 22 | - **"Motion Timeout"**: This sets the amount of time before guesture controls are disabled after the last interaction, measured in minutes. 23 | 24 | - **"Save Volume"**: After disconnecting power, choose whether to save the volume the saber was set to or not. 25 | - **"Save Preset"**: After disconnecting power, choose whether to save the last preset the saber was set to or not. 26 | - **"Save Color"**: Choose whether to save color changes after switching preset or not. 27 | - **"Disable Color Change"**: Disable color change functionality. 28 | - **"Disable Talkie"**: Removes the "Talkie" spoken prompts and error messages and replaces them with [beeps](https://pod.hubbe.net/troubleshooting/beep_codes.html). Can be used to save FLASH memory if prompted. 29 | - **"Disable Basic Parser Styles"**: Removes the option to use "Basic Parser Styles" in the ProffieOS Workbench, can be used to save FLASH memory if promted. 30 | - **"Disable Diagnostic Commands"**: Removes certain commands used with the Arduino Serial Monitor, recommended unless commands are needed, can be used to save FLASH memory if prompted. 31 | - **"Enable Developer Commands"**: Enables special commands used for Proffieboard development, this probably shouldn't be enabled. Should be disabled to save FLASH memory. 32 | - **"WS281X Max LEDs"**: This sets the maximum size of a WS281X blade to be configured in the "Blades" page. Unless you have a blade longer than this, it should not be changed. 33 | 34 | ## That's All! 35 | 36 | Next Up: [Prop Page](/docs/props.md) 37 | -------------------------------------------------------------------------------- /docs/linux-build.md: -------------------------------------------------------------------------------- 1 | # Building ProffieConfig on Linux (for Linux) 2 | 3 | This process was written and tested on Debian 12 (Thanks chemicalivory!), but the same process is used for development on openSUSE Tumbleweed, and should be directly transferrable to other linux distributions, or transferrable with minimal tweaking. 4 | 5 | ## Building wxWidgets 6 | 7 | In order to build ProffieConfig, you must first build and install the library ProffieConfig is built on, wxWidgets. **wxWidgets must be built custom from source!** Distribution packages **WILL NOT** work, either because they've a wrong version, are compiled with different flags, or simply don't support the features ProffieConfig uses. 8 | 9 | Luckily this process is pretty straightforward: 10 | 11 | 1. Clone/Download wxWidgets source code: 12 | ``` 13 | git clone --recursive https://github.com/wxWidgets/wxWidgets.git 14 | ``` 15 | 1. Switch Directory to the newly-downloaded folder: 16 | ``` 17 | cd wxWidgets/ 18 | ``` 19 | 1. Ensure wxWidgets submodules are initialized and updated (this shouldn't be required with `--recursive`, but is here for good measure): 20 | ``` 21 | git submodule init 22 | git submodule update --init 23 | ``` 24 | 1. Create a new build directory and switch to it: 25 | ``` 26 | mkdir gtk-build 27 | cd gtk-build 28 | ``` 29 | 1. Run wxWidgets configuration script: 30 | ``` 31 | ../configure --enable-stl --disable-shared 32 | ``` 33 | 1. Build wxWidgets (Set number of CPU cores you have): 34 | ``` 35 | make -j [NUMBER OF CORES] 36 | ``` 37 | 1. Install wxWidgets to system directories for use compiling ProffieConfig: 38 | ``` 39 | sudo make install 40 | ``` 41 | 42 | (NOTE: `--disable-shared` is recommended for distribution, so it is included here. If `--disable-shared` is not used, the command `sudo ldconfig` must be run after `sudo make install` to update the dynamic linker, and your ProffieConfig build will only work on your machine.) 43 | 44 | ## Building ProffieConfig: 45 | 46 | 1. Clone/Download ProffieConfig source code: 47 | ``` 48 | git clone --recursive https://github.com/ryryog25/ProffieConfig 49 | ``` 50 | 1. Switch to ProffieConfig directory, create build directory, then switch to it: 51 | ``` 52 | cd ProffieConfig 53 | mkdir build && cd build 54 | ``` 55 | 1. Run `qmake` to configure the ProffieConfig build: 56 | (You'll need to install `qmake` first, easiest is via your distribution package manager) 57 | ``` 58 | qmake6 -o Makefile ../src/ProffieConfig.pro 59 | ``` 60 | 1. Build ProffieConfig (Set number of CPU cores you have): 61 | ``` 62 | make -j [NUMBER OF CORES] 63 | ``` 64 | 1. Copy ProffieConfig resources: 65 | ``` 66 | cp -r ../resources/linux/arduino-cli resources/ 67 | cp -r ../resources/ProffieOS resources/ 68 | cp -r ../resources/props resources/ 69 | cp -r ../resources/StyleEditor resources/ 70 | ``` 71 | 72 | Now at this point you should have a `ProffieConfig` binary executable alongside its `resources` folder (and probably a lot of other compile artifacts ending with `.o`), and you can run ProffieConfig! 73 | -------------------------------------------------------------------------------- /docs/presets.md: -------------------------------------------------------------------------------- 1 | ## Presets Page 2 | 3 | Here you'll setup all the *things* that happen when you turn on your saber: what sounds it plays, what effects occur on your blades, etc. 4 | Through this section you can add new fonts and bladestyles to your saber. Click the "+" button to add another preset entry, in which you can specify a new font/bladstyle pair. 5 | 6 | ## Preset Name 7 | 8 | This entry has two purposes: 9 | A) To serve as a name simply for organizational/recall purposes, and 10 | B) To choose what text to display on an OLED, provided no custom bitmaps are shown. 11 | 12 | Any name can be used, but it cannot contain spaces. If you're setting up a name for an OLED, it's best practice to use lowercase, and if you want to put text on a new line, insert "\n" as if it were a space or enter key. 13 | 14 | ## Font Directory 15 | 16 | This is the directory where the soundfont files will be found to play. 17 | 18 | This is a location of a folder on your saber SD card, and if you have a soundfont folder inside another folder, you'll have to indicate that by doing something like `FolderName/FontFolderName`. 19 | 20 | You can specify multiple folders to pull sound files from here. For example, if you had a "common" folder which holds things like menu effect files or similar, you could specify it by doing something like `FontFolderName;common`. The `;` seperates folders, and you can have multiple. 21 | 22 | What you enter into this field should exactly match the Font Folder name, and the folder names cannot contain spaces. For example, if you have a font folder named "My Cool Font," you'd need to change the folder name to something like "My-Cool-Font," and then enter in exactly that in ProffieConfig. If you had such a folder and you entered in "my-cool-font" it would not work. This is case-sensitive. 23 | 24 | ## Track File 25 | 26 | This can point to any audio file on the SD card. Whether you keep your tracks in a "track" folder, or if they're inside your font folder, they have to be referenced from the start of the SD card folders, it's not relative to the soundfont folder they may be in. Similarly, this field cannot contain spaces, and will always end in ".wav," (unless the field is left blank, which is valid) which is the file extension for the audio files. 27 | 28 | ## List 29 | 30 | The list in the center of the page allows you to navigate between presets, select which blade you're editing the style for, and add and remove presets. Presets will be added automatically if you type into the name, directory, or track fields and there's no preset selected. Pressing "+" will add a preset. Pressing "-" will remove the preset currently selected, if there is one. 31 | 32 | ## Blade Style Editor 33 | 34 | The box on the right of the page is where you'll input the bladestyle for the specific blade for the specific preset you have selected. This bladestyle is the code which creates the effect to be displayed on your blade (See ["Where do I get blade styles?"](/docs/faq.md#where-do-i-get-blade-styles)) and depending on the style they may be dependent on a particular Prop file or feature. 35 | 36 | This field auto-populates with `StyleNormalPtr, BLUE, 300, 800>()` which is a basic example of a bladestyle, with a simple in, out, and audioflicker, essentially doing the bare minimum, and should be replaced with your own. 37 | 38 | ## That's It! 39 | Next Up: [Applying Config](/docs/applying.md). 40 | -------------------------------------------------------------------------------- /docs/props.md: -------------------------------------------------------------------------------- 1 | # Prop File 2 | 3 | This page contains prop-specific options related to the way your saber works. 4 | 5 | ## Prop Dropdown 6 | 7 | Here you can choose the prop file to use for your saber. Generally, the biggest difference between prop files is the button layout, though some props offer certain features others don't. In the dropdown, select a prop file (Each of them are the names/aliases of the authors of the prop file), and try one out! 8 | 9 | ## Prop Options/Buttons 10 | 11 | Prop options are generally straightforward, but they can be complex to understand, especially with the wide array of potential choices. For a detailed listing of the capabilites and button mappings for each prop file, check out their respective pages, or better yet, click on "Buttons..." inside ProffieConfig. 12 | 13 | - [Default](https://github.com/profezzorn/ProffieOS/blob/master/props/saber.h) 14 | - [SA22C](https://github.com/profezzorn/ProffieOS/blob/master/props/saber_sa22c_buttons.h) 15 | - [Fett263](https://github.com/profezzorn/ProffieOS/blob/master/props/saber_fett263_buttons.h) 16 | - [BC](https://github.com/profezzorn/ProffieOS/blob/master/props/saber_BC_buttons.h) 17 | - [Caiwyn](https://github.com/profezzorn/ProffieOS/blob/master/props/saber_caiwyn_buttons.h) 18 | - [Shtok](https://github.com/profezzorn/ProffieOS/blob/master/props/saber_shtok_buttons.h) 19 | 20 | ## That's it! 21 | 22 | Next Up: [Blades Page](/docs/blades.md) 23 | -------------------------------------------------------------------------------- /mingw-tc.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Windows) 2 | 3 | # The cstd lib stuff had *issues* linking shared and I don't feel like troubleshooting them. 4 | # They are non-trivial in size so building shared and adding them as DLLs would be better, maybe look at this later 5 | # set(CMAKE_FIND_ROOT_PATH /opt/mxe/usr/x86_64-w64-mingw32.shared) 6 | # set(CMAKE_C_COMPILER /opt/mxe/usr/bin/x86_64-w64-mingw32.shared-gcc) 7 | # set(CMAKE_CXX_COMPILER /opt/mxe/usr/bin/x86_64-w64-mingw32.shared-g++) 8 | set(CMAKE_FIND_ROOT_PATH /opt/mxe/usr/x86_64-w64-mingw32.static) 9 | set(CMAKE_C_COMPILER /opt/mxe/usr/bin/x86_64-w64-mingw32.static-gcc) 10 | set(CMAKE_CXX_COMPILER /opt/mxe/usr/bin/x86_64-w64-mingw32.static-g++) 11 | 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 13 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 14 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 15 | 16 | -------------------------------------------------------------------------------- /resources/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # resources/CMakeLists.txt 4 | 5 | install(FILES 6 | # icons/blade.png 7 | # icons/chip.png 8 | # icons/edit.png 9 | icons/icon.png 10 | # icons/import.png 11 | # icons/led.png 12 | # icons/new.png 13 | # icons/reload.png 14 | # icons/serial_monitor.png 15 | # icons/sound.png 16 | # icons/settings.png 17 | # icons/wiring.png 18 | # icons/presets.png 19 | # icons/props.png 20 | 21 | DESTINATION ${INSTALL_RESOURCE_DIR}/icons 22 | ) 23 | 24 | install(FILES 25 | props/BC.pconf 26 | props/caiwyn.pconf 27 | props/fett263.pconf 28 | props/sa22c.pconf 29 | props/shtok.pconf 30 | 31 | DESTINATION ${INSTALL_RESOURCE_DIR}/props 32 | ) 33 | 34 | if (CMAKE_SYSTEM_NAME STREQUAL Darwin) 35 | install(PROGRAMS bin/macOS/arduino-cli DESTINATION ${INSTALL_BIN_DIR}) 36 | elseif (CMAKE_SYSTEM_NAME STREQUAL Linux) 37 | install(PROGRAMS bin/Linux/arduino-cli DESTINATION ${INSTALL_BIN_DIR}) 38 | elseif (CMAKE_SYSTEM_NAME STREQUAL Windows) 39 | install(PROGRAMS 40 | bin/Win32/arduino-cli.exe 41 | bin/Win32/proffie-dfu-setup.exe 42 | bin/Win32/windowMode.exe 43 | 44 | DESTINATION ${INSTALL_BIN_DIR} 45 | ) 46 | endif() 47 | 48 | # install(FILES 49 | # component-icons/proffieboardv1.png 50 | # component-icons/proffieboardv2.png 51 | # component-icons/proffieboardv3.png 52 | # component-icons/pixel.png 53 | # component-icons/led.png 54 | # component-icons/resistor.png 55 | # component-icons/rfid.png 56 | # 57 | # DESTINATION ${INSTALL_RESOURCE_DIR}/components 58 | # ) 59 | 60 | -------------------------------------------------------------------------------- /resources/bin/Linux/arduino-cli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/bin/Linux/arduino-cli -------------------------------------------------------------------------------- /resources/bin/Win32/arduino-cli.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/bin/Win32/arduino-cli.exe -------------------------------------------------------------------------------- /resources/bin/Win32/proffie-dfu-setup.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/bin/Win32/proffie-dfu-setup.exe -------------------------------------------------------------------------------- /resources/bin/Win32/windowMode.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/bin/Win32/windowMode.exe -------------------------------------------------------------------------------- /resources/bin/macOS/arduino-cli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/bin/macOS/arduino-cli -------------------------------------------------------------------------------- /resources/component-icons/led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/led.png -------------------------------------------------------------------------------- /resources/component-icons/pixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/pixel.png -------------------------------------------------------------------------------- /resources/component-icons/proffieboardv1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/proffieboardv1.png -------------------------------------------------------------------------------- /resources/component-icons/proffieboardv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/proffieboardv2.png -------------------------------------------------------------------------------- /resources/component-icons/proffieboardv3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/proffieboardv3.png -------------------------------------------------------------------------------- /resources/component-icons/resistor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/resistor.png -------------------------------------------------------------------------------- /resources/component-icons/rfid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/component-icons/rfid.png -------------------------------------------------------------------------------- /resources/i18n/es/proffieconfig.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/i18n/es/proffieconfig.mo -------------------------------------------------------------------------------- /resources/icons/blade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/blade.png -------------------------------------------------------------------------------- /resources/icons/blade.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 39 | 41 | 45 | 50 | 55 | 62 | 69 | 74 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /resources/icons/chip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/chip.png -------------------------------------------------------------------------------- /resources/icons/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/edit.png -------------------------------------------------------------------------------- /resources/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/icon.icns -------------------------------------------------------------------------------- /resources/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/icon.ico -------------------------------------------------------------------------------- /resources/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/icon.png -------------------------------------------------------------------------------- /resources/icons/import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/import.png -------------------------------------------------------------------------------- /resources/icons/led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/led.png -------------------------------------------------------------------------------- /resources/icons/led.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 39 | 41 | 45 | 50 | 55 | 60 | 64 | 68 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /resources/icons/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/new.png -------------------------------------------------------------------------------- /resources/icons/new.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 39 | 41 | 51 | 67 | 83 | 84 | 88 | 99 | 104 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /resources/icons/old/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/old/icon.icns -------------------------------------------------------------------------------- /resources/icons/old/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/old/icon.ico -------------------------------------------------------------------------------- /resources/icons/old/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/old/icon.png -------------------------------------------------------------------------------- /resources/icons/presets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/presets.png -------------------------------------------------------------------------------- /resources/icons/props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/props.png -------------------------------------------------------------------------------- /resources/icons/reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/reload.png -------------------------------------------------------------------------------- /resources/icons/reload.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 39 | 41 | 55 | 59 | 60 | 61 | 65 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /resources/icons/serial_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/serial_monitor.png -------------------------------------------------------------------------------- /resources/icons/serial_monitor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 39 | 41 | 45 | 54 | 59 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /resources/icons/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/settings.png -------------------------------------------------------------------------------- /resources/icons/sound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/sound.png -------------------------------------------------------------------------------- /resources/icons/sound.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 39 | 41 | 45 | 49 | 54 | 59 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /resources/icons/wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/resources/icons/wiring.png -------------------------------------------------------------------------------- /resources/props/shtok.pconf: -------------------------------------------------------------------------------- 1 | NAME: "Shtok" 2 | FILENAME: "saber_shtok_buttons.h" 3 | INFO: { 4 | "CUSTOM SOUNDS SUPPORTED (add to font to enable):" 5 | "" 6 | "On Demand Power Save - dim.wav" 7 | "On Demand Battery Level - battery.wav" 8 | "Battle Mode On (on toggle) - bmbegin.wav" 9 | "Battle Mode Off (on toggle) - bmend.wav" 10 | "Enter Volume Menu - vmbegin.wav" 11 | "Exit Volume Menu - vmend.wav" 12 | "Force Push - push.wav" 13 | "Fast On (optional) - faston.wav" 14 | "Multi-Blast Mode On - blstbgn.wav" 15 | "Multi-Blast Mode Off - blstend.wav" 16 | } 17 | 18 | BUTTONS{0} { 19 | STATE("OFF") { 20 | BUTTON("Thrust or Swing") { 21 | DESCRIPTION: "Activate blade" 22 | } 23 | BUTTON("Clash") { 24 | DESCRIPTION: "Play/Stop Music" 25 | } 26 | BUTTON("Light Shake while Saber is Up") { 27 | DESCRIPTION: "Next Preset" 28 | } 29 | } 30 | STATE("ON") { 31 | BUTTON("Clash until Swing") { 32 | DESCRIPTION: "Lockup" 33 | } 34 | BUTTON("Push Gesture") { 35 | DESCRIPTION: "Force Effect" 36 | } 37 | BUTTON("Light Shake while Saber is Up") { 38 | DESCRIPTION: "Color Change" 39 | } 40 | BUTTON("Clash") { 41 | DESCRIPTION: "Exit Color Change (Confirm Selection)" 42 | } 43 | } 44 | } 45 | 46 | BUTTONS{1} { 47 | STATE("OFF") { 48 | BUTTON("Short Click (Thrust/Swing On)") { 49 | DESCRIPTION: "Activate Blade" 50 | } 51 | BUTTON("Double Click") { 52 | DESCRIPTION: "Activate Muted" 53 | } 54 | BUTTON("Hold and Release") { 55 | DESCRIPTION: "Next Preset" 56 | } 57 | BUTTON("Hold and Wait") { 58 | DESCRIPTION: "Previous Preset" 59 | } 60 | BUTTON("Hold and Clash") { 61 | DESCRIPTION: "Enter Volume Menu" 62 | } 63 | BUTTON("Triple Click") { 64 | DESCRIPTION: "Battery Level" 65 | } 66 | BUTTON("Hold and Swing On") { 67 | DESCRIPTION: "Activate with Battle Mode" 68 | } 69 | } 70 | STATE("ON") { 71 | BUTTON("Hold and Release") { 72 | DESCRIPTION: "Play/Stop Music" 73 | } 74 | BUTTON("Hold and Wait") { 75 | DESCRIPTION: "Turn the blade off" 76 | } 77 | BUTTON("Hold and Clash") { 78 | DESCRIPTION: "Lockup" 79 | } 80 | BUTTON("Hold and Clash while pointing down") { 81 | DESCRIPTION: "Drag" 82 | } 83 | BUTTON("Short Click") { 84 | DESCRIPTION: "Blaster Block" 85 | } 86 | BUTTON("Hold and Push Gesture") { 87 | DESCRIPTION: "Force Effect" 88 | } 89 | BUTTON("Hold and Twist") { 90 | DESCRIPTION: "Color Change Mode" 91 | } 92 | BUTTON("Hold and Stab") { 93 | DESCRIPTION: "Melt" 94 | } 95 | BUTTON("Double Click and Hold") { 96 | DESCRIPTION: "Lightning Block" 97 | } 98 | BUTTON("Hold and Swing") { 99 | DESCRIPTION: "Enter Multi-Block Mode" 100 | } 101 | } 102 | STATE("in Volume Menu") { 103 | BUTTON("Hold and Release") { 104 | DESCRIPTION: "Volume Down" 105 | } 106 | BUTTON("Short Click") { 107 | DESCRIPTION: "Volume Up" 108 | } 109 | BUTTON("Hold and Clash") { 110 | DESCRIPTION: "Exit" 111 | } 112 | } 113 | STATE("in Color Change") { 114 | BUTTON("Hold Button") { 115 | DESCRIPTION: "Confirm Selection and Exit" 116 | } 117 | } 118 | STATE("in Multi-Block") { 119 | BUTTON("Short Click") { 120 | DESCRIPTION: "Exit Multi-Block Mode" 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /resources/templates/resource.rc.in: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ApplicationIcon ICON "${CMAKE_SOURCE_DIR}/resources/icons/icon.ico" 4 | ${TRANSLATIONS} 5 | 6 | 1 VERSIONINFO 7 | FILEVERSION 1,0,0,0 8 | PRODUCTVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},0 9 | FILEOS VOS_NT 10 | BEGIN 11 | BLOCK "StringFileInfo" 12 | BEGIN 13 | BLOCK "040904E4" // US English, UTF-8. 14 | BEGIN 15 | VALUE "ProductName", "ProffieConfig" 16 | VALUE "ProductVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.0" 17 | VALUE "CompanyName", "Kafrene Trading" 18 | VALUE "FileDescription", "${DESCRIPTION}" 19 | VALUE "InternalName", "$" 20 | VALUE "LegalCopyright", "(C) 2025 Ryan Ogurek" 21 | VALUE "OriginalFilename", "$" 22 | END 23 | END 24 | BLOCK "VarFileInfo" 25 | BEGIN 26 | VALUE "Translation", 0x0409, 1252 // US English, UTF-8 27 | END 28 | END 29 | -------------------------------------------------------------------------------- /screenshots/editor-bladearrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/screenshots/editor-bladearrays.png -------------------------------------------------------------------------------- /screenshots/editor-bladeawareness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/screenshots/editor-bladeawareness.png -------------------------------------------------------------------------------- /screenshots/editor-general.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/screenshots/editor-general.png -------------------------------------------------------------------------------- /screenshots/editor-presetsstyles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/screenshots/editor-presetsstyles.png -------------------------------------------------------------------------------- /screenshots/editor-propfile-fett263.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/screenshots/editor-propfile-fett263.png -------------------------------------------------------------------------------- /screenshots/mainmenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryancog/ProffieConfig/9c37c01225f657b7ced55d1b17bfafc9106af0a1/screenshots/mainmenu.png -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, The All-In-One Proffieboard Management Utility! 2 | 3 | # src/CMakeLists.txt 4 | 5 | set(SHARED_COMPONENTS 6 | utils 7 | log 8 | ui 9 | pconf 10 | ) 11 | 12 | set(STATIC_COMPONENTS 13 | app 14 | ) 15 | set(ALL_COMPONENTS ${SHARED_COMPONENTS} ${STATIC_COMPONENTS}) 16 | 17 | foreach(component ${ALL_COMPONENTS}) 18 | add_subdirectory(components/${component}) 19 | endforeach() 20 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/components) 21 | 22 | add_subdirectory(proffieconfig) 23 | add_subdirectory(launcher) 24 | add_subdirectory(upgen) 25 | 26 | install(TARGETS proffieconfig RUNTIME DESTINATION ${INSTALL_BIN_DIR}) 27 | install(TARGETS launcher RUNTIME DESTINATION ${INSTALL_DIR} BUNDLE DESTINATION ${INSTALL_DIR}) 28 | 29 | install(TARGETS ${SHARED_COMPONENTS} 30 | LIBRARY DESTINATION ${INSTALL_COMPONENTS_DIR} 31 | RUNTIME DESTINATION ${INSTALL_COMPONENTS_DIR} 32 | ) 33 | 34 | -------------------------------------------------------------------------------- /src/Common.cmake: -------------------------------------------------------------------------------- 1 | # ProffieConfig, The All-In-One Proffieboard Management Utility! 2 | 3 | # src/Common.cmake 4 | 5 | function(setup_target TARGET) 6 | if (CMAKE_SYSTEM_NAME STREQUAL Linux) 7 | set(RPATH "$ORIGIN/../lib:$ORIGIN/../components") 8 | elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin) 9 | if (CMAKE_BUILD_TYPE STREQUAL Debug) 10 | set(RPATH "@executable_path/../lib\;@executable_path/../components") 11 | elseif (CMAKE_BUILD_TYPE STREQUAL Release) 12 | set(RPATH "@executable_path/../../../../lib\;@executable_path/../../../../components") 13 | endif() 14 | 15 | get_target_property(EXEC_VERSION ${TARGET} VERSION) 16 | set_target_properties(${TARGET} PROPERTIES 17 | MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION}" 18 | ) 19 | elseif (CMAKE_SYSTEM_NAME STREQUAL Windows) 20 | set(RPATH "ThisMeansNothing") 21 | get_target_property(DESCRIPTION ${TARGET} DESCRIPTION) 22 | if (${DESCRIPTION} STREQUAL "DESCRIPTION-NOTFOUND") 23 | set(DESCRIPTION "$ library for ProffieConfig") 24 | endif() 25 | get_target_property(TRANSLATIONS ${TARGET} TRANSLATION_LIST) 26 | foreach(TRANSLATION TRANSLATION_LIST) 27 | string(APPEND TRANSLATIONS "${TARGET}_${TRANSLATION} MOFILE \"${CMAKE_CURRENT_LIST_DIR}/i18n/${TRANSLATION}/${TARGET}.mo\"") 28 | endforeach() 29 | configure_file(${CMAKE_SOURCE_DIR}/resources/templates/resource.rc.in ${CMAKE_CURRENT_BINARY_DIR}/resource.rc.gen) 30 | file(GENERATE 31 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.rc 32 | INPUT ${CMAKE_CURRENT_BINARY_DIR}/resource.rc.gen 33 | ) 34 | target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/wxWidgets/include) 35 | target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.rc) 36 | endif() 37 | set_target_properties(${TARGET} PROPERTIES 38 | INSTALL_RPATH ${RPATH} 39 | BUILD_WITH_INSTALL_RPATH true 40 | ) 41 | 42 | get_target_property(VERSION ${TARGET} EXEC_VERSION) 43 | target_compile_definitions(${TARGET} PRIVATE EXEC_VERSION=${VERSION}) 44 | endfunction() 45 | -------------------------------------------------------------------------------- /src/components/Component.cmake: -------------------------------------------------------------------------------- 1 | include(GenerateExportHeader) 2 | include(${CMAKE_CURRENT_LIST_DIR}/../Common.cmake) 3 | 4 | function(setup_component TARGET) 5 | target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) # Include components/ 6 | 7 | set_target_properties(${TARGET} PROPERTIES 8 | CXX_VISIBILITY_PRESET hidden 9 | VISIBILITY_INLINES_HIDDEN YES 10 | POSITION_INDEPENDENT_CODE ON 11 | ) 12 | 13 | generate_export_header(${TARGET} 14 | EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/private/export.h 15 | ) 16 | 17 | setup_target(${TARGET}) 18 | endfunction() 19 | 20 | function(setup_component_and_static TARGET) 21 | setup_component(${TARGET}) 22 | 23 | target_include_directories(${TARGET}-static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) # Include components/ 24 | string(TOUPPER ${TARGET} TARGET_UPPER) 25 | target_compile_definitions(${TARGET}-static PUBLIC -D${TARGET_UPPER}_STATIC_DEFINE) 26 | 27 | setup_target(${TARGET}-static) 28 | endfunction() 29 | 30 | -------------------------------------------------------------------------------- /src/components/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # components/app/CMakeLists.txt 4 | 5 | set(files 6 | app.cpp 7 | ) 8 | 9 | # This gets statically linked regardless, but there's still 10 | # distinction in its dependencies 11 | add_library(app STATIC ${files}) 12 | add_library(app-static STATIC ${files}) 13 | 14 | target_link_libraries(app 15 | wxWidgets 16 | 17 | utils 18 | log 19 | ) 20 | target_link_libraries(app-static 21 | wxWidgets-static 22 | 23 | utils-static 24 | log-static 25 | ) 26 | 27 | include(../Component.cmake) 28 | setup_component_and_static(app) 29 | 30 | -------------------------------------------------------------------------------- /src/components/app/app.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/app/app.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "private/export.h" 28 | 29 | namespace App { 30 | 31 | /** 32 | * Initialize an application 33 | * 34 | * @param appName the name to use in the Application 35 | * @param lockName the name to use to lock concurrent runs, defaults to appName 36 | * 37 | * @return if the app should continue running or not. 38 | */ 39 | APP_EXPORT bool init(const string& appName, const string& lockName = {}); 40 | 41 | APP_EXPORT void exceptionHandler(); 42 | 43 | struct APP_EXPORT Menus { 44 | wxMenuBar *menuBar; 45 | wxMenu *file; 46 | wxMenu *edit; 47 | wxMenu *view; 48 | wxMenu *help; 49 | }; 50 | 51 | // This is a memory leak if not used! 52 | APP_EXPORT Menus createDefaultMenuBar(); 53 | 54 | #if defined(__WIN32__) 55 | APP_EXPORT [[nodiscard]] bool darkMode(); 56 | #endif 57 | 58 | inline string getAppName() { return wxApp::GetGUIInstance()->GetAppName().ToStdString(); } 59 | 60 | } // namespace App 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/components/app/windowids.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/app/windowids.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | namespace App { 23 | 24 | enum { 25 | MAIN_MENU, 26 | WIRING_EDITOR, 27 | STYLE_DOCS, 28 | }; 29 | 30 | } // namespace App 31 | 32 | -------------------------------------------------------------------------------- /src/components/log/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # components/log/CMakeLists.txt 4 | 5 | set(files 6 | logger.cpp 7 | context.cpp 8 | branch.cpp 9 | message.cpp 10 | ) 11 | 12 | add_library(log SHARED ${files}) 13 | add_library(log-static STATIC ${files}) 14 | 15 | target_link_libraries(log 16 | utils 17 | ) 18 | 19 | target_link_libraries(log-static 20 | utils-static 21 | ) 22 | 23 | include(../Component.cmake) 24 | setup_component_and_static(log) 25 | 26 | -------------------------------------------------------------------------------- /src/components/log/branch.cpp: -------------------------------------------------------------------------------- 1 | #include "branch.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/branch.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "context.h" 23 | #include "logger.h" 24 | 25 | namespace Log { 26 | 27 | } // namespace Log 28 | 29 | Log::Branch::Branch(const string& message, Severity sev, Logger *logger) : 30 | Message(message, sev, logger), mParent(logger) {} 31 | 32 | Log::Branch::~Branch() { 33 | for (const auto *logger : mLoggers) { 34 | delete logger; 35 | } 36 | } 37 | 38 | Log::Logger& Log::Branch::createLogger(string name) { 39 | mListLock.lock(); 40 | mLoggers.push_back(new Logger{std::move(name), mParent->pContext}); 41 | mListLock.unlock(); 42 | return *mLoggers.back(); 43 | } 44 | 45 | Log::Logger& Log::Branch::optCreateLogger(string name, Log::Branch *branch) { 46 | return branch ? branch->createLogger(std::move(name)) : Context::getGlobal().createLogger(std::move(name)); 47 | } 48 | 49 | std::list Log::Branch::getLoggers() const { return mLoggers; } 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/components/log/branch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/branch.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "private/export.h" 28 | #include "message.h" 29 | 30 | namespace Log { 31 | 32 | class Logger; 33 | 34 | // Used to create a new logger specifically for a 35 | // subfunction/action which is a "branch" off an 36 | // existing logger. 37 | // 38 | // Extends from Message because it's placed in the 39 | // parent logger's message list. 40 | class LOG_EXPORT Branch : public Message { 41 | public: 42 | Branch() = delete; 43 | Branch(const Branch&) = delete; 44 | ~Branch() override; 45 | 46 | // Create a logger with the provided branch, if valid, otherwise log 47 | // with the global context. 48 | [[nodiscard]] static Logger& optCreateLogger(string name, Branch *); 49 | [[nodiscard]] Logger& createLogger(string name); 50 | 51 | [[nodiscard]] std::list getLoggers() const; 52 | 53 | [[nodiscard]] Type getType() const override { return Type::BRANCH; } 54 | 55 | private: 56 | friend class Logger; 57 | Branch(const string& message, Severity, Logger *); 58 | 59 | std::list mLoggers; 60 | std::mutex mListLock; 61 | const Logger *mParent; 62 | }; 63 | 64 | } // namespace Log 65 | 66 | -------------------------------------------------------------------------------- /src/components/log/context.cpp: -------------------------------------------------------------------------------- 1 | #include "context.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/context.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "logger.h" 30 | 31 | namespace Log { 32 | 33 | constexpr cstring GLOBAL_TAG{"GLOBAL"}; 34 | std::unique_ptr globalContext; 35 | 36 | } // namespace Log 37 | 38 | Log::Context::Context(string name, vector outStreams, 39 | bool outputToFile) 40 | : pName(std::move(name)), mOutputs(std::move(outStreams)) { 41 | 42 | if (outputToFile) { 43 | if (pName == GLOBAL_TAG) { 44 | mRESOutFile.open(Paths::logs() / (App::getAppName() + ".log")); 45 | } else { 46 | mRESOutFile.open(Paths::logs() / (App::getAppName() + "-" + pName + ".log")); 47 | } 48 | mOutputs.insert(mOutputs.begin(), &mRESOutFile); 49 | 50 | constexpr cstring HEADER_START{" Log [Context: "}; 51 | constexpr cstring HEADER_END{"]\n"}; 52 | constexpr cstring TIME_START{"Started at "}; 53 | 54 | auto now{std::chrono::system_clock::now()}; 55 | auto timeNow{std::chrono::system_clock::to_time_t(now)}; 56 | 57 | mRESOutFile << App::getAppName().c_str() << " Log (" << wxSTRINGIZE(EXEC_VERSION) 58 | << ") [Context: " << pName << "]\n"; 59 | mRESOutFile << "Started at " << std::ctime(&timeNow) << "\n\n" 60 | << std::flush; 61 | } 62 | } 63 | 64 | Log::Context::~Context() { 65 | for (const auto *logger : mLoggers) { 66 | delete logger; 67 | } 68 | mRESOutFile.close(); 69 | } 70 | 71 | Log::Context &Log::Context::getGlobal() { 72 | if (not globalContext) { 73 | globalContext = std::make_unique(GLOBAL_TAG); 74 | } 75 | return *globalContext; 76 | } 77 | 78 | void Log::Context::destroyGlobal() { globalContext.reset(); } 79 | 80 | bool Log::Context::setGlobalOuput(vector outStreams, 81 | bool fileOutput) { 82 | if (globalContext) 83 | return false; 84 | 85 | globalContext = std::make_unique( 86 | GLOBAL_TAG, std::move(outStreams), fileOutput); 87 | return true; 88 | } 89 | 90 | void Log::Context::setSeverity(Severity sev) { mCurrentSev = sev; } 91 | 92 | void Log::Context::quickLog(Severity sev, string tag, string message) { 93 | sendOut(sev, Message{std::move(message), sev, std::move(tag)}.formatted()); 94 | } 95 | 96 | void Log::Context::sendOut(Severity sev, const string &str) { 97 | if (sev < mCurrentSev) return; 98 | 99 | mSendLock.lock(); 100 | for (auto *out : mOutputs) *out << '\n' << str << std::flush; 101 | mSendLock.unlock(); 102 | } 103 | 104 | Log::Logger &Log::Context::createLogger(string name) { 105 | mListLock.lock(); 106 | mLoggers.push_back(new Logger{std::move(name), this}); 107 | mListLock.unlock(); 108 | return *mLoggers.back(); 109 | } 110 | 111 | std::list Log::Context::getLoggers() const { return mLoggers; } 112 | -------------------------------------------------------------------------------- /src/components/log/context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/context.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "utils/types.h" 28 | 29 | #include "severity.h" 30 | #include "private/export.h" 31 | 32 | namespace Log { 33 | 34 | class Logger; 35 | class LOG_EXPORT Context { 36 | public: 37 | Context() = delete; 38 | Context(string name, vector = {}, bool outputToFile = true); 39 | ~Context(); 40 | 41 | static Context& getGlobal(); 42 | static void destroyGlobal(); 43 | 44 | [[nodiscard]] Logger& createLogger(string name); 45 | [[nodiscard]] list getLoggers() const; 46 | 47 | void setSeverity(Severity); 48 | void quickLog(Severity, string tag, string message); 49 | 50 | /** 51 | * Attempts to set the outputs for the global loggger. 52 | * 53 | * Must be called before first usage of `getGlobal()`. 54 | * Initializes the global output and cannot be used twice. 55 | * 56 | * @return true if succeeded, false otherwise 57 | */ 58 | static bool setGlobalOuput(vector outStreams, bool fileOutput = true); 59 | 60 | protected: 61 | friend class Logger; 62 | friend class Branch; 63 | 64 | void sendOut(Severity, const string&); 65 | const string pName; 66 | 67 | private: 68 | std::list mLoggers; 69 | std::vector mOutputs; 70 | 71 | std::mutex mSendLock; 72 | std::mutex mListLock; 73 | 74 | Severity mCurrentSev{Severity::DBUG}; 75 | 76 | // Reserved object, should not be used except to maintain lifetime! 77 | std::ofstream mRESOutFile; 78 | }; 79 | 80 | } // namespace Log 81 | 82 | -------------------------------------------------------------------------------- /src/components/log/logger.cpp: -------------------------------------------------------------------------------- 1 | #include "logger.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/private/logger.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "branch.h" 23 | #include "context.h" 24 | 25 | namespace Log { 26 | 27 | } // namespace Log 28 | 29 | Log::Logger::Logger(string name, Context *context) : 30 | name(std::move(name)), pContext(context) {} 31 | 32 | Log::Logger::~Logger() { 33 | for (const auto *message : mMessages) { 34 | delete message; 35 | } 36 | } 37 | 38 | [[nodiscard]] std::list Log::Logger::getMessages() const { 39 | return mMessages; 40 | } 41 | 42 | Log::Branch* Log::Logger::branch(Severity sev, const string& message) { 43 | auto *branch{new Log::Branch(message, sev, this)}; 44 | auto formattedMessage{branch->formatted()}; 45 | 46 | pContext->sendOut(sev, formattedMessage); 47 | 48 | mMessageLock.lock(); 49 | mMessages.push_back(branch); 50 | mMessageLock.unlock(); 51 | 52 | return branch; 53 | } 54 | 55 | Log::Branch* Log::Logger::berror(const string& message) { 56 | return branch(Severity::ERR, message); 57 | } 58 | 59 | Log::Branch* Log::Logger::bwarn(const string& message) { 60 | return branch(Severity::WARN, message); 61 | } 62 | 63 | Log::Branch* Log::Logger::binfo(const string& message) { 64 | return branch(Severity::INFO, message); 65 | } 66 | 67 | Log::Branch* Log::Logger::bdebug(const string& message) { 68 | return branch(Severity::DBUG, message); 69 | } 70 | 71 | Log::Branch* Log::Logger::bverbose(const string& message) { 72 | return branch(Severity::VERB, message); 73 | } 74 | 75 | void Log::Logger::log(Severity sev, const string& message) { 76 | auto *messageObj{new Message(message, sev, this)}; 77 | auto formattedMessage{messageObj->formatted()}; 78 | 79 | pContext->sendOut(sev, formattedMessage); 80 | 81 | mMessageLock.lock(); 82 | mMessages.push_back(messageObj); 83 | mMessageLock.unlock(); 84 | } 85 | 86 | void Log::Logger::error(const string& message) { 87 | return log(Severity::ERR, message); 88 | } 89 | void Log::Logger::warn(const string& message) { 90 | return log(Severity::WARN, message); 91 | } 92 | void Log::Logger::info(const string& message) { 93 | return log(Severity::INFO, message); 94 | } 95 | void Log::Logger::debug(const string& message) { 96 | return log(Severity::DBUG, message); 97 | } 98 | void Log::Logger::verbose(const string& message) { 99 | return log(Severity::VERB, message); 100 | } 101 | 102 | -------------------------------------------------------------------------------- /src/components/log/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/logger.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "private/export.h" 28 | #include "message.h" 29 | #include "severity.h" 30 | 31 | namespace Log { 32 | class Branch; 33 | class Context; 34 | 35 | // Primary logger class 36 | class LOG_EXPORT Logger { 37 | public: 38 | Logger() = delete; 39 | Logger(const Logger&) = delete; 40 | ~Logger(); 41 | 42 | const string name; 43 | 44 | [[nodiscard]] Branch *branch(Severity, const string& message); 45 | [[nodiscard]] Branch *berror(const string& message); 46 | [[nodiscard]] Branch *bwarn(const string& message); 47 | [[nodiscard]] Branch *binfo(const string& message); 48 | [[nodiscard]] Branch *bdebug(const string& message); 49 | [[nodiscard]] Branch *bverbose(const string& message); 50 | 51 | void log(Severity, const string&); 52 | void error(const string&); 53 | void warn(const string&); 54 | void info(const string&); 55 | void debug(const string&); 56 | void verbose(const string&); 57 | 58 | // Copy to avoid concurrent read/mod errors 59 | [[nodiscard]] std::list getMessages() const; 60 | 61 | protected: 62 | friend class Branch; 63 | friend class Context; 64 | 65 | Logger(string name, Context *context); 66 | Context *const pContext; 67 | 68 | private: 69 | 70 | std::list mMessages; 71 | std::mutex mMessageLock; 72 | }; 73 | 74 | } // namespace Log 75 | 76 | -------------------------------------------------------------------------------- /src/components/log/message.cpp: -------------------------------------------------------------------------------- 1 | #include "message.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/private/message.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "log/severity.h" 23 | #include "logger.h" 24 | 25 | namespace Log { 26 | 27 | } // namespace Log 28 | 29 | Log::Message::Message(string message, Severity severity, Logger *parent) : 30 | message(std::move(message)), severity(severity), logTag(parent->name) {} 31 | 32 | string Log::Message::formatted() const { 33 | string messagePrefix{"[" + logTag + "] "}; 34 | switch (severity) { 35 | case Severity::VERB: 36 | messagePrefix += "(VERB) "; 37 | break; 38 | case Severity::DBUG: 39 | messagePrefix += "(DBUG) "; 40 | break; 41 | case Severity::INFO: 42 | messagePrefix += "(INFO) "; 43 | break; 44 | case Severity::WARN: 45 | messagePrefix += "(WARN) "; 46 | break; 47 | case Severity::ERR: 48 | messagePrefix += " (ERR) "; 49 | break; 50 | case Severity::MAX: 51 | abort(); 52 | } 53 | auto tmpMessage{message}; 54 | auto newlinePos{tmpMessage.find('\n')}; 55 | while (newlinePos != string::npos) { 56 | tmpMessage.insert(newlinePos + 1, messagePrefix.size(), ' '); 57 | newlinePos = tmpMessage.find('\n', newlinePos + 1); 58 | } 59 | 60 | return messagePrefix + tmpMessage; 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/components/log/message.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/message.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "utils/types.h" 25 | #include "private/export.h" 26 | #include "severity.h" 27 | 28 | namespace Log { 29 | 30 | class Logger; 31 | class LOG_EXPORT Message { 32 | public: 33 | Message() = delete; 34 | virtual ~Message() = default; 35 | 36 | enum class Type { 37 | MESSAGE, 38 | BRANCH 39 | }; 40 | 41 | [[nodiscard]] virtual Type getType() const { return Type::MESSAGE; } 42 | 43 | [[nodiscard]] string formatted() const; 44 | const string message; 45 | const Severity severity; 46 | const string logTag; 47 | 48 | protected: 49 | friend class Logger; 50 | friend class Context; 51 | Message(string message, Severity severity, Logger *parent); 52 | Message(string message, Severity severity, string logTag) : 53 | message(std::move(message)), severity(severity), logTag(std::move(logTag)) {} 54 | }; 55 | 56 | } // namespace Log 57 | 58 | -------------------------------------------------------------------------------- /src/components/log/severity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/log/severity.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | namespace Log { 23 | 24 | enum class Severity { 25 | VERB, 26 | DBUG, 27 | INFO, 28 | WARN, 29 | ERR, 30 | MAX, 31 | }; 32 | 33 | } // namespace Log 34 | 35 | -------------------------------------------------------------------------------- /src/components/pconf/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # components/pconf/CMakeLists.txt 4 | 5 | set(files 6 | pconf.cpp 7 | ) 8 | 9 | add_library(pconf SHARED ${files}) 10 | add_library(pconf-static STATIC ${files}) 11 | 12 | target_link_libraries(pconf log) 13 | 14 | target_link_libraries(pconf-static log-static) 15 | 16 | include(../Component.cmake) 17 | setup_component_and_static(pconf) 18 | 19 | -------------------------------------------------------------------------------- /src/components/pconf/pconf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/pconf/pconf.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | // TODO: Break this up into separate files 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include "private/export.h" 32 | 33 | namespace PConf { 34 | 35 | struct Entry; 36 | struct Section; 37 | 38 | using Data = vector>; 39 | using HashedData = std::unordered_multimap>; 40 | 41 | PCONF_EXPORT bool read(std::istream&, Data& out, Log::Branch *); 42 | PCONF_EXPORT void write(std::ostream&, const Data&, Log::Branch *); 43 | 44 | [[nodiscard]] PCONF_EXPORT HashedData hash(const Data&); 45 | 46 | enum class Type { 47 | ENTRY, 48 | SECTION 49 | }; 50 | 51 | struct PCONF_EXPORT Entry { 52 | Entry() = default; 53 | Entry( 54 | string name, 55 | std::optional value = std::nullopt, 56 | std::optional label = std::nullopt, 57 | std::optional labelNum = std::nullopt 58 | ); 59 | virtual ~Entry() = default; 60 | 61 | string name; 62 | std::optional value{std::nullopt}; 63 | std::optional label{std::nullopt}; 64 | std::optional labelNum{std::nullopt}; 65 | 66 | [[nodiscard]] virtual Type getType() const { return Type::ENTRY; } 67 | }; 68 | 69 | struct PCONF_EXPORT Section : public Entry { 70 | Section() = default; 71 | Section( 72 | string name, 73 | std::optional label = std::nullopt, 74 | std::optional labelNum = std::nullopt, 75 | Data entries = {} 76 | ); 77 | Data entries; 78 | 79 | [[nodiscard]] Type getType() const override { return Type::SECTION; } 80 | }; 81 | 82 | } // namespace PConf 83 | -------------------------------------------------------------------------------- /src/components/ui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # components/utils/CMakeLists.txt 4 | 5 | set(files 6 | frame.cpp 7 | movable.cpp 8 | plaque.cpp 9 | controls.cpp 10 | message.cpp 11 | ) 12 | 13 | add_library(ui SHARED ${files}) 14 | add_library(ui-static STATIC ${files}) 15 | 16 | target_link_libraries(ui 17 | wxWidgets 18 | app 19 | ) 20 | 21 | target_link_libraries(ui-static 22 | wxWidgets-static 23 | app-static 24 | ) 25 | 26 | if (CMAKE_SYSTEM_NAME STREQUAL Windows) 27 | target_link_libraries(ui dwmapi) 28 | target_link_libraries(ui-static dwmapi) 29 | endif() 30 | 31 | include(../Component.cmake) 32 | setup_component_and_static(ui) 33 | 34 | -------------------------------------------------------------------------------- /src/components/ui/controls.cpp: -------------------------------------------------------------------------------- 1 | #include "controls.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/ui/controls.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | PCUI::Bool::Bool( 29 | ::wxWindow *parent, 30 | wxWindowID winID, 31 | bool initialValue, 32 | wxString onText, 33 | wxString offText, 34 | int64 style, 35 | const wxString& label, 36 | wxOrientation orient) : 37 | ControlBase(parent, winID), 38 | mOffText(std::move(offText)), 39 | mOnText(std::move(onText)) { 40 | 41 | auto *control{new wxToggleButton(this, winID, initialValue ? mOnText : mOffText, wxDefaultPosition, wxDefaultSize, style)}; 42 | if (initialValue) control->SetValue(true); 43 | 44 | init(control, label, orient); 45 | 46 | control->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent&) { 47 | entry()->SetLabel(entry()->GetValue() ? mOnText : mOffText); 48 | }); 49 | } 50 | 51 | PCUI::Choice::Choice( 52 | wxWindow *parent, 53 | wxWindowID winID, 54 | const wxArrayString& choices, 55 | const wxString& label, 56 | wxOrientation orient) : 57 | ControlBase(parent, winID) { 58 | 59 | auto *control{new wxChoice(this, winID, wxDefaultPosition, wxDefaultSize, choices)}; 60 | if (choices.size()) control->SetSelection(0); 61 | 62 | # ifdef __WXGTK__ 63 | control->SetMinSize(control->GetBestSize() + wxSize{ FromDIP(20), 0 }); 64 | # endif 65 | 66 | init(control, label, orient); 67 | } 68 | 69 | PCUI::ComboBox::ComboBox( 70 | wxWindow *parent, 71 | wxWindowID winID, 72 | const wxArrayString& choices, 73 | wxString defaultValue, 74 | const wxString& label, 75 | wxOrientation orient) : 76 | ControlBase(parent, winID) { 77 | 78 | auto *control{new wxComboBox(this, winID, defaultValue, wxDefaultPosition, wxDefaultSize, choices)}; 79 | if (choices.size() and defaultValue.empty()) control->SetSelection(0); 80 | 81 | # ifdef __WXGTK__ 82 | control->SetMinSize(control->GetBestSize() + wxSize{ FromDIP(20), 0 }); 83 | # endif 84 | 85 | init(control, label, orient); 86 | } 87 | 88 | PCUI::Numeric::Numeric( 89 | wxWindow* parent, 90 | wxWindowID winID, 91 | int32_t min, 92 | int32_t max, 93 | int32_t initial, 94 | int32_t increment, 95 | int64_t style, 96 | const wxString& label, 97 | const wxOrientation& orient) : 98 | ControlBase(parent, winID) { 99 | 100 | auto *control{new wxSpinCtrl(this, winID, {}, wxDefaultPosition, wxDefaultSize, style, min, max, initial)}; 101 | control->SetIncrement(increment); 102 | 103 | init(control, label, orient); 104 | } 105 | 106 | PCUI::NumericDec::NumericDec( 107 | wxWindow* parent, 108 | wxWindowID winID, 109 | float64 min, 110 | float64 max, 111 | float64 initial, 112 | float64 increment, 113 | int64 style, 114 | const wxString& label, 115 | const wxOrientation& orient) : 116 | ControlBase(parent, winID) { 117 | 118 | auto *control{new wxSpinCtrlDouble(this, winID, {}, wxDefaultPosition, wxDefaultSize, style, min, max, initial)}; 119 | control->SetIncrement(increment); 120 | 121 | init(control, label, orient); 122 | } 123 | 124 | PCUI::Text::Text( 125 | wxWindow *parent, 126 | wxWindowID winID, 127 | const wxString &initial, 128 | int64 style, 129 | const wxString &label, 130 | wxOrientation orient) : 131 | ControlBase(parent, winID) { 132 | 133 | auto *control{new wxTextCtrl(this, winID, initial, wxDefaultPosition, wxDefaultSize, style)}; 134 | # ifdef __WXMAC__ 135 | control->OSXDisableAllSmartSubstitutions(); 136 | # endif 137 | 138 | init(control, label, orient); 139 | } 140 | 141 | -------------------------------------------------------------------------------- /src/components/ui/frame.cpp: -------------------------------------------------------------------------------- 1 | #include "frame.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/ui/frame.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifdef __WIN32__ 23 | #include 24 | #endif 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | namespace PCUI { 33 | 34 | Frame::Frame(wxWindow *parent, 35 | wxWindowID winID, 36 | const wxString& title, 37 | const wxPoint& pos, 38 | const wxSize& size, 39 | int32_t style, 40 | const wxString& name) { 41 | Create(parent, winID, title, pos, size, style, name); 42 | 43 | # ifdef __WIN32__ 44 | SetIcon(wxICON(ApplicationIcon)); 45 | SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); 46 | 47 | Bind(wxEVT_CREATE, [this](wxWindowCreateEvent&) { 48 | DWORD useDarkMode{App::darkMode()}; 49 | DwmSetWindowAttribute( 50 | # ifdef __WXGTK__ 51 | GTKGetWin32Handle(), 52 | # else 53 | GetHWND(), 54 | # endif 55 | DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE, 56 | &useDarkMode, 57 | sizeof(DWORD) 58 | ); 59 | }); 60 | # endif 61 | 62 | SetDoubleBuffered(true); 63 | 64 | # ifdef __APPLE__ 65 | mMenus = App::createDefaultMenuBar(); 66 | SetMenuBar(mMenus.menuBar); 67 | # endif 68 | } 69 | 70 | Frame::~Frame() { 71 | if (mReference and *mReference) (*mReference) = nullptr; 72 | } 73 | 74 | App::Menus Frame::getMenus() { return mMenus; } 75 | 76 | void Frame::setReference(Frame** ref) { 77 | mReference = ref; 78 | } 79 | 80 | } // namespace PCUI 81 | 82 | -------------------------------------------------------------------------------- /src/components/ui/frame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/ui/frame.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "private/export.h" 28 | 29 | namespace PCUI { 30 | 31 | class UI_EXPORT Frame : public wxFrame { 32 | public: 33 | Frame(wxWindow* parent, 34 | int32_t winID, 35 | const wxString& title, 36 | const wxPoint& pos = wxDefaultPosition, 37 | const wxSize& size = wxDefaultSize, 38 | int32_t style = wxDEFAULT_FRAME_STYLE, 39 | const wxString& name = "Frame"); 40 | ~Frame() override; 41 | 42 | [[nodiscard]] App::Menus getMenus(); 43 | 44 | void setReference(Frame**); 45 | 46 | private: 47 | App::Menus mMenus; 48 | Frame** mReference{nullptr}; 49 | }; 50 | 51 | } // namespace PCUI 52 | -------------------------------------------------------------------------------- /src/components/ui/message.cpp: -------------------------------------------------------------------------------- 1 | #include "message.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/ui/message.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | int32 PCUI::showMessage(const wxString& msg, const wxString& caption, int32 style, wxWindow *parent) { 25 | # ifdef __WXMSW__ 26 | // for dark mode 27 | wxGenericMessageDialog dlg(parent, msg, caption.empty() ? wxMessageBoxCaptionStr : caption, style); 28 | auto ret{dlg.ShowModal()}; 29 | switch (ret) { 30 | case wxID_OK: return wxOK; 31 | case wxID_CANCEL: return wxCANCEL; 32 | case wxID_YES: return wxYES; 33 | case wxID_NO: return wxNO; 34 | case wxID_HELP: return wxHELP; 35 | default: return 0; 36 | } 37 | # else 38 | return wxMessageBox(msg, caption.empty() ? wxMessageBoxCaptionStr : caption, style, parent); 39 | # endif 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/components/ui/message.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/ui/message.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "private/export.h" 28 | 29 | namespace PCUI { 30 | 31 | /** 32 | * Show a wxMessageBox (with platform-specific setup) 33 | * 34 | * Blocks until user has acknowledged the window. 35 | * 36 | * @param msg The main message within the box to show 37 | * @param caption The box window title 38 | * @param style Augmenting style flags 39 | * @param parent Window to be modal over 40 | * 41 | * @return user selection 42 | */ 43 | UI_EXPORT int32 showMessage(const wxString& msg, const wxString& caption = {}, int32 style = wxOK | wxCENTER, wxWindow *parent = nullptr); 44 | 45 | #ifdef __WXMSW__ 46 | using ProgressDialog = wxGenericProgressDialog; 47 | #else 48 | using ProgressDialog = wxProgressDialog; 49 | #endif 50 | 51 | } // namespace PCUI 52 | 53 | -------------------------------------------------------------------------------- /src/components/ui/plaque.cpp: -------------------------------------------------------------------------------- 1 | #include "plaque.h" 2 | #include "wx/generic/statbmpg.h" 3 | /* 4 | * ProffieConfig, All-In-One Proffieboard Management Utility 5 | * Copyright (C) 2024 Ryan Ogurek 6 | * 7 | * components/ui/plaque.cpp 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | UI_EXPORT wxWindow *PCUI::createPlaque(wxWindow *parent, wxWindowID winID) { 30 | # ifdef __WXOSX__ 31 | // This is kind of a reverse way of building what's effectively a wxStaticBoxSizer 32 | auto *plaque{new wxStaticBox(parent, winID, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0)}; 33 | # else 34 | // TODO: the border doesn't update on color/theme switch 35 | constexpr auto STYLE{wxTAB_TRAVERSAL | wxBORDER_SUNKEN}; 36 | auto *plaque{new wxPanel(parent, winID, wxDefaultPosition, wxDefaultSize, STYLE)}; 37 | Theme::colorWindow(plaque, {{ 30, 2 }}); 38 | # endif 39 | 40 | return plaque; 41 | } 42 | 43 | UI_EXPORT wxStaticBitmapBase *PCUI::createStaticImage(wxWindow *parent, wxWindowID winID, const wxBitmap& bitmap) { 44 | # ifdef __WINDOWS__ 45 | auto *image{new wxGenericStaticBitmap(parent, winID, bitmap)}; 46 | # else 47 | auto *image{new wxStaticBitmap(parent, winID, bitmap)}; 48 | # endif 49 | image->SetScaleMode(wxStaticBitmapBase::Scale_AspectFill); 50 | return image; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/components/ui/plaque.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/ui/plaque.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "private/export.h" 27 | 28 | namespace PCUI { 29 | 30 | // Platform-dependent way of creating a raised "plaque" area for 31 | // visual distinction. 32 | [[nodiscard]] UI_EXPORT wxWindow *createPlaque(wxWindow *parent, wxWindowID winID); 33 | 34 | [[nodiscard]] UI_EXPORT wxStaticBitmapBase *createStaticImage(wxWindow *parent, wxWindowID winID, const wxBitmap&); 35 | 36 | } // namespace PCUI 37 | 38 | -------------------------------------------------------------------------------- /src/components/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # components/utils/CMakeLists.txt 4 | 5 | set(files 6 | trace.cpp 7 | paths.cpp 8 | image.cpp 9 | undo.cpp 10 | theme.cpp 11 | crypto.cpp 12 | ) 13 | 14 | add_library(utils SHARED ${files}) 15 | add_library(utils-static STATIC ${files}) 16 | 17 | target_link_libraries(utils 18 | wxWidgets 19 | tomcrypt-static 20 | ) 21 | target_link_libraries(utils-static 22 | wxWidgets-static 23 | tomcrypt-static 24 | ) 25 | 26 | include(../Component.cmake) 27 | setup_component_and_static(utils) 28 | 29 | -------------------------------------------------------------------------------- /src/components/utils/clone.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/clone.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | template 25 | struct RequireClone { 26 | virtual ~RequireClone() = default; 27 | virtual BASE *clone() const = 0; 28 | }; 29 | 30 | template 31 | struct Cloneable : BASE { 32 | Cloneable() = default; 33 | template 34 | Cloneable(ARGS&&... args) : BASE(std::forward(args)...){}; 35 | BASE *clone() const override { 36 | return new DERIVED(static_cast(*this)); 37 | } 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /src/components/utils/color.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/color.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | namespace Theme { 28 | 29 | enum ColorPlane { 30 | FOREGROUND, 31 | BACKGROUND, 32 | }; 33 | struct ColorInfo { 34 | wxSystemColour base; 35 | ColorPlane colorPlane; 36 | uint8 lightOffset; 37 | uint8 darkOffset; 38 | }; 39 | 40 | struct colorWindow { 41 | colorWindow() = delete; 42 | colorWindow(wxWindow *window, ColorInfo colorInfo) : mWindow(window), mColorInfo(colorInfo) { color(); } 43 | 44 | // Do coloring of window 45 | void color() const; 46 | 47 | private: 48 | ColorInfo mColorInfo; 49 | wxWindow *mWindow; 50 | }; 51 | 52 | } // namespace WindowColor 53 | 54 | -------------------------------------------------------------------------------- /src/components/utils/crypto.cpp: -------------------------------------------------------------------------------- 1 | #include "crypto.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/crypto.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | string Crypto::computeHash(const filepath& path) { 27 | auto inputStream{std::ifstream(path, std::ios::binary)}; 28 | array buffer; 29 | 30 | hash_state hashState; 31 | sha256_init(&hashState); 32 | 33 | while (not false) { 34 | inputStream.read(reinterpret_cast(buffer.data()), buffer.size()); 35 | auto bytesRead{inputStream.gcount()}; 36 | if (bytesRead == 0) break; 37 | 38 | sha256_process(&hashState, buffer.data(), bytesRead); 39 | } 40 | inputStream.close(); 41 | 42 | string hashStr; 43 | hashStr.resize(64); 44 | array hash; 45 | sha256_done(&hashState, hash.data()); 46 | 47 | for (uint64 byte{0}; byte < hash.size(); byte++) { 48 | (void)snprintf(&hashStr.at(byte * 2), 3, "%02x", hash[byte]); 49 | } 50 | 51 | return hashStr; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/components/utils/crypto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/crypto.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "private/export.h" 28 | 29 | namespace Crypto { 30 | 31 | // Pass in a `collisionMap` map of given type to check against to ensure no 32 | // duplicates/collisions are generated by this function. 33 | template 34 | inline uint64 genUID(const MAP& collisionMap) { 35 | std::mt19937_64 idGen{static_cast(std::chrono::steady_clock::now().time_since_epoch().count())}; 36 | auto id{idGen()}; 37 | while (collisionMap.find(id) != collisionMap.end()) id ^= idGen(); 38 | return id; 39 | } 40 | 41 | /** 42 | * Compute the hash at the given `path` 43 | * 44 | * Computes the SHA256 hash of the file using tomcrypt. 45 | * 46 | * @param path The path of the file to hash 47 | * 48 | * @return The hash as a str 49 | */ 50 | UTILS_EXPORT string computeHash(const filepath& path); 51 | 52 | 53 | } // namespace Crypto 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/components/utils/defer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/defer.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | struct Defer { 27 | Defer(std::function func) : mOnScopeLeave(std::move(func)) {} 28 | ~Defer() { mOnScopeLeave(); } 29 | 30 | Defer(const Defer&) = delete; 31 | Defer(Defer&&) = delete; 32 | Defer& operator=(const Defer&) = delete; 33 | Defer& operator=(Defer&&) = delete; 34 | 35 | private: 36 | const std::function mOnScopeLeave; 37 | }; 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/components/utils/image.cpp: -------------------------------------------------------------------------------- 1 | #include "image.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/image.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace Image { 29 | 30 | std::unordered_map bmps; 31 | 32 | } // namespace Image 33 | 34 | wxBitmap Image::loadPNG(const string& name, bool dpiScaled) { 35 | auto bmpIt{bmps.find(name)}; 36 | if (bmpIt != bmps.end()) return bmpIt->second; 37 | 38 | auto pngPath{Paths::resources() / "icons" / (name + ".png")}; 39 | // std::cout << "Loading PNG \"" << name << "\" from \"" << pngPath.native() << '"' << std::endl; 40 | auto bitmap{wxBitmap{pngPath.native(), wxBITMAP_TYPE_PNG}}; 41 | if (dpiScaled) bitmap.SetScaleFactor(getDPIScaleFactor()); 42 | 43 | bmps.emplace(name, bitmap); 44 | return bitmap; 45 | } 46 | 47 | wxBitmap Image::newBitmap(wxSize size) { 48 | wxBitmap bmp; 49 | bmp.CreateWithDIPSize(size, getDPIScaleFactor(), 32); 50 | bmp.UseAlpha(); 51 | return std::move(bmp); 52 | } 53 | 54 | int32 Image::getDPIScaleFactor() { return 2; } 55 | 56 | wxColour Image::getAccentColor() { return { 0x27, 0x4a, 0x72 }; } 57 | 58 | -------------------------------------------------------------------------------- /src/components/utils/image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/image.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include "private/export.h" 27 | 28 | namespace Image { 29 | 30 | UTILS_EXPORT wxBitmap loadPNG(const string& name, bool dpiScaled = true); 31 | UTILS_EXPORT wxBitmap newBitmap(wxSize); 32 | UTILS_EXPORT int32 getDPIScaleFactor(); 33 | UTILS_EXPORT wxColour getAccentColor(); 34 | 35 | } // namespace Image 36 | 37 | -------------------------------------------------------------------------------- /src/components/utils/paths.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/paths.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "private/export.h" 25 | 26 | namespace Paths { 27 | 28 | enum class Executable { 29 | CURRENT, 30 | LAUNCHER, 31 | MAIN, 32 | }; 33 | 34 | /** 35 | * Retrieve the path to an executable binary. 36 | * 37 | * @param exec The executable to retrieve a path for. Default is `Executable::CURRENT` 38 | * 39 | * @return The full executable path (including file) 40 | */ 41 | [[nodiscard]] UTILS_EXPORT filepath executable(Executable exec = Executable::CURRENT); 42 | 43 | /** 44 | * Retrieve the app root path 45 | * 46 | * This is the location where core app things are located. 47 | * A location modifiable without admin rights. 48 | * 49 | * @return root path 50 | */ 51 | [[nodiscard]] UTILS_EXPORT filepath approot(); 52 | 53 | [[nodiscard]] UTILS_EXPORT filepath binaries(); 54 | [[nodiscard]] UTILS_EXPORT filepath libraries(); 55 | [[nodiscard]] UTILS_EXPORT filepath components(); 56 | [[nodiscard]] UTILS_EXPORT filepath resources(); 57 | 58 | [[nodiscard]] UTILS_EXPORT filepath data(); 59 | [[nodiscard]] UTILS_EXPORT filepath configs(); 60 | [[nodiscard]] UTILS_EXPORT filepath injections(); 61 | [[nodiscard]] UTILS_EXPORT filepath props(); 62 | [[nodiscard]] UTILS_EXPORT filepath proffieos(); 63 | 64 | [[nodiscard]] UTILS_EXPORT filepath logs(); 65 | 66 | [[nodiscard]] UTILS_EXPORT string website(); 67 | [[nodiscard]] UTILS_EXPORT string remoteAssets(); 68 | [[nodiscard]] UTILS_EXPORT string remoteUpdateAssets(); 69 | 70 | } // namespace Paths 71 | 72 | -------------------------------------------------------------------------------- /src/components/utils/position.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/position.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "types.h" 25 | #include "private/export.h" 26 | 27 | struct UTILS_EXPORT Point { 28 | Point() = default; 29 | constexpr Point(int32 x, int32 y) : x(x), y(y) {} 30 | 31 | template 32 | explicit Point(T point) : x(point.x), y (point.y) {} 33 | 34 | Point(wxSize point) : x(point.x), y(point.y) {} 35 | Point(wxPoint point) : x(point.x), y(point.y) {} 36 | 37 | template 38 | explicit operator T() const { return { x, y }; } 39 | 40 | operator wxSize() const { return { x, y }; } 41 | operator wxPoint() const { return { x, y }; } 42 | 43 | bool operator==(const Point& rhs) const noexcept = default; 44 | auto operator<=>(const Point& rhs) const { 45 | if (*this == rhs) return std::partial_ordering::equivalent; 46 | if (x > rhs.x and y > rhs.y) return std::partial_ordering::greater; 47 | if (x < rhs.x and y < rhs.y) return std::partial_ordering::less; 48 | return std::partial_ordering::unordered; 49 | }; 50 | 51 | template 52 | [[nodiscard]] inline constexpr Point operator+(const T& rhs) const { 53 | return Point{ static_cast(std::round(x + rhs.x)), static_cast(std::round(y + rhs.y)) }; 54 | } 55 | 56 | template 57 | [[nodiscard]] inline constexpr Point operator-(const T& rhs) const { 58 | return Point{ static_cast(std::round(x - rhs.x)), static_cast(std::round(y - rhs.y)) }; 59 | } 60 | 61 | template 62 | [[nodiscard]] inline constexpr Point operator*(T scale) const { 63 | return Point{ static_cast(std::round(x * scale)), static_cast(std::round(y * scale)) }; 64 | } 65 | 66 | template 67 | [[nodiscard]] inline constexpr Point operator/(T scale) const { 68 | return Point{ static_cast(std::round(x / scale)), static_cast(std::round(y / scale)) }; 69 | } 70 | 71 | template 72 | inline constexpr Point& operator+=(const T& rhs) { return *this = (*this + rhs); } 73 | template 74 | inline constexpr Point& operator-=(const T& rhs) { return *this = (*this - rhs); } 75 | template 76 | inline constexpr Point& operator*=(const T& rhs) { return *this = (*this * rhs); } 77 | template 78 | inline constexpr Point& operator/=(const T& rhs) { return *this = (*this / rhs); } 79 | 80 | int32 x{0}; 81 | int32 y{0}; 82 | }; 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/components/utils/theme.cpp: -------------------------------------------------------------------------------- 1 | #include "theme.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/theme.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | namespace Theme { 31 | 32 | void init(); 33 | void color(wxWindow *, ColorInfo); 34 | void rebuildHierarchy(); 35 | 36 | // > 37 | std::map>windowLookup; 38 | deque colorQueue; 39 | 40 | } // namespace Theme 41 | 42 | void Theme::colorWindow(wxWindow *window, vector colorsInfo) { 43 | init(); 44 | for (const auto& colorInfo : colorsInfo) color(window, colorInfo); 45 | // Override default behavior in case of wxPanel 46 | window->Bind(wxEVT_SYS_COLOUR_CHANGED, [](wxSysColourChangedEvent& evt) { evt.Skip(false); }); 47 | windowLookup.emplace(window, std::move(colorsInfo)); 48 | rebuildHierarchy(); 49 | 50 | window->Bind(wxEVT_DESTROY, [window](wxWindowDestroyEvent& evt) { 51 | evt.Skip(); 52 | if (evt.GetWindow() != window) return; 53 | 54 | windowLookup.erase(windowLookup.find(window)); 55 | rebuildHierarchy(); 56 | }); 57 | } 58 | 59 | void Theme::init() { 60 | static bool initialized{false}; 61 | if (initialized) return; 62 | initialized = true; 63 | 64 | wxApp::GetGUIInstance()->GetTopWindow()->Bind(wxEVT_SYS_COLOUR_CHANGED, [](wxSysColourChangedEvent& evt) { 65 | evt.Skip(); 66 | for (auto *const win : colorQueue) { 67 | auto colorsInfo{windowLookup.find(win)->second}; 68 | for (const auto& colorInfo : colorsInfo) color(win, colorInfo); 69 | } 70 | }); 71 | } 72 | 73 | 74 | void Theme::color(wxWindow *window, ColorInfo colorInfo) { 75 | auto *refWin{colorInfo.referenceWindow ? colorInfo.referenceWindow : window->GetParent()}; 76 | wxColour baseColor; 77 | if (refWin) { 78 | baseColor = colorInfo.referencePlane == FOREGROUND ? 79 | refWin->GetForegroundColour() : 80 | refWin->GetBackgroundColour(); 81 | } else baseColor = wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK); 82 | 83 | auto newColor{ 84 | wxSystemSettings::SelectLightDark( 85 | baseColor.ChangeLightness(100 + colorInfo.lightOffset), 86 | baseColor.ChangeLightness(100 + colorInfo.darkOffset)) 87 | }; 88 | switch (colorInfo.colorPlane) { 89 | case FOREGROUND: 90 | window->SetForegroundColour(newColor); 91 | break; 92 | case BACKGROUND: 93 | window->SetBackgroundColour(newColor); 94 | break; 95 | default: 96 | // Make it obviously broken 97 | auto uglyColor{wxColour(0xFF, 0x00, 0xCC)}; 98 | window->SetBackgroundColour(uglyColor); 99 | window->SetForegroundColour(uglyColor); 100 | } 101 | 102 | } 103 | 104 | void Theme::rebuildHierarchy() { 105 | std::map coloredWindows{}; 106 | for (const auto& [ win, data ] : windowLookup) coloredWindows.emplace(win, false); 107 | 108 | colorQueue.clear(); 109 | for (const auto& winData : windowLookup) { 110 | auto *win{winData.first}; 111 | auto coloredIt{coloredWindows.find(win)}; 112 | if (coloredIt->second) continue; 113 | coloredIt->second = true; 114 | 115 | 116 | colorQueue.emplace_back(win); 117 | auto insertIt{std::prev(colorQueue.end())}; 118 | while (win->GetParent()) { 119 | win = win->GetParent(); 120 | auto coloredIt{coloredWindows.find(win)}; 121 | if (coloredIt != coloredWindows.end()) { 122 | if (coloredIt->second) break; 123 | coloredIt->second = true; 124 | 125 | insertIt = colorQueue.emplace(insertIt, win); 126 | } 127 | } 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/components/utils/theme.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/theme.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #include "private/export.h" 29 | 30 | namespace Theme { 31 | 32 | enum ColorPlane { 33 | FOREGROUND, 34 | BACKGROUND, 35 | }; 36 | 37 | struct UTILS_EXPORT ColorInfo { 38 | ColorInfo(int8 lightOffset, int8 darkOffset, ColorPlane colorPlane = BACKGROUND, ColorPlane refPlane = BACKGROUND, wxWindow *refWindow = nullptr) : 39 | lightOffset(lightOffset), darkOffset(darkOffset), colorPlane(colorPlane), referencePlane(refPlane), referenceWindow(refWindow) {} 40 | 41 | int8 lightOffset; 42 | int8 darkOffset; 43 | ColorPlane colorPlane; 44 | ColorPlane referencePlane; 45 | wxWindow *referenceWindow{nullptr}; 46 | }; 47 | 48 | UTILS_EXPORT void colorWindow(wxWindow *, vector); 49 | 50 | } // namespace Theme 51 | 52 | -------------------------------------------------------------------------------- /src/components/utils/trace.cpp: -------------------------------------------------------------------------------- 1 | #include "trace.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/trace.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | Trace::FilePos Trace::getFilePos(const string& fileBuffer, const uint64 index) { 23 | FilePos ret{}; 24 | if (index > fileBuffer.size() - 1) return ret; 25 | uint64 newLinePos{}; 26 | for (uint64 searchIdx{0}; searchIdx <= index; searchIdx++) { 27 | char chr{fileBuffer.at(searchIdx)}; 28 | if (chr == '\n') { 29 | newLinePos = searchIdx; 30 | ret.pos = 0; 31 | ret.line++; 32 | continue; 33 | } 34 | 35 | ret.pos++; 36 | } 37 | if (newLinePos != fileBuffer.size() - 1) { 38 | auto lineStart{fileBuffer.find_first_not_of(" \t", newLinePos + 1)}; 39 | if (lineStart != string::npos) ret.fullLine = fileBuffer.substr(lineStart, fileBuffer.find_first_of("\r\n", newLinePos + 1) - lineStart); 40 | } 41 | return ret; 42 | } 43 | 44 | Trace::FilePos::operator string() const { 45 | return "At line " + std::to_string(line + 1) + ", col " + std::to_string(pos + 1) + ": " + fullLine; 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/components/utils/trace.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/trace.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "private/export.h" 25 | 26 | namespace Trace { 27 | 28 | struct UTILS_EXPORT FilePos { 29 | string fullLine; 30 | int32 line{0}; 31 | int32 pos{0}; 32 | 33 | [[nodiscard]] operator string() const; 34 | }; 35 | 36 | [[nodiscard]] UTILS_EXPORT FilePos getFilePos(const string& fileBuffer, uint64 index); 37 | 38 | } // namespace Trace 39 | 40 | -------------------------------------------------------------------------------- /src/components/utils/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/types.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | // "Standard" types for ProffieConfig 33 | 34 | using int64 = int64_t; 35 | using int32 = int32_t; 36 | using int16 = int16_t; 37 | using int8 = int8_t; 38 | using uint64 = uint64_t; 39 | using uint32 = uint32_t; 40 | using uint16 = uint16_t; 41 | using uint8 = uint8_t; 42 | 43 | // These float sizes technically aren't 100% guaranteed, but 44 | // afaics on modern desktop this should always be the case... 45 | using float32 = float; 46 | using float64 = double; 47 | using float128 = long double; 48 | 49 | using byte = uint8; 50 | 51 | using cstring = const char *; 52 | 53 | using std::any; 54 | using std::array; 55 | using std::deque; 56 | using std::function; 57 | using std::list; 58 | using std::nullopt; 59 | using std::optional; 60 | using std::string; 61 | using std::wstring; 62 | using std::string_view; 63 | using std::vector; 64 | namespace fs = std::filesystem; 65 | using filepath = fs::path; 66 | -------------------------------------------------------------------------------- /src/components/utils/undo.cpp: -------------------------------------------------------------------------------- 1 | #include "undo.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/undo.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | namespace Undo { 25 | 26 | enum EventTriggers { 27 | NONE, 28 | UNDO = 1 << 0, 29 | REDO = 1 << 1, 30 | REGISTER = 1 << 2, 31 | }; 32 | 33 | } // namespace Undo 34 | 35 | Undo::Event::Event(int32 triggers, wxEventType eventType) : wxNotifyEvent(eventType, wxID_ANY), mTriggers(triggers) {} 36 | 37 | wxEvent *Undo::Event::Clone() const { return new Event(*this); } 38 | 39 | bool Undo::Event::isUndo() const { return mTriggers & UNDO; } 40 | bool Undo::Event::isRedo() const { return mTriggers & REDO; } 41 | bool Undo::Event::isRegister() const { return mTriggers & REGISTER; } 42 | 43 | wxDEFINE_EVENT(Undo::EVT_ACTION, Undo::Event); 44 | wxDEFINE_EVENT(Undo::EVT_AT_SAVED, Undo::Event); 45 | wxDEFINE_EVENT(Undo::EVT_LEAVE_SAVED, Undo::Event); 46 | 47 | Undo::Action::Action(wxString name, ActionFunc perform, ActionFunc revert, any data) : 48 | mDoPerform(std::move(perform)), mDoRevert(std::move(revert)), mName(std::move(name)), mData(std::move(data)) {} 49 | 50 | void Undo::Action::perform() { 51 | if (not mDoPerform) return; 52 | mDoPerform(mData); 53 | } 54 | 55 | void Undo::Action::revert() { 56 | if (not mDoRevert) return; 57 | mDoRevert(mData); 58 | } 59 | 60 | const wxString& Undo::Action::name() const { return mName; } 61 | 62 | Undo::Handler::Handler(wxEvtHandler *evtHandler, int32 maxDepth) : mMaxDepth(maxDepth), mEvtHandler(evtHandler) {} 63 | 64 | optional Undo::Handler::canUndo() const { return mIdx >= 0 ? optional{mActions[mIdx].name()} : nullopt; } 65 | optional Undo::Handler::canRedo() const { return mIdx + 1 < mActions.size() ? optional{mActions[mIdx + 1].name()} : nullopt; }; 66 | bool Undo::Handler::isSaved() const { return mSavedIdx == mIdx; } 67 | 68 | void Undo::Handler::undo() { 69 | if (not canUndo()) return; 70 | 71 | bool wasOnSaved{isSaved()}; 72 | 73 | mActions[mIdx].revert(); 74 | mIdx--; 75 | 76 | wxPostEvent(mEvtHandler, Event(UNDO, EVT_ACTION)); 77 | if (wasOnSaved) wxPostEvent(mEvtHandler, Event(UNDO, EVT_LEAVE_SAVED)); 78 | else if (isSaved()) wxPostEvent(mEvtHandler, Event(UNDO, EVT_AT_SAVED)); 79 | } 80 | void Undo::Handler::redo() { 81 | if (not canRedo()) return; 82 | 83 | bool wasOnSaved{isSaved()}; 84 | 85 | mIdx++; 86 | mActions[mIdx].perform(); 87 | 88 | wxPostEvent(mEvtHandler, Event(REDO, EVT_ACTION)); 89 | if (wasOnSaved) wxPostEvent(mEvtHandler, Event(REDO, EVT_LEAVE_SAVED)); 90 | else if (isSaved()) wxPostEvent(mEvtHandler, Event(REDO, EVT_AT_SAVED)); 91 | } 92 | 93 | void Undo::Handler::registerAction(Action&& action, bool perform) { 94 | bool wasOnSaved{isSaved()}; 95 | 96 | if (mActions.size() == mMaxDepth) { 97 | mActions.pop_front(); 98 | mIdx--; 99 | mSavedIdx--; 100 | } 101 | 102 | mIdx++; 103 | if (mIdx < mActions.size()) mActions.erase(std::next(mActions.begin(), mIdx), mActions.end()); 104 | mActions.emplace_back(std::move(action)); 105 | 106 | if (perform) mActions.back().perform(); 107 | 108 | wxPostEvent(mEvtHandler, Event(REGISTER, EVT_ACTION)); 109 | if (wasOnSaved) wxPostEvent(mEvtHandler, Event(REGISTER, EVT_LEAVE_SAVED)); 110 | } 111 | 112 | void Undo::Handler::flagAsSaved() { 113 | mSavedIdx = mIdx; 114 | 115 | wxPostEvent(mEvtHandler, Event(NONE, EVT_AT_SAVED)); 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/components/utils/undo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * components/utils/undo.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include "private/export.h" 27 | 28 | namespace Undo { 29 | 30 | using ActionFunc = function; 31 | 32 | struct UTILS_EXPORT Event : wxNotifyEvent { 33 | Event(int32 triggers, wxEventType); 34 | 35 | [[nodiscard]] wxEvent *Clone() const override; 36 | 37 | // Check triggers 38 | [[nodiscard]] bool isUndo() const; 39 | [[nodiscard]] bool isRedo() const; 40 | [[nodiscard]] bool isRegister() const; 41 | 42 | private: 43 | int32 mTriggers; 44 | }; 45 | 46 | // Triggered on any undo/redo action. 47 | // Can use `isX()` to check what action occurred. 48 | UTILS_EXPORT wxDECLARE_EVENT(EVT_ACTION, Event); 49 | 50 | // Reached the action in the chain which is saved, or 51 | // the current action was flagged as the current saved version. 52 | // 53 | // Not sent on Handler init. 54 | UTILS_EXPORT wxDECLARE_EVENT(EVT_AT_SAVED, Event); 55 | 56 | // Left the action in the chain which is saved and/or 57 | // an undo/redo occurred. 58 | UTILS_EXPORT wxDECLARE_EVENT(EVT_LEAVE_SAVED, Event); 59 | 60 | struct UTILS_EXPORT Action { 61 | Action(wxString name, ActionFunc perform, ActionFunc revert, any data = {}); 62 | 63 | void perform(); 64 | void revert(); 65 | [[nodiscard]] const wxString& name() const; 66 | 67 | private: 68 | ActionFunc mDoPerform; 69 | ActionFunc mDoRevert; 70 | 71 | wxString mName; 72 | any mData; 73 | }; 74 | 75 | struct UTILS_EXPORT Handler { 76 | Handler(wxEvtHandler *, int32 maxDepth = 1024); 77 | 78 | // Return name of action that can be undone/redone if it exists. 79 | [[nodiscard]] optional canUndo() const; 80 | [[nodiscard]] optional canRedo() const; 81 | [[nodiscard]] bool isSaved() const; 82 | 83 | void undo(); 84 | void redo(); 85 | 86 | void registerAction(Action&&, bool perform = true); 87 | 88 | void flagAsSaved(); 89 | 90 | private: 91 | int32 mMaxDepth; 92 | int32 mIdx{-1}; 93 | int32 mSavedIdx{-1}; 94 | deque mActions; 95 | 96 | wxEvtHandler *mEvtHandler; 97 | }; 98 | 99 | } // namespace Undo 100 | 101 | -------------------------------------------------------------------------------- /src/launcher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # updater/CMakeLists.txt 4 | 5 | set(ICON_PATH ${CMAKE_SOURCE_DIR}/resources/icons/icon.icns) 6 | set_source_files_properties(${ICON_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) 7 | 8 | # set(TRANSLATION_ES ${CMAKE_CURRENT_LIST_DIR}/i18n/es/proffieconfig.mo) 9 | # set_source_files_properties(${TRANSLATION_ES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/es.lproj) 10 | 11 | add_executable(launcher WIN32 MACOSX_BUNDLE 12 | main.cpp 13 | 14 | routines.cpp 15 | 16 | update/update.cpp 17 | update/pulldata.cpp 18 | update/changelog.cpp 19 | update/install.cpp 20 | 21 | ${ICON_PATH} 22 | ) 23 | 24 | 25 | set_target_properties(launcher PROPERTIES 26 | OUTPUT_NAME "ProffieConfig" 27 | DESCRIPTION "ProffieConfig Launcher" # Windows is stupid so this isn't actually a description 28 | EXEC_VERSION 1.0.5 29 | TRANSLATIONS es 30 | MACOSX_BUNDLE_COPYRIGHT "Copyright (C) 2025 Ryan Ogurek" 31 | MACOSX_BUNDLE_GUI_IDENTIFIER "com.kafrenetrading.proffieconfiglauncher" 32 | MACOSX_BUNDLE_ICON_FILE "icon.icns" 33 | ) 34 | 35 | target_link_libraries(launcher 36 | wxWidgets-static 37 | 38 | app-static 39 | log-static 40 | utils-static 41 | ui-static 42 | pconf-static 43 | ) 44 | 45 | include(../Common.cmake) 46 | setup_target(launcher) 47 | 48 | -------------------------------------------------------------------------------- /src/launcher/routines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * launcher/routines.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | namespace Routine { 25 | 26 | void launch(Log::Branch&); 27 | 28 | void platformInstall(Log::Branch&); 29 | void platformUninstall(); 30 | 31 | } // namespace Routine 32 | 33 | -------------------------------------------------------------------------------- /src/launcher/update/changelog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * launcher/update/changelog.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "update.h" 25 | 26 | namespace Update { 27 | 28 | struct Changelog { 29 | Version currentBundleVersion; 30 | Version latestBundleVersion; 31 | 32 | struct ChangedFile { 33 | ItemID id; 34 | string hash; 35 | Version currentVersion; 36 | Version latestVersion; 37 | }; 38 | 39 | vector changedFiles; 40 | vector removedFiles; 41 | }; 42 | 43 | [[nodiscard]] Changelog generateChangelog(const Data&, const Version& currentVersion, Log::Branch&); 44 | 45 | [[nodiscard]] bool promptWithChangelog(const Data&, const Changelog&, Log::Branch&); 46 | 47 | [[nodiscard]] Version determineCurrentVersion(const Data&, PCUI::ProgressDialog *, Log::Branch&); 48 | 49 | } // namespace Update 50 | 51 | -------------------------------------------------------------------------------- /src/launcher/update/install.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * launcher/update/install.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "update.h" 25 | #include "changelog.h" 26 | 27 | namespace Update { 28 | 29 | [[nodiscard]] bool pullNewFiles(const Changelog& changelog, const Data& data, PCUI::ProgressDialog *, Log::Branch&); 30 | 31 | void installFiles(const Changelog& changelog, const Data& data, PCUI::ProgressDialog *, Log::Branch&); 32 | 33 | } // namespace Update 34 | 35 | -------------------------------------------------------------------------------- /src/launcher/update/pulldata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * launcher/update/pulldata.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include "update.h" 25 | #include "utils/paths.h" 26 | 27 | namespace Update { 28 | 29 | /** 30 | * Attempts to download latest version of `MANIFEST_FILE` 31 | */ 32 | [[nodiscard]] bool pullData(PCUI::ProgressDialog *, Log::Branch&); 33 | 34 | /** 35 | * Reads data from `MANIFEST_FILE` 36 | */ 37 | [[nodiscard]] optional parseData(PCUI::ProgressDialog *, Log::Branch&, bool heedMessages = true); 38 | 39 | inline filepath manifestFile() { return Paths::data() / "manifest.pconf"; } 40 | 41 | } // namespace Update 42 | 43 | -------------------------------------------------------------------------------- /src/launcher/update/update.cpp: -------------------------------------------------------------------------------- 1 | #include "update.h" 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * launcher/update/update.cpp 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | namespace Update { 27 | 28 | wxEvtHandler *handler{nullptr}; 29 | 30 | } // namespace Update 31 | 32 | 33 | void Update::init() { 34 | handler = new wxEvtHandler(); 35 | } 36 | 37 | wxEvtHandler *Update::getEventHandler() { return handler; } 38 | 39 | Update::Version::Version(string_view str) { 40 | string_view convStr{str}; 41 | const cstring end{str.end()}; 42 | 43 | auto parseNum{[this, &convStr, &end]() -> uint8 { 44 | if (convStr.data() >= end) { 45 | err = Err::STR_EMPTY; 46 | return 0; 47 | } 48 | 49 | char *parseEnd{}; 50 | int32 ret{}; 51 | ret = strtol(convStr.data(), &parseEnd, 10); 52 | 53 | if (convStr == parseEnd) { 54 | err = Err::STR_INVALID; 55 | return 0; 56 | } 57 | convStr = parseEnd; 58 | 59 | if (ret > std::numeric_limits::max() or ret < 0) { 60 | err = Err::NUM_RANGE; 61 | return 0; 62 | } 63 | 64 | return static_cast(ret); 65 | }}; 66 | 67 | 68 | major = parseNum(); 69 | if (err != Err::NONE) return; 70 | 71 | // Jump over '.' 72 | convStr.remove_prefix(1); 73 | minor = parseNum(); 74 | if (err != Err::NONE) { 75 | minor = 0; 76 | if (err == Err::STR_EMPTY) err = Err::NONE; 77 | return; 78 | } 79 | 80 | // Jump over '.' 81 | convStr.remove_prefix(1); 82 | bugfix = parseNum(); 83 | if (err != Err::NONE) { 84 | bugfix = 0; 85 | if (err == Err::STR_EMPTY) err = Err::NONE; 86 | return; 87 | } 88 | 89 | if (convStr == end) return; 90 | if (convStr[0] != '-') { 91 | err = Err::STR_INVALID; 92 | return; 93 | } 94 | 95 | // Jump over '-' 96 | convStr.remove_prefix(1); 97 | // If has whitespace 98 | if (convStr.end() != std::find_if(convStr.begin(), convStr.end(), [](char chr){ return std::isspace(chr); })) { 99 | err = Err::STR_INVALID; 100 | return; 101 | } 102 | 103 | tag = convStr; 104 | } 105 | 106 | Update::Version::operator string() const { 107 | switch (err) { 108 | case Err::INVALID: 109 | return "INVALID"; 110 | case Err::NUM_RANGE: 111 | return "Invalid given numeric range"; 112 | case Err::STR_INVALID: 113 | return "Invalid input"; 114 | case Err::STR_EMPTY: 115 | return "Empty input"; 116 | case Err::NONE: break; 117 | } 118 | 119 | auto ret{std::to_string(major)}; 120 | ret += '.' + std::to_string(minor); 121 | ret += '.' + std::to_string(bugfix); 122 | if (not tag.empty()) ret += '-' + tag; 123 | return ret; 124 | } 125 | 126 | Update::Version::operator bool() const { return err == Err::NONE; } 127 | 128 | Update::Version Update::Version::invalidObject() { 129 | Version ret; 130 | ret.err = Err::INVALID; 131 | return ret; 132 | } 133 | 134 | filepath Update::typeFolder(ItemType type) { 135 | switch (type) { 136 | case ItemType::EXEC: return "bin"; 137 | case ItemType::LIB: return "lib"; 138 | case ItemType::COMP: return "components"; 139 | case ItemType::RSRC: return "resources"; 140 | case TYPE_MAX: break; 141 | } 142 | return {}; 143 | } 144 | 145 | -------------------------------------------------------------------------------- /src/launcher/update/update.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ProffieConfig, All-In-One Proffieboard Management Utility 4 | * Copyright (C) 2024 Ryan Ogurek 5 | * 6 | * launcher/update/update.h 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace Update { 30 | 31 | enum ItemType { 32 | EXEC, 33 | LIB, 34 | COMP, 35 | RSRC, 36 | TYPE_MAX 37 | }; 38 | 39 | struct Version { 40 | Version() = default; 41 | 42 | /** 43 | * Construct a Version from a string. 44 | * 45 | * Uses the form: "[major](.[minor])(.[bugfix])(-[tag])". 46 | * - "-[tag]", minor, and bugfix are optional 47 | * - tag is a string unbroken by space 48 | * - major, minor, and bugfix are positive ints [0-255] 49 | */ 50 | Version(string_view str); 51 | 52 | static Version invalidObject(); 53 | 54 | uint8 major{0}; 55 | uint8 minor{0}; 56 | uint8 bugfix{0}; 57 | 58 | // Version is valid if `err == NONE` 59 | enum Err : uint8 { 60 | NONE, 61 | INVALID, 62 | NUM_RANGE, 63 | STR_INVALID, 64 | STR_EMPTY, 65 | } err{Err::NONE}; 66 | 67 | /** 68 | * Used for (optional) tagging of specialized versions. e.g 1.0.0-dev. 69 | * "dev" would be the tag. 70 | */ 71 | string tag; 72 | 73 | auto operator<=>(const Version&) const = default; 74 | 75 | /** 76 | * Convert a Version into string representation. 77 | * 78 | * If valid, it returns [major](.[minor])(.[bugfix])(-[tag]). 79 | * If invalid, it returns a string form of the `Err` 80 | */ 81 | operator string() const; 82 | operator bool() const; 83 | }; 84 | 85 | enum class Comparator { 86 | EQUAL, 87 | LESS_THAN, 88 | GREATER_THAN, 89 | }; 90 | 91 | struct ItemID { 92 | ItemType type; 93 | string name; 94 | bool ignored{false}; 95 | 96 | auto operator<=>(const ItemID&) const = default; 97 | }; 98 | 99 | struct ItemVersionData { 100 | string hash; 101 | 102 | vector fixes; 103 | vector changes; 104 | vector features; 105 | }; 106 | 107 | struct Item { 108 | string path; 109 | 110 | std::map versions; 111 | bool hidden; 112 | }; 113 | 114 | struct Bundle { 115 | string note; 116 | 117 | struct RequiredItem { 118 | RequiredItem(ItemID id, Version version, string hash = {}) : id{std::move(id)}, version{std::move(version)}, hash{std::move(hash)} {} 119 | 120 | ItemID id; 121 | Version version; 122 | string hash; 123 | }; 124 | vector reqs; 125 | }; 126 | 127 | using Items = std::map; 128 | using Bundles = std::map; 129 | 130 | struct Data { 131 | Items items; 132 | Bundles bundles; 133 | }; 134 | 135 | void init(); 136 | [[nodiscard]] wxEvtHandler *getEventHandler(); 137 | 138 | filepath typeFolder(ItemType); 139 | 140 | } // namespace Update 141 | 142 | -------------------------------------------------------------------------------- /src/proffieconfig/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ProffieConfig, All-In-One Proffieboard Management Utility! 2 | # 3 | # proffieconfig/CMakeLists.txt 4 | 5 | add_executable(proffieconfig WIN32 6 | main.cpp 7 | 8 | editor/dialogs/bladearraydlg.cpp 9 | editor/dialogs/customoptionsdlg.cpp 10 | editor/editorwindow.cpp 11 | editor/pages/propspage.cpp 12 | core/appstate.cpp 13 | core/utilities/misc.cpp 14 | core/utilities/progress.cpp 15 | core/config/configuration.cpp 16 | core/config/settings.cpp 17 | core/config/propfile.cpp 18 | editor/pages/generalpage.cpp 19 | editor/pages/presetspage.cpp 20 | editor/pages/bladespage.cpp 21 | mainmenu/dialogs/addconfig.cpp 22 | mainmenu/dialogs/props.cpp 23 | mainmenu/mainmenu.cpp 24 | onboard/onboard.cpp 25 | onboard/pages/dependencypage.cpp 26 | onboard/pages/overviewpage.cpp 27 | onboard/pages/welcomepage.cpp 28 | tools/arduino.cpp 29 | tools/serialmonitor.cpp 30 | ) 31 | 32 | set_target_properties(proffieconfig PROPERTIES 33 | OUTPUT_NAME "ProffieConfig" 34 | DESCRIPTION "ProffieConfig" # Windows is stupid so this isn't actually a description 35 | EXEC_VERSION "${CMAKE_PROJECT_VERSION}" 36 | ) 37 | 38 | target_link_libraries(proffieconfig 39 | wxWidgets 40 | 41 | app 42 | log 43 | ui 44 | utils 45 | pconf 46 | ) 47 | 48 | include (../Common.cmake) 49 | setup_target(proffieconfig) 50 | 51 | -------------------------------------------------------------------------------- /src/proffieconfig/core/appstate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // ProffieConfig, All-In-One GUI Proffieboard Configuration Utility 3 | // Copyright (C) 2025 Ryan Ogurek 4 | 5 | #include "utils/types.h" 6 | 7 | #include 8 | 9 | namespace AppState { 10 | 11 | void init(); 12 | 13 | [[nodiscard]] bool isSaved(); 14 | extern bool doneWithFirstRun; 15 | 16 | void setSaved(bool = true); 17 | void loadState(); 18 | void saveState(); 19 | 20 | void addProp(const string& propName, const string& propPath, const string& propConfigPath); 21 | void removeProp(const string& propName); 22 | 23 | const vector& getPropFileNames(); 24 | static constexpr array BUILTIN_PROPS{ 25 | "BC", 26 | "caiwyn", 27 | "fett263", 28 | "sa22c", 29 | "shtok", 30 | }; 31 | 32 | } // namespace AppState 33 | -------------------------------------------------------------------------------- /src/proffieconfig/core/config/configuration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // ProffieConfig, All-In-One GUI Proffieboard Configuration Utility 3 | // Copyright (C) 2025 Ryan Ogurek 4 | 5 | #include "../../editor/editorwindow.h" 6 | 7 | #include "log/branch.h" 8 | #include "utils/types.h" 9 | 10 | namespace Configuration { 11 | bool outputConfig(EditorWindow *editorWindow); 12 | 13 | /** 14 | * @param fullOutput output injection files 15 | */ 16 | bool outputConfig(const filepath&, EditorWindow *editorWindow, Log::Branch * = nullptr, bool fullOutput = false); 17 | bool exportConfig(EditorWindow *editorWindow); 18 | bool readConfig(const filepath&, EditorWindow *editorWindow); 19 | bool importConfig(EditorWindow *editorWindow); 20 | 21 | using MapPair = std::pair; 22 | using VMap = vector; 23 | const MapPair& findInVMap(const VMap&, const wxString& search); 24 | 25 | enum Orientation { 26 | ORIENTATION_FETS_TOWARDS_BLADE, 27 | ORIENTATION_USB_TOWARDS_BLADE, 28 | ORIENTATION_USB_CCW_FROM_BLADE, 29 | ORIENTATION_USB_CW_FROM_BLADE, 30 | ORIENTATION_TOP_TOWARDS_BLADE, 31 | ORIENTATION_BOTTOM_TOWARDS_BLADE, 32 | ORIENTATION_MAX, 33 | }; 34 | 35 | wxArrayString orientationStrings(); 36 | wxString orientToStr(Orientation); 37 | 38 | constexpr array ORIENT_CONFIG_STRINGS = { 39 | "ORIENTATION_FETS_TOWARDS_BLADE", 40 | "ORIENTATION_USB_TOWARDS_BLADE", 41 | "ORIENTATION_USB_CCW_FROM_BLADE", 42 | "ORIENTATION_USB_CW_FROM_BLADE", 43 | "ORIENTATION_TOP_TOWARDS_BLADE", 44 | "ORIENTATION_BOTTOM_TOWARDS_BLADE", 45 | }; 46 | 47 | const VMap PROFFIEBOARD = { 48 | { "Proffieboard V3", "#include \"proffieboard_v3_config.h\"" }, 49 | { "Proffieboard V2", "#include \"proffieboard_v2_config.h\"" }, 50 | { "Proffieboard V1", "#include \"proffieboard_v1_config.h\"" }, 51 | }; 52 | } // namespace Configuration 53 | -------------------------------------------------------------------------------- /src/proffieconfig/core/config/propfile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // ProffieConfig, All-In-One GUI Proffieboard Configuration Utility 3 | // Copyright (C) 2025 Ryan Ogurek 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "log/logger.h" 15 | #include "pconf/pconf.h" 16 | #include "utils/types.h" 17 | 18 | namespace std { 19 | 20 | template <> 21 | struct hash> { 22 | size_t operator()(const vector& vector) const { 23 | size_t hash = 0; 24 | for (const auto& string : vector) { 25 | hash ^= std::hash{}(string) + 0x9e3779b9 + (hash << 6) + (hash >> 2); 26 | } 27 | return hash; 28 | } 29 | }; 30 | 31 | } // namespace std 32 | 33 | class PropFile : public wxPanel { 34 | public: 35 | PropFile() = delete; 36 | ~PropFile() override; 37 | struct Setting; 38 | using SettingMap = std::unordered_map; 39 | struct Button; 40 | struct ButtonState { 41 | ButtonState(string stateName, vector