Browse Source

Beginning of tiling wm

master
Adam Pippin 4 years ago
parent
commit
8634a43ece
  1. 152
      UI.cpp
  2. 15
      UI.h
  3. 41
      watchos.ino

152
UI.cpp

@ -1,22 +1,168 @@
#include <M5StickC.h>
#include "Kernel.h"
#include "UI.h"
#define MAX_WINDOWS 8
struct Window *UI_get_window(int hwnd);
void base_window_callback(int hwnd, int x, int y, int width, int height);
void draw(int parent_hwnd, int x, int y, int width, int height);
struct Window windows[MAX_WINDOWS];
int next_hwnd = 1;
int UI(int pid, unsigned int signal)
{
if (signal & SIGNAL_START)
{
Kernel_signal_mask(pid, SIGNAL_START | SIGNAL_STOP | SIGNAL_REDRAW);
windows[0].hwnd = next_hwnd++;
windows[0].hwnd_parent = 0;
windows[0].layout_mode = LAYOUT_MODE_SPLIT_VERTICAL;
windows[0].callback = &base_window_callback;
}
if (signal & SIGNAL_STOP)
{
return 255;
}
if (signal & SIGNAL_REDRAW)
{
M5.Lcd.fillScreen(TFT_DARKGREY);
M5.Lcd.setRotation(3);
M5.Lcd.setTextColor(TFT_WHITE, TFT_DARKGREY);
for (int i=0; i<MAX_WINDOWS; i++)
{
if (windows[i].hwnd == 0 || windows[i].hwnd_parent != 0)
{
continue;
}
M5.Lcd.setTextColor(TFT_WHITE, TFT_DARKGREY);
// TODO: Get actual screen bounds somehow
draw(windows[i].hwnd, 0, 0, 160, 80);
}
}
return 0;
}
void draw(int parent_hwnd, int x, int y, int width, int height)
{
Serial.printf("Drawing window %d\n", parent_hwnd);
// Trigger draw
Window* parent_window = UI_get_window(parent_hwnd);
if (parent_window->hwnd == -1)
{
return;
}
// Call callback on parent if available
if (parent_window->placeholder != true)
{
(*parent_window->callback)(parent_hwnd, x, y, width, height);
}
// Count the number of children
int child_count = 0;
for (int i=0; i<MAX_WINDOWS; i++)
{
if (windows[i].hwnd_parent == parent_hwnd)
{
child_count++;
}
}
Serial.printf("Found %d children\n", child_count);
if (child_count == 0)
{
return;
}
// Grab all the children
Window* children[child_count];
int next_child = 0;
for (int i=0; i<MAX_WINDOWS; i++)
{
if (windows[i].hwnd_parent == parent_hwnd)
{
children[next_child++] = &windows[i];
}
}
switch (parent_window->layout_mode)
{
case LAYOUT_MODE_NONE:
{
Serial.printf("Layout mode: none\n");
for (int i=0; i<child_count; i++)
{
draw(children[i]->hwnd, x, y, width, height);
}
}
break;
case LAYOUT_MODE_SPLIT_VERTICAL:
{
Serial.printf("Layout mode: vertical\n");
int child_width = width / child_count;
for (int i=0; i<child_count; i++)
{
draw(children[i]->hwnd, x + (i * child_width), y, child_width, height);
}
}
break;
case LAYOUT_MODE_SPLIT_HORIZONTAL:
{
Serial.printf("Layout mode: horizontal\n");
int child_height = height / child_count;
for (int i=0; i<child_count; i++)
{
draw(children[i]->hwnd, x, y + (i * child_height), width, child_height);
}
}
break;
}
}
void base_window_callback(int hwnd, int x, int y, int width, int height)
{
M5.Lcd.fillScreen(TFT_DARKGREY);
M5.Lcd.setRotation(3);
}
int UI_create_window(void (*callback)(int, int, int, int, int), int parent /* = 0 */, int zorder /* = 0 */, bool placeholder /* = true */)
{
Window* window = UI_get_window(0);
if (window->hwnd == -1)
{
Kernel_panic("Cannot create window! Out of handles!");
}
window->hwnd = next_hwnd++;
window->hwnd_parent = parent;
window->placeholder = placeholder;
window->callback = callback;
return window->hwnd;
}
void UI_set_layout_mode(int hwnd, int layout_mode)
{
Window* window = UI_get_window(0);
if (window->hwnd == -1)
{
return;
}
window->layout_mode = layout_mode;
}
struct Window *UI_get_window(int hwnd)
{
for (int i=0; i<MAX_WINDOWS; i++)
{
if (windows[i].hwnd == hwnd)
{
return &windows[i];
}
}
struct Window empty = Window();
empty.hwnd = -1;
return &empty;
}

