Skip to content

Commit

Permalink
implemented basic desktop
Browse files Browse the repository at this point in the history
  • Loading branch information
KenVanHoeylandt committed Jan 3, 2024
1 parent f6c547a commit 48d2fd6
Show file tree
Hide file tree
Showing 19 changed files with 245 additions and 223 deletions.
7 changes: 6 additions & 1 deletion components/furi/src/app_manifest.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ typedef struct _lv_obj_t lv_obj_t;
typedef enum {
AppTypeService,
AppTypeSystem,
AppTypeDesktop,
AppTypeUser
} AppType;

typedef enum {
AppStackSizeNormal = 2048
AppStackSizeTiny = 512,
AppStackSizeSmall = 1024,
AppStackSizeNormal = 2048,
AppStackSizeLarge = 4096,
AppStackSizeHuge = 8192,
} AppStackSize;

typedef void (*AppOnStart)(void _Nonnull* parameter);
Expand Down
8 changes: 4 additions & 4 deletions components/furi/src/app_manifest_registry.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ const AppManifest _Nullable* app_manifest_registry_find_by_id(const char* id) {
return (manifest != NULL) ? *manifest : NULL;
}

void app_manifest_registry_for_each_of_type(AppType type, AppManifestCallback callback) {
void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback) {
APP_REGISTRY_FOR_EACH(manifest, {
if (manifest->type == type) {
callback(manifest);
callback(manifest, context);
}
});
}

void app_manifest_registry_for_each(AppManifestCallback callback) {
void app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context) {
APP_REGISTRY_FOR_EACH(manifest, {
callback(manifest);
callback(manifest, context);
});
}
6 changes: 3 additions & 3 deletions components/furi/src/app_manifest_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ extern "C" {
extern const AppManifest* const INTERNAL_APP_MANIFESTS[];
extern const size_t INTERNAL_APP_COUNT;

typedef void (*AppManifestCallback)(const AppManifest*);
typedef void (*AppManifestCallback)(const AppManifest*, void* context);

void app_manifest_registry_init();
void app_manifest_registry_add(const AppManifest _Nonnull* manifest);
void app_manifest_registry_remove(const AppManifest _Nonnull* manifest);
const AppManifest _Nullable* app_manifest_registry_find_by_id(const char* id);
void app_manifest_registry_for_each(AppManifestCallback callback);
void app_manifest_registry_for_each_of_type(AppType type, AppManifestCallback callback);
void app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context);
void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback);

#ifdef __cplusplus
}
Expand Down
File renamed without changes
File renamed without changes
53 changes: 47 additions & 6 deletions components/nanobake/src/apps/services/desktop/desktop.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,59 @@
#include "desktop.h"
#include "furi_extra_defines.h"
#include "lvgl.h"
#include "check.h"
#include "record.h"
#include "apps/services/loader/loader.h"
#include "apps/services/gui/gui.h"
#include "apps/services/gui/view_port.h"
#include "app_manifest_registry.h"

static void desktop_start(void* param) {
UNUSED(param);
printf("desktop app init\n");
static void on_open_app(lv_event_t* e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
const AppManifest* manifest = lv_event_get_user_data(e);
FURI_RECORD_TRANSACTION(RECORD_LOADER, Loader*, loader, {
loader_start_app_nonblocking(loader, manifest->id, NULL);
})
}
}

static void add_app_to_list(const AppManifest* manifest, void* _Nullable parent) {
furi_check(parent);
lv_obj_t* list = (lv_obj_t*)parent;
lv_obj_t* btn = lv_list_add_btn(list, LV_SYMBOL_FILE, manifest->name);
lv_obj_add_event_cb(btn, &on_open_app, LV_EVENT_CLICKED, (void*)manifest);
}

static void desktop_show(lv_obj_t* parent, void* context) {
lv_obj_t* list = lv_list_create(parent);
lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
lv_obj_center(list);

lv_list_add_text(list, "System");
app_manifest_registry_for_each_of_type(AppTypeSystem, list, add_app_to_list);
lv_list_add_text(list, "User");
app_manifest_registry_for_each_of_type(AppTypeUser, list, add_app_to_list);
}

static void desktop_start() {
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, &desktop_show, NULL);
FURI_RECORD_TRANSACTION(RECORD_GUI, Gui*, gui, {
gui_add_view_port(gui, view_port, GuiLayerDesktop);
})
}

static void desktop_stop() {
furi_crash("desktop_stop is not implemented");
}

