Multiple "scenes" for screen resize (#270)

## Link to GitHub Issue, if one exists
Fixes #263 

## Description of change
Add "scenes" to screen resize.

* UI changes - F11 menu now has a "scene switcher" for `Scene 1/2/3/4`.
Clean up other UI bits.
* Add hotkeys for `Screen Resize Scene 1`, `Screen Resize 2`, and so on.
* Detect hot key and trigger resizes.
* Add additional objects to screen_resize.json for saving and loading
the new scene settings.
* Existing screen resize data is backwards compatible (can be
loaded/saved to JSON), and is treated as `Scene 1`.
* Add API endpoint for `Resize`, allow toggling resize on/off, switching
active scene
* Add Python wrapper. Did not bother with the other wrappers (Dart, C++,
etc)...

## Compiling
🥇 

## Testing
Still testing, but seems to work fine for TDJ.
This commit is contained in:
bicarus-dev
2025-03-21 21:52:47 -07:00
committed by GitHub
parent e0dd371d61
commit b267ad09ac
15 changed files with 300 additions and 46 deletions
+2
View File
@@ -27,6 +27,7 @@
#include "modules/lights.h"
#include "modules/memory.h"
#include "modules/touch.h"
#include "modules/resize.h"
#include "request.h"
#include "response.h"
@@ -403,6 +404,7 @@ void Controller::init_state(api::ClientState *state) {
state->modules.push_back(new modules::Lights());
state->modules.push_back(new modules::Memory());
state->modules.push_back(new modules::Touch());
state->modules.push_back(new modules::Resize());
}
void Controller::free_state(api::ClientState *state) {
+53
View File
@@ -0,0 +1,53 @@
#include "resize.h"
#include "external/rapidjson/document.h"
#include "cfg/screen_resize.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
static thread_local std::vector<uint8_t> CAPTURE_BUFFER;
Resize::Resize() : Module("resize") {
functions["image_resize_enable"] = std::bind(&Resize::image_resize_enable, this, _1, _2);
functions["image_resize_set_scene"] = std::bind(&Resize::image_resize_set_scene, this, _1, _2);
}
/**
* image_resize_enable(enable: bool)
*/
void Resize::image_resize_enable(Request &req, Response &res) {
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsBool()) {
return error_type(res, "enable", "bool");
}
cfg::SCREENRESIZE->enable_screen_resize = req.params[0].GetBool();
}
/**
* image_resize_set_scene(scene: int)
*/
void Resize::image_resize_set_scene(Request &req, Response &res) {
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsInt()) {
return error_type(res, "scene", "int");
}
const auto scene = req.params[0].GetInt();
if (scene < 0 || (int)std::size(cfg::SCREENRESIZE->scene_settings) < scene) {
return error(res, "invalid scene number");
}
if (scene == 0) {
cfg::SCREENRESIZE->enable_screen_resize = false;
} else {
cfg::SCREENRESIZE->enable_screen_resize = true;
cfg::SCREENRESIZE->screen_resize_current_scene = scene - 1;
}
}
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Resize : public Module {
public:
Resize();
private:
// function definitions
void image_resize_enable(Request &req, Response &res);
void image_resize_set_scene(Request &req, Response &res);
};
}
@@ -12,3 +12,4 @@ from .keypads import *
from .lights import *
from .memory import *
from .touch import *
from .resize import *
@@ -0,0 +1,12 @@
from .connection import Connection
from .request import Request
def image_resize_enable(con: Connection, enable: bool):
req = Request("resize", "image_resize_enable")
req.add_param(enable)
con.request(req)
def image_resize_set_scene(con: Connection, scene: int):
req = Request("resize", "image_resize_set_scene")
req.add_param(scene)
con.request(req)
@@ -397,6 +397,65 @@ class LightsTab(ttk.Frame):
# set text
self.txt_lights.set_text(txt)
class ResizeTab(ttk.Frame):
"""Resize tab."""
def __init__(self, app, parent, **kwargs):
# init frame
ttk.Frame.__init__(self, parent, **kwargs)
self.app = app
self.parent = parent
# scale grid
self.columnconfigure(0, weight=1)
# image resize
self.resize = ttk.Frame(self, padding=(8, 8, 8, 8))
self.resize.grid(row=0, column=0, sticky=tk.E+tk.W)
self.resize.columnconfigure(0, weight=1)
self.resize.columnconfigure(1, weight=1)
self.resize_lbl = ttk.Label(self.resize, text="Image Resize")
self.resize_lbl.grid(row=0, columnspan=2)
self.resize_off = ttk.Button(self.resize, text="Disable", command=self.action_resize_false)
self.resize_off.grid(row=2, column=0, sticky=NSEW, padx=2, pady=2)
self.resize_on = ttk.Button(self.resize, text="Enable", command=self.action_resize_on)
self.resize_on.grid(row=2, column=1, sticky=NSEW, padx=2, pady=2)
self.resize_scene_1 = ttk.Button(self.resize, text="Scene 1", command=self.action_resize_scene_1)
self.resize_scene_1.grid(row=3, column=0, sticky=NSEW, padx=2, pady=2)
self.resize_scene_2 = ttk.Button(self.resize, text="Scene 2", command=self.action_resize_scene_2)
self.resize_scene_2.grid(row=3, column=1, sticky=NSEW, padx=2, pady=2)
self.resize_scene_3 = ttk.Button(self.resize, text="Scene 3", command=self.action_resize_scene_3)
self.resize_scene_3.grid(row=4, column=0, sticky=NSEW, padx=2, pady=2)
self.resize_scene_4 = ttk.Button(self.resize, text="Scene 4", command=self.action_resize_scene_4)
self.resize_scene_4.grid(row=4, column=1, sticky=NSEW, padx=2, pady=2)
@api_action
def action_resize_on(self):
spiceapi.image_resize_enable(self.app.connection, True)
@api_action
def action_resize_false(self):
spiceapi.image_resize_enable(self.app.connection, False)
@api_action
def action_resize_scene_1(self):
spiceapi.image_resize_set_scene(self.app.connection, 1)
@api_action
def action_resize_scene_2(self):
spiceapi.image_resize_set_scene(self.app.connection, 2)
@api_action
def action_resize_scene_3(self):
spiceapi.image_resize_set_scene(self.app.connection, 3)
@api_action
def action_resize_scene_4(self):
spiceapi.image_resize_set_scene(self.app.connection, 4)
class MainApp(ttk.Frame):
"""The main application frame."""
@@ -419,6 +478,8 @@ class MainApp(ttk.Frame):
self.tabs.add(self.tab_analogs, text="Analogs")
self.tab_lights = LightsTab(self, self.tabs)
self.tabs.add(self.tab_lights, text="Lights")
self.tab_resize = ResizeTab(self, self.tabs)
self.tabs.add(self.tab_resize, text="Resize")
self.tab_manual = ManualTab(self, self.tabs)
self.tabs.add(self.tab_manual, text="Manual")
self.tabs.pack(expand=True, fill=tk.BOTH)