15
UI.h

@ -1,2 +1,17 @@
struct Window
{
int hwnd = 0;
void (*callback)(int, int, int, int, int);
int hwnd_parent = 0;
int layout_mode = 0;
bool placeholder = false;
};
#define LAYOUT_MODE_NONE 0
#define LAYOUT_MODE_SPLIT_VERTICAL 1
#define LAYOUT_MODE_SPLIT_HORIZONTAL 2
int UI(int pid, unsigned int signal);
int UI_create_window(void (*callback)(int, int, int, int, int), int parent = 0, int zorder = 0, bool placeholder = false);
void UI_set_layout_mode(int hwnd, int layout_mode);

41
watchos.ino

@ -11,11 +11,34 @@
int count = 0;
bool input_a = false, input_b = false;
void test_draw(int hwnd, int x, int y, int width, int height)
{
M5.Lcd.setCursor(x, y);
M5.Lcd.println(String(count));
y += 10;
if (input_a)
{
M5.Lcd.setCursor(x, y);
M5.Lcd.println("Input A!");
y += 10;
}
if (input_b)
{
M5.Lcd.setCursor(x, y);
M5.Lcd.println("Input B!");
y += 10;
}
}
int test_func(int pid, unsigned int signal)
{
if (signal & SIGNAL_START)
{
Kernel_signal_mask(pid, SIGNAL_START | SIGNAL_STOP | SIGNAL_TICK | SIGNAL_REDRAW | SIGNAL_INPUT_A | SIGNAL_INPUT_B);
Kernel_signal_mask(pid, SIGNAL_START | SIGNAL_STOP | SIGNAL_TICK | SIGNAL_INPUT_A | SIGNAL_INPUT_B);
UI_set_layout_mode(1, LAYOUT_MODE_SPLIT_VERTICAL);
int hwnd = UI_create_window(&test_draw, 1);
hwnd = UI_create_window(&test_draw, 1);
if (EAT_allocate(1, 2))
{
EAT_write(1, 0, 0);
@ -54,18 +77,6 @@ int test_func(int pid, unsigned int signal)
input_b = true;
Kernel_signal(SIGNAL_REDRAW);
}
if (signal & SIGNAL_REDRAW)
{
M5.Lcd.setCursor(0, 0);
M5.Lcd.print("Ran: ");
M5.Lcd.print(String(count));
M5.Lcd.println(" times");
if (input_a)
M5.Lcd.println("Input A!");
if (input_b)
M5.Lcd.println("Input B!");
}
return 0;
}
@ -83,8 +94,8 @@ void setup()
Serial.printf("[POWER] pid %d\n", pid);
pid = Kernel_start(&UserInput, 0);
Serial.printf("[INPUT] pid %d\n", pid);
//pid = Kernel_start(&test_func, 5000);
//Serial.printf("[TEST ] pid %d\n", pid);
pid = Kernel_start(&test_func, 5000);
Serial.printf("[TEST ] pid %d\n", pid);
pid = Kernel_start(&Clock, 1000);
Serial.printf("[CLOCK] pid %d\n", pid);
pid = Kernel_start(&Battery, 2000);

Loading…
Cancel
Save