const AppManifest desktop_app = {
.id = "desktop",
.name = "Desktop",
.icon = NULL,
.type = AppTypeService,
.type = AppTypeDesktop,
.on_start = &desktop_start,
.on_stop = NULL,
.on_stop = &desktop_stop,
.on_show = NULL,
.stack_size = AppStackSizeNormal
};
227 changes: 59 additions & 168 deletions components/nanobake/src/apps/services/gui/gui_draw.c
Original file line number Diff line number Diff line change
@@ -1,191 +1,84 @@
#include "check.h"
#include "gui_i.h"
#include "log.h"
#include "record.h"
#include "esp_lvgl_port.h"
#include "apps/services/gui/widgets/widgets.h"
#include "apps/services/loader/loader.h"

static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
/*
ViewPortArray_it_t it;
uint8_t left_used = 0;
uint8_t right_used = 0;
uint8_t width;
canvas_frame_set(
gui->lvgl_parent, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
// for support black theme - paint white area and
// draw icon with transparent white color
canvas_set_color(gui->canvas, ColorWhite);
canvas_draw_box(gui->canvas, 1, 1, 9, 7);
canvas_draw_box(gui->canvas, 7, 3, 58, 6);
canvas_draw_box(gui->canvas, 61, 1, 32, 7);
canvas_draw_box(gui->canvas, 89, 3, 38, 6);
canvas_set_color(gui->canvas, ColorBlack);
canvas_set_bitmap_mode(gui->canvas, 1);
canvas_draw_icon(gui->canvas, 0, 0, &I_Background_128x11);
canvas_set_bitmap_mode(gui->canvas, 0);
// Right side
uint8_t x = GUI_DISPLAY_WIDTH - 1;
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]);
while(!ViewPortArray_end_p(it) && right_used < GUI_STATUS_BAR_WIDTH) {
ViewPort* view_port = *ViewPortArray_ref(it);
if(view_port_is_enabled(view_port)) {
width = view_port_get_width(view_port);
if(!width) width = 8;
// Recalculate next position
right_used += (width + 2);
x -= (width + 2);
// Prepare work area background
canvas_frame_set(
gui->canvas,
x - 1,
GUI_STATUS_BAR_Y + 1,
width + 2,
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
canvas_set_color(gui->canvas, ColorWhite);
canvas_draw_box(
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
canvas_set_color(gui->canvas, ColorBlack);
// ViewPort draw
canvas_frame_set(
gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
view_port_draw(view_port, gui->canvas);
}
ViewPortArray_next(it);
}
// Draw frame around icons on the right
if(right_used) {
canvas_frame_set(
gui->canvas,
GUI_DISPLAY_WIDTH - 3 - right_used,
GUI_STATUS_BAR_Y,
right_used + 3,
GUI_STATUS_BAR_HEIGHT);
canvas_set_color(gui->canvas, ColorBlack);
canvas_draw_rframe(
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
canvas_draw_line(
gui->canvas,
canvas_width(gui->canvas) - 2,
1,
canvas_width(gui->canvas) - 2,
canvas_height(gui->canvas) - 2);
canvas_draw_line(
gui->canvas,
1,
canvas_height(gui->canvas) - 2,
canvas_width(gui->canvas) - 2,
canvas_height(gui->canvas) - 2);
}
#define TAG "gui"

// Left side
x = 2;
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]);
while(!ViewPortArray_end_p(it) && (right_used + left_used) < GUI_STATUS_BAR_WIDTH) {
ViewPort* view_port = *ViewPortArray_ref(it);
if(view_port_is_enabled(view_port)) {
width = view_port_get_width(view_port);
if(!width) width = 8;
// Prepare work area background
canvas_frame_set(
gui->canvas,
x - 1,
GUI_STATUS_BAR_Y + 1,
width + 2,
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
canvas_set_color(gui->canvas, ColorWhite);
canvas_draw_box(
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
canvas_set_color(gui->canvas, ColorBlack);
// ViewPort draw
canvas_frame_set(
gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
view_port_draw(view_port, gui->canvas);
// Recalculate next position
left_used += (width + 2);
x += (width + 2);
}
ViewPortArray_next(it);
}
// Extra notification
if(need_attention) {
width = icon_get_width(&I_Hidden_window_9x8);
// Prepare work area background
canvas_frame_set(
gui->canvas,
x - 1,
GUI_STATUS_BAR_Y + 1,
width + 2,
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
canvas_set_color(gui->canvas, ColorWhite);
canvas_draw_box(gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
canvas_set_color(gui->canvas, ColorBlack);
// Draw Icon
canvas_frame_set(
gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
canvas_draw_icon(gui->canvas, 0, 0, &I_Hidden_window_9x8);
// Recalculate next position
left_used += (width + 2);
x += (width + 2);
}
// Draw frame around icons on the left
if(left_used) {
canvas_frame_set(gui->canvas, 0, 0, left_used + 3, GUI_STATUS_BAR_HEIGHT);
canvas_draw_rframe(
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
canvas_draw_line(
gui->canvas,
canvas_width(gui->canvas) - 2,
1,
canvas_width(gui->canvas) - 2,
canvas_height(gui->canvas) - 2);
canvas_draw_line(
gui->canvas,
1,
canvas_height(gui->canvas) - 2,
canvas_width(gui->canvas) - 2,
canvas_height(gui->canvas) - 2);
}
*/
static lv_obj_t* screen_with_top_bar(lv_obj_t* parent) {
lv_obj_set_style_bg_blacken(parent);

lv_obj_t* vertical_container = lv_obj_create(parent);
lv_obj_set_size(vertical_container, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(vertical_container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_no_padding(vertical_container);
lv_obj_set_style_bg_blacken(vertical_container);

top_bar(vertical_container);

lv_obj_t* child_container = lv_obj_create(vertical_container);
lv_obj_set_width(child_container, LV_PCT(100));
lv_obj_set_flex_grow(child_container, 1);
lv_obj_set_style_no_padding(vertical_container);
lv_obj_set_style_bg_blacken(vertical_container);

return child_container;
}

static bool gui_redraw_window(Gui* gui) {
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerWindow]);
if (view_port) {
lv_obj_set_style_bg_blacken(gui->lvgl_parent);
static lv_obj_t* screen_with_top_bar_and_toolbar(lv_obj_t* parent) {
lv_obj_set_style_bg_blacken(parent);

lv_obj_t* vertical_container = lv_obj_create(parent);
lv_obj_set_size(vertical_container, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(vertical_container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_no_padding(vertical_container);
lv_obj_set_style_bg_blacken(vertical_container);

top_bar(vertical_container);

lv_obj_t* vertical_container = lv_obj_create(gui->lvgl_parent);
lv_obj_set_size(vertical_container, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(vertical_container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_no_padding(vertical_container);
lv_obj_set_style_bg_blacken(vertical_container);
FURI_RECORD_TRANSACTION(RECORD_LOADER, Loader*, loader, {
const AppManifest* manifest = loader_get_current_app(loader);
if (manifest != NULL) {
toolbar(vertical_container, TOP_BAR_HEIGHT, manifest);
}
})

lv_obj_t* spacer = lv_obj_create(vertical_container);
lv_obj_set_size(spacer, 2, 2);
lv_obj_set_style_bg_blacken(spacer);

top_bar(vertical_container);
lv_obj_t* child_container = lv_obj_create(vertical_container);
lv_obj_set_width(child_container, LV_PCT(100));
lv_obj_set_flex_grow(child_container, 1);
lv_obj_set_style_no_padding(vertical_container);
lv_obj_set_style_bg_blacken(vertical_container);

lv_obj_t* window_parent = lv_obj_create(vertical_container);
lv_obj_set_width(window_parent, LV_PCT(100));
lv_obj_set_flex_grow(window_parent, 1);
lv_obj_set_style_no_padding(vertical_container);
lv_obj_set_style_bg_blacken(vertical_container);
return child_container;
}

view_port_draw(view_port, window_parent);
static bool gui_redraw_window(Gui* gui) {
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerWindow]);
if (view_port) {
lv_obj_t* container = screen_with_top_bar_and_toolbar(gui->lvgl_parent);
view_port_draw(view_port, container);
return true;
} else {
return false;
}
}

static bool gui_redraw_desktop(Gui* gui) {
/*
canvas_frame_set(gui->lvgl_parent, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]);
if(view_port) {
view_port_draw(view_port, gui->lvgl_parent);
if (view_port) {
lv_obj_t* container = screen_with_top_bar(gui->lvgl_parent);
view_port_draw(view_port, container);
return true;
} else {
FURI_LOG_E(TAG, "no desktop layer found");
}
*/

return false;
}
Expand All @@ -207,12 +100,10 @@ void gui_redraw(Gui* gui) {
furi_check(lvgl_port_lock(100));
lv_obj_clean(gui->lvgl_parent);

gui_redraw_desktop(gui);
if (!gui_redraw_fs(gui)) {
if (!gui_redraw_window(gui)) {
gui_redraw_desktop(gui);
}
gui_redraw_status_bar(gui, false);
}

lvgl_port_unlock();
Expand Down
Loading

0 comments on commit 48d2fd6

Please sign in to comment.