mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2025-10-05 11:58:44 +02:00
JS: Expose button event type in gui/widget button callback --nobuild
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
- Sub-GHz:
|
- Sub-GHz:
|
||||||
- UL: Add 868.46 MHz to default subghz freqs list (by @xMasterX)
|
- UL: Add 868.46 MHz to default subghz freqs list (by @xMasterX)
|
||||||
- UL: Reduce less popular freqs in default hopper preset, make it faster (by @xMasterX)
|
- UL: Reduce less popular freqs in default hopper preset, make it faster (by @xMasterX)
|
||||||
|
- JS: Expose button event type in `gui/widget` button callback (by @WillyJL)
|
||||||
- UL: Docs: Update Sub-GHz DoorHan programming instructions (by @li0ard)
|
- UL: Docs: Update Sub-GHz DoorHan programming instructions (by @li0ard)
|
||||||
|
|
||||||
### Fixed:
|
### Fixed:
|
||||||
|
@@ -137,8 +137,8 @@ eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, gui, views
|
|||||||
}, gui, views, eventLoop);
|
}, gui, views, eventLoop);
|
||||||
|
|
||||||
// go to the demo chooser screen when the right key is pressed on the widget screen
|
// go to the demo chooser screen when the right key is pressed on the widget screen
|
||||||
eventLoop.subscribe(views.stopwatchWidget.button, function (_sub, buttonId, gui, views) {
|
eventLoop.subscribe(views.stopwatchWidget.button, function (_sub, buttonEvent, gui, views) {
|
||||||
if (buttonId === "right")
|
if (buttonEvent.key === "right" && buttonEvent.type === "short")
|
||||||
gui.viewDispatcher.switchTo(views.demos);
|
gui.viewDispatcher.switchTo(views.demos);
|
||||||
}, gui, views);
|
}, gui, views);
|
||||||
|
|
||||||
|
@@ -10,6 +10,11 @@ typedef struct {
|
|||||||
|
|
||||||
#define QUEUE_LEN 2
|
#define QUEUE_LEN 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GuiButtonType key;
|
||||||
|
InputType type;
|
||||||
|
} JsWidgetButtonEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parses position (X and Y) from an element declaration object
|
* @brief Parses position (X and Y) from an element declaration object
|
||||||
*/
|
*/
|
||||||
@@ -101,8 +106,11 @@ static bool element_get_text(struct mjs* mjs, mjs_val_t element, mjs_val_t* text
|
|||||||
* @brief Widget button element callback
|
* @brief Widget button element callback
|
||||||
*/
|
*/
|
||||||
static void js_widget_button_callback(GuiButtonType result, InputType type, JsWidgetCtx* context) {
|
static void js_widget_button_callback(GuiButtonType result, InputType type, JsWidgetCtx* context) {
|
||||||
UNUSED(type);
|
JsWidgetButtonEvent event = {
|
||||||
furi_check(furi_message_queue_put(context->queue, &result, 0) == FuriStatusOk);
|
.key = result,
|
||||||
|
.type = type,
|
||||||
|
};
|
||||||
|
furi_check(furi_message_queue_put(context->queue, &event, 0) == FuriStatusOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DESTRUCTURE_OR_RETURN(mjs, child_obj, part, ...) \
|
#define DESTRUCTURE_OR_RETURN(mjs, child_obj, part, ...) \
|
||||||
@@ -263,25 +271,44 @@ static mjs_val_t js_widget_button_event_transformer(
|
|||||||
FuriMessageQueue* queue,
|
FuriMessageQueue* queue,
|
||||||
JsWidgetCtx* context) {
|
JsWidgetCtx* context) {
|
||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
GuiButtonType btn_type;
|
JsWidgetButtonEvent event;
|
||||||
furi_check(furi_message_queue_get(queue, &btn_type, 0) == FuriStatusOk);
|
furi_check(furi_message_queue_get(queue, &event, 0) == FuriStatusOk);
|
||||||
const char* btn_name;
|
const char* event_key;
|
||||||
if(btn_type == GuiButtonTypeLeft) {
|
if(event.key == GuiButtonTypeLeft) {
|
||||||
btn_name = "left";
|
event_key = "left";
|
||||||
} else if(btn_type == GuiButtonTypeCenter) {
|
} else if(event.key == GuiButtonTypeCenter) {
|
||||||
btn_name = "center";
|
event_key = "center";
|
||||||
} else if(btn_type == GuiButtonTypeRight) {
|
} else if(event.key == GuiButtonTypeRight) {
|
||||||
btn_name = "right";
|
event_key = "right";
|
||||||
} else {
|
} else {
|
||||||
furi_crash();
|
furi_crash();
|
||||||
}
|
}
|
||||||
return mjs_mk_string(mjs, btn_name, ~0, false);
|
const char* event_type;
|
||||||
|
if(event.type == InputTypePress) {
|
||||||
|
event_type = "press";
|
||||||
|
} else if(event.type == InputTypeRelease) {
|
||||||
|
event_type = "release";
|
||||||
|
} else if(event.type == InputTypeShort) {
|
||||||
|
event_type = "short";
|
||||||
|
} else if(event.type == InputTypeLong) {
|
||||||
|
event_type = "long";
|
||||||
|
} else if(event.type == InputTypeRepeat) {
|
||||||
|
event_type = "repeat";
|
||||||
|
} else {
|
||||||
|
furi_crash();
|
||||||
|
}
|
||||||
|
mjs_val_t obj = mjs_mk_object(mjs);
|
||||||
|
JS_ASSIGN_MULTI(mjs, obj) {
|
||||||
|
JS_FIELD("key", mjs_mk_string(mjs, event_key, ~0, true));
|
||||||
|
JS_FIELD("type", mjs_mk_string(mjs, event_type, ~0, true));
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* js_widget_custom_make(struct mjs* mjs, Widget* widget, mjs_val_t view_obj) {
|
static void* js_widget_custom_make(struct mjs* mjs, Widget* widget, mjs_val_t view_obj) {
|
||||||
UNUSED(widget);
|
UNUSED(widget);
|
||||||
JsWidgetCtx* context = malloc(sizeof(JsWidgetCtx));
|
JsWidgetCtx* context = malloc(sizeof(JsWidgetCtx));
|
||||||
context->queue = furi_message_queue_alloc(QUEUE_LEN, sizeof(GuiButtonType));
|
context->queue = furi_message_queue_alloc(QUEUE_LEN, sizeof(JsWidgetButtonEvent));
|
||||||
context->contract = (JsEventLoopContract){
|
context->contract = (JsEventLoopContract){
|
||||||
.magic = JsForeignMagic_JsEventLoopContract,
|
.magic = JsForeignMagic_JsEventLoopContract,
|
||||||
.object_type = JsEventLoopObjectTypeQueue,
|
.object_type = JsEventLoopObjectTypeQueue,
|
||||||
|
@@ -58,12 +58,16 @@ type Element = StringMultilineElement
|
|||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
type Child = Element;
|
type Child = Element;
|
||||||
|
declare class ButtonEvent {
|
||||||
|
key: "left" | "center" | "right";
|
||||||
|
type: "press" | "release" | "short" | "long" | "repeat";
|
||||||
|
}
|
||||||
declare class Widget extends View<Props, Child> {
|
declare class Widget extends View<Props, Child> {
|
||||||
/**
|
/**
|
||||||
* Event source for buttons. Only gets fired if there's a corresponding
|
* Event source for buttons. Only gets fired if there's a corresponding
|
||||||
* button element.
|
* button element.
|
||||||
*/
|
*/
|
||||||
button: Contract<"left" | "center" | "right">;
|
button: Contract<ButtonEvent>;
|
||||||
}
|
}
|
||||||
declare class WidgetFactory extends ViewFactory<Props, Child, Widget> { }
|
declare class WidgetFactory extends ViewFactory<Props, Child, Widget> { }
|
||||||
declare const factory: WidgetFactory;
|
declare const factory: WidgetFactory;
|
||||||
|
@@ -35,3 +35,20 @@ Elements are objects with properties to define them, in the form `{ element: "ty
|
|||||||
| `rect` | `x` (number), `y` (number) <br> `w` (number), `h` (number) <br> `radius` (number), `fill` (boolean) | Draw a rectangle, optionally rounded and filled. |
|
| `rect` | `x` (number), `y` (number) <br> `w` (number), `h` (number) <br> `radius` (number), `fill` (boolean) | Draw a rectangle, optionally rounded and filled. |
|
||||||
| `circle` | `x` (number), `y` (number) <br> `radius` (number), `fill` (boolean) | Draw a circle, optionally filled. |
|
| `circle` | `x` (number), `y` (number) <br> `radius` (number), `fill` (boolean) | Draw a circle, optionally filled. |
|
||||||
| `line` | `x1` (number), `y1` (number) <br> `x2` (number), `y2` (number) | Draw a line between 2 points. |
|
| `line` | `x1` (number), `y1` (number) <br> `x2` (number), `y2` (number) | Draw a line between 2 points. |
|
||||||
|
|
||||||
|
## Structures
|
||||||
|
|
||||||
|
### ButtonEvent
|
||||||
|
|
||||||
|
Button event information structure.
|
||||||
|
|
||||||
|
**Fields**
|
||||||
|
|
||||||
|
- key: The key that was pressed (`"left" | "center" | "right"`)
|
||||||
|
- type: The type of the event (`"press" | "release" | "short" | "long" | "repeat"`)
|
||||||
|
|
||||||
|
## View events
|
||||||
|
|
||||||
|
| Item | Type | Description |
|
||||||
|
|----------|--------|-----------------------------------------------------------------------------|
|
||||||
|
| `button` | `ButtonEvent`| Fires when the user presses on one of the three possible buttons if there's a corresponding button element. Refer to the `ButtonEvent` structure above for possible values. |
|
||||||
|
Reference in New Issue
Block a user