You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
494 lines
14 KiB
494 lines
14 KiB
2 years ago
|
/*
|
||
|
* EEZ Modular Firmware
|
||
|
* Copyright (C) 2015-present, Envox d.o.o.
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <eez/gui/data.h>
|
||
|
#include <eez/gui/widget.h>
|
||
|
|
||
|
namespace eez {
|
||
|
namespace gui {
|
||
|
|
||
|
static const uint32_t HEADER_TAG = 0x7A65657E;
|
||
|
|
||
|
static const uint8_t PROJECT_VERSION_V2 = 2;
|
||
|
static const uint8_t PROJECT_VERSION_V3 = 3;
|
||
|
|
||
|
static const uint8_t ASSETS_TYPE_FIRMWARE = 1;
|
||
|
static const uint8_t ASSETS_TYPE_FIRMWARE_MODULE = 2;
|
||
|
static const uint8_t ASSETS_TYPE_RESOURCE = 3;
|
||
|
static const uint8_t ASSETS_TYPE_APPLET = 4;
|
||
|
static const uint8_t ASSETS_TYPE_DASHBOARD = 5;
|
||
|
|
||
|
struct Header {
|
||
|
uint32_t tag; // HEADER_TAG
|
||
|
uint8_t projectMajorVersion;
|
||
|
uint8_t projectMinorVersion;
|
||
|
uint8_t assetsType;
|
||
|
uint8_t reserved;
|
||
|
uint32_t decompressedSize;
|
||
|
};
|
||
|
|
||
|
extern bool g_isMainAssetsLoaded;
|
||
|
extern Assets *g_mainAssets;
|
||
|
extern Assets *g_externalAssets;
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
/* This template is used (on 64-bit systems) to pack asset pointers into 32-bit values.
|
||
|
* All pointers are relative to MEMORY_BEGIN.
|
||
|
* This way, the assets created by Studio can be used without having to fix all
|
||
|
* the sizes - Studio creates 32-bit pointers that are relative to the
|
||
|
* beginning of the assets, which the firmware rewrites to global pointers
|
||
|
* during initialization. On a 32-bit system this works just fine, but for a
|
||
|
* 64-bit system the pointers have different sizes and this breaks. By
|
||
|
* inserting a 'middleman' structure that stores the pointers as a 32-bit
|
||
|
* offset to MEMORY_BEGIN, we can keep the pointer sizes and initialization
|
||
|
* code the same.
|
||
|
*/
|
||
|
template<typename T>
|
||
|
struct AssetsPtrImpl {
|
||
|
/* Conversion to a T pointer */
|
||
|
operator T*() { return ptr(); }
|
||
|
operator const T*() const { return ptr(); }
|
||
|
/* Dereferencing operators */
|
||
|
T* operator->() { return ptr(); }
|
||
|
const T* operator->() const { return ptr(); }
|
||
|
|
||
|
void operator=(T* ptr) {
|
||
|
if (ptr != nullptr) {
|
||
|
offset = (uint8_t *)ptr - MEMORY_BEGIN;
|
||
|
} else {
|
||
|
offset = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint32_t offset = 0;
|
||
|
|
||
|
private:
|
||
|
T* ptr() {
|
||
|
return offset ? (T *)(MEMORY_BEGIN + offset) : nullptr;
|
||
|
}
|
||
|
|
||
|
const T* ptr() const {
|
||
|
return offset ? (const T *)(MEMORY_BEGIN + offset) : nullptr;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/* This struct chooses the type used for AssetsPtr<T> - by default it uses an AssetsPtrImpl<> */
|
||
|
template<typename T, uint32_t ptrSize>
|
||
|
struct AssetsPtrChooser
|
||
|
{
|
||
|
using type = AssetsPtrImpl<T>;
|
||
|
};
|
||
|
|
||
|
/* On 32-bit systems, we can just use raw pointers */
|
||
|
template<typename T>
|
||
|
struct AssetsPtrChooser<T, 4>
|
||
|
{
|
||
|
using type = T*;
|
||
|
};
|
||
|
|
||
|
/* Utility typedef that delegates to AssetsPtrChooser */
|
||
|
template<typename T>
|
||
|
using AssetsPtr = typename AssetsPtrChooser<T, sizeof(void*)>::type;
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template<typename T>
|
||
|
struct ListOfAssetsPtr {
|
||
|
/* Array access */
|
||
|
T* operator[](uint32_t i) { return item(i); }
|
||
|
const T* operator[](uint32_t i) const { return item(i); }
|
||
|
|
||
|
uint32_t count = 0;
|
||
|
AssetsPtr<AssetsPtr<T>> items;
|
||
|
|
||
|
private:
|
||
|
T* item(int i) {
|
||
|
return static_cast<T *>(static_cast<AssetsPtr<T> *>(items)[i]);
|
||
|
}
|
||
|
|
||
|
const T* item(int i) const {
|
||
|
return static_cast<const T *>(static_cast<const AssetsPtr<T> *>(items)[i]);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct ListOfFundamentalType {
|
||
|
/* Array access */
|
||
|
T& operator[](uint32_t i) { return ptr()[i]; }
|
||
|
const T& operator[](uint32_t i) const { return ptr()[i]; }
|
||
|
|
||
|
uint32_t count;
|
||
|
AssetsPtr<T> items;
|
||
|
|
||
|
private:
|
||
|
T *ptr() {
|
||
|
return static_cast<T *>(items);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct Settings {
|
||
|
uint16_t displayWidth;
|
||
|
uint16_t displayHeight;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#define WIDGET_FLAG_PIN_TO_LEFT (1 << 0)
|
||
|
#define WIDGET_FLAG_PIN_TO_RIGHT (1 << 1)
|
||
|
#define WIDGET_FLAG_PIN_TO_TOP (1 << 2)
|
||
|
#define WIDGET_FLAG_PIN_TO_BOTTOM (1 << 3)
|
||
|
|
||
|
#define WIDGET_FLAG_FIX_WIDTH (1 << 4)
|
||
|
#define WIDGET_FLAG_FIX_HEIGHT (1 << 5)
|
||
|
|
||
|
#define WIDGET_TIMELINE_PROPERTY_X (1 << 0)
|
||
|
#define WIDGET_TIMELINE_PROPERTY_Y (1 << 1)
|
||
|
#define WIDGET_TIMELINE_PROPERTY_WIDTH (1 << 2)
|
||
|
#define WIDGET_TIMELINE_PROPERTY_HEIGHT (1 << 3)
|
||
|
#define WIDGET_TIMELINE_PROPERTY_OPACITY (1 << 4)
|
||
|
|
||
|
#define EASING_FUNC_LINEAR 0
|
||
|
#define EASING_FUNC_IN_QUAD 1
|
||
|
#define EASING_FUNC_OUT_QUAD 2
|
||
|
#define EASING_FUNC_IN_OUT_QUAD 3
|
||
|
#define EASING_FUNC_IN_CUBIC 4
|
||
|
#define EASING_FUNC_OUT_CUBIC 5
|
||
|
#define EASING_FUNC_IN_OUT_CUBIC 6
|
||
|
#define EASING_FUNC_IN__QUART 7
|
||
|
#define EASING_FUNC_OUT_QUART 8
|
||
|
#define EASING_FUNC_IN_OUT_QUART 9
|
||
|
#define EASING_FUNC_IN_QUINT 10
|
||
|
#define EASING_FUNC_OUT_QUINT 11
|
||
|
#define EASING_FUNC_IN_OUT_QUINT 12
|
||
|
#define EASING_FUNC_IN_SINE 13
|
||
|
#define EASING_FUNC_OUT_SINE 14
|
||
|
#define EASING_FUNC_IN_OUT_SINE 15
|
||
|
#define EASING_FUNC_IN_EXPO 16
|
||
|
#define EASING_FUNC_OUT_EXPO 17
|
||
|
#define EASING_FUNC_IN_OUT_EXPO 18
|
||
|
#define EASING_FUNC_IN_CIRC 19
|
||
|
#define EASING_FUNC_OUT_CIRC 20
|
||
|
#define EASING_FUNC_IN_OUT_CIRC 21
|
||
|
#define EASING_FUNC_IN_BACK 22
|
||
|
#define EASING_FUNC_OUT_BACK 23
|
||
|
#define EASING_FUNC_IN_OUT_BACK 24
|
||
|
#define EASING_FUNC_IN_ELASTIC 25
|
||
|
#define EASING_FUNC_OUT_ELASTIC 26
|
||
|
#define EASING_FUNC_IN_OUT_ELASTIC 27
|
||
|
#define EASING_FUNC_IN_BOUNCE 28
|
||
|
#define EASING_FUNC_OUT_BOUNCE 29
|
||
|
#define EASING_FUNC_IN_OUT_BOUNCE 30
|
||
|
|
||
|
struct TimelineKeyframe {
|
||
|
float start;
|
||
|
float end;
|
||
|
|
||
|
uint32_t enabledProperties;
|
||
|
|
||
|
int16_t x;
|
||
|
int16_t y;
|
||
|
int16_t width;
|
||
|
int16_t height;
|
||
|
float opacity;
|
||
|
|
||
|
uint8_t xEasingFunc;
|
||
|
uint8_t yEasingFunc;
|
||
|
uint8_t widthEasingFunc;
|
||
|
uint8_t heightEasingFunc;
|
||
|
uint8_t opacityEasingFunc;
|
||
|
|
||
|
uint8_t reserved1;
|
||
|
uint8_t reserved2;
|
||
|
uint8_t reserved3;
|
||
|
};
|
||
|
|
||
|
struct Widget {
|
||
|
uint16_t type;
|
||
|
int16_t data;
|
||
|
int16_t visible;
|
||
|
int16_t action;
|
||
|
int16_t x;
|
||
|
int16_t y;
|
||
|
int16_t width;
|
||
|
int16_t height;
|
||
|
int16_t style;
|
||
|
uint16_t flags;
|
||
|
ListOfAssetsPtr<TimelineKeyframe> timeline;
|
||
|
};
|
||
|
|
||
|
#define SHADOW_FLAG (1 << 0)
|
||
|
#define CLOSE_PAGE_IF_TOUCHED_OUTSIDE_FLAG (1 << 1)
|
||
|
#define PAGE_IS_USED_AS_CUSTOM_WIDGET (1 << 2)
|
||
|
#define PAGE_CONTAINER (1 << 3)
|
||
|
#define PAGE_SCALE_TO_FIT (1 << 4)
|
||
|
|
||
|
struct PageAsset : public Widget {
|
||
|
ListOfAssetsPtr<Widget> widgets;
|
||
|
uint16_t flags;
|
||
|
int16_t overlay;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#define STYLE_FLAGS_HORZ_ALIGN_MASK 0x7
|
||
|
#define STYLE_FLAGS_HORZ_ALIGN_LEFT 0
|
||
|
#define STYLE_FLAGS_HORZ_ALIGN_RIGHT 1
|
||
|
#define STYLE_FLAGS_HORZ_ALIGN_CENTER 2
|
||
|
|
||
|
#define STYLE_FLAGS_VERT_ALIGN_MASK (0x7 << 3)
|
||
|
#define STYLE_FLAGS_VERT_ALIGN_TOP (0 << 3)
|
||
|
#define STYLE_FLAGS_VERT_ALIGN_BOTTOM (1 << 3)
|
||
|
#define STYLE_FLAGS_VERT_ALIGN_CENTER (2 << 3)
|
||
|
|
||
|
#define STYLE_FLAGS_BLINK (1 << 6)
|
||
|
|
||
|
struct Style {
|
||
|
uint16_t flags; // STYLE_FLAGS_...
|
||
|
|
||
|
uint16_t backgroundColor;
|
||
|
uint16_t color;
|
||
|
|
||
|
uint16_t activeBackgroundColor;
|
||
|
uint16_t activeColor;
|
||
|
|
||
|
uint16_t focusBackgroundColor;
|
||
|
uint16_t focusColor;
|
||
|
|
||
|
uint8_t borderSizeTop;
|
||
|
uint8_t borderSizeRight;
|
||
|
uint8_t borderSizeBottom;
|
||
|
uint8_t borderSizeLeft;
|
||
|
|
||
|
uint16_t borderColor;
|
||
|
|
||
|
uint8_t borderRadiusTLX;
|
||
|
uint8_t borderRadiusTLY;
|
||
|
uint8_t borderRadiusTRX;
|
||
|
uint8_t borderRadiusTRY;
|
||
|
uint8_t borderRadiusBLX;
|
||
|
uint8_t borderRadiusBLY;
|
||
|
uint8_t borderRadiusBRX;
|
||
|
uint8_t borderRadiusBRY;
|
||
|
|
||
|
uint8_t font;
|
||
|
uint8_t opacity; // 0 - 255
|
||
|
|
||
|
uint8_t paddingTop;
|
||
|
uint8_t paddingRight;
|
||
|
uint8_t paddingBottom;
|
||
|
uint8_t paddingLeft;
|
||
|
|
||
|
int16_t backgroundImage;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct GlyphData {
|
||
|
int8_t dx; // DWIDTH (-128 indicated empty glyph)
|
||
|
uint8_t width; // BBX width
|
||
|
uint8_t height; // BBX height
|
||
|
int8_t x; // BBX xoffset
|
||
|
int8_t y; // BBX yoffset
|
||
|
uint8_t reserved1;
|
||
|
uint8_t reserved2;
|
||
|
uint8_t reserved3;
|
||
|
uint8_t pixels[1];
|
||
|
};
|
||
|
|
||
|
struct GlyphsGroup {
|
||
|
uint32_t encoding;
|
||
|
uint32_t glyphIndex;
|
||
|
uint32_t length;
|
||
|
};
|
||
|
|
||
|
struct FontData {
|
||
|
uint8_t ascent;
|
||
|
uint8_t descent;
|
||
|
uint8_t reserved1;
|
||
|
uint8_t reserved2;
|
||
|
uint32_t encodingStart;
|
||
|
uint32_t encodingEnd;
|
||
|
ListOfAssetsPtr<GlyphsGroup> groups;
|
||
|
ListOfAssetsPtr<GlyphData> glyphs;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct Bitmap {
|
||
|
int16_t w;
|
||
|
int16_t h;
|
||
|
int16_t bpp;
|
||
|
int16_t reserved;
|
||
|
const uint8_t pixels[1];
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct Theme {
|
||
|
AssetsPtr<const char> name;
|
||
|
ListOfFundamentalType<uint16_t> colors;
|
||
|
};
|
||
|
|
||
|
struct Colors {
|
||
|
ListOfAssetsPtr<Theme> themes;
|
||
|
ListOfFundamentalType<uint16_t> colors;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_MASK = 0x0007 << 13;
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_PARAM_MASK = 0xFFFF >> 3;
|
||
|
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_CONSTANT = (0 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_INPUT = (1 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_LOCAL_VAR = (2 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_GLOBAL_VAR = (3 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_OUTPUT = (4 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_ARRAY_ELEMENT = (5 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_OPERATION = (6 << 13);
|
||
|
static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_END = (7 << 13);
|
||
|
|
||
|
struct Property {
|
||
|
uint8_t evalInstructions[1];
|
||
|
};
|
||
|
|
||
|
struct Connection {
|
||
|
uint16_t targetComponentIndex;
|
||
|
uint16_t targetInputIndex;
|
||
|
};
|
||
|
|
||
|
struct ComponentOutput {
|
||
|
ListOfAssetsPtr<Connection> connections;
|
||
|
uint32_t isSeqOut;
|
||
|
};
|
||
|
|
||
|
static const uint16_t BREAKPOINT_ENABLED = 1;
|
||
|
static const uint16_t BREAKPOINT_DISABLED = 2;
|
||
|
|
||
|
struct Component {
|
||
|
uint16_t type;
|
||
|
uint16_t breakpoint;
|
||
|
|
||
|
// These are indexes to Flow::componentInputs.
|
||
|
// We use this to check if component is ready to run (i.e. all mandatory inputs have a value).
|
||
|
ListOfFundamentalType<uint16_t> inputs;
|
||
|
|
||
|
ListOfAssetsPtr<Property> properties;
|
||
|
ListOfAssetsPtr<ComponentOutput> outputs;
|
||
|
int16_t errorCatchOutput;
|
||
|
uint16_t reserved;
|
||
|
};
|
||
|
|
||
|
struct WidgetDataItem {
|
||
|
int16_t componentIndex;
|
||
|
int16_t propertyValueIndex;
|
||
|
};
|
||
|
|
||
|
struct WidgetActionItem {
|
||
|
int16_t componentIndex;
|
||
|
int16_t componentOutputIndex;
|
||
|
};
|
||
|
|
||
|
#define COMPONENT_INPUT_FLAG_IS_SEQ_INPUT (1 << 0)
|
||
|
#define COMPONENT_INPUT_FLAG_IS_OPTIONAL (1 << 1)
|
||
|
typedef uint8_t ComponentInput;
|
||
|
|
||
|
struct Flow {
|
||
|
ListOfAssetsPtr<Component> components;
|
||
|
ListOfAssetsPtr<Value> localVariables;
|
||
|
|
||
|
// List of all component inputs of all components in this flow
|
||
|
// When flow state is created we reserve this many Value's in memory
|
||
|
// to keep the latest value of component input.
|
||
|
ListOfFundamentalType<ComponentInput> componentInputs;
|
||
|
|
||
|
ListOfAssetsPtr<WidgetDataItem> widgetDataItems;
|
||
|
ListOfAssetsPtr<WidgetActionItem> widgetActions;
|
||
|
};
|
||
|
|
||
|
struct FlowDefinition {
|
||
|
ListOfAssetsPtr<Flow> flows;
|
||
|
ListOfAssetsPtr<Value> constants;
|
||
|
ListOfAssetsPtr<Value> globalVariables;
|
||
|
};
|
||
|
|
||
|
struct Language {
|
||
|
AssetsPtr<const char> languageID;
|
||
|
ListOfAssetsPtr<const char> translations;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct Assets {
|
||
|
uint8_t projectMajorVersion;
|
||
|
uint8_t projectMinorVersion;
|
||
|
uint8_t assetsType;
|
||
|
uint8_t external;
|
||
|
|
||
|
AssetsPtr<Settings> settings;
|
||
|
ListOfAssetsPtr<PageAsset> pages;
|
||
|
ListOfAssetsPtr<Style> styles;
|
||
|
ListOfAssetsPtr<FontData> fonts;
|
||
|
ListOfAssetsPtr<Bitmap> bitmaps;
|
||
|
AssetsPtr<Colors> colorsDefinition;
|
||
|
ListOfAssetsPtr<const char> actionNames;
|
||
|
ListOfAssetsPtr<const char> variableNames;
|
||
|
AssetsPtr<FlowDefinition> flowDefinition;
|
||
|
ListOfAssetsPtr<Language> languages;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
bool decompressAssetsData(const uint8_t *assetsData, uint32_t assetsDataSize, Assets *decompressedAssets, uint32_t maxDecompressedAssetsSize, int *err);
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void loadMainAssets(const uint8_t *assets, uint32_t assetsSize);
|
||
|
bool loadExternalAssets(const char *filePath, int *err);
|
||
|
void unloadExternalAssets();
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
const PageAsset *getPageAsset(int pageId);
|
||
|
const PageAsset* getPageAsset(int pageId, WidgetCursor& widgetCursor);
|
||
|
|
||
|
const Style *getStyle(int styleID);
|
||
|
const FontData *getFontData(int fontID);
|
||
|
const Bitmap *getBitmap(int bitmapID);
|
||
|
|
||
|
int getThemesCount();
|
||
|
const char *getThemeName(int i);
|
||
|
const uint32_t getThemeColorsCount(int themeIndex);
|
||
|
const uint16_t *getThemeColors(int themeIndex);
|
||
|
const uint16_t *getColors();
|
||
|
|
||
|
int getExternalAssetsMainPageId();
|
||
|
|
||
|
const char *getActionName(const WidgetCursor &widgetCursor, int16_t actionId);
|
||
|
int16_t getDataIdFromName(const WidgetCursor &widgetCursor, const char *name);
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
} // namespace gui
|
||
|
} // namespace eez
|