Meta: Add files to repository
14
.clang-format
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: WebKit
|
||||
SpaceAfterTemplateKeyword: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignTrailingComments: true
|
||||
BreakBeforeInheritanceComma: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
IndentPPDirectives: AfterHash
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
NamespaceIndentation: None
|
||||
QualifierAlignment: Right
|
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
src/image/** linguist-vendored
|
||||
src/tlse/** linguist-vendored
|
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
build/
|
||||
reports/
|
||||
src/net/exports/
|
10
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"jaktLanguageServer.compiler.executablePath": "jakt",
|
||||
"git.ignoreLimitWarning": true,
|
||||
"pmd-cpd.language": [
|
||||
"cpp"
|
||||
],
|
||||
"pmd-cpd.onStartBehavior": "Show",
|
||||
"pmd-cpd.sourceDirectory": "/home/alec/repos/erythros",
|
||||
"terminal.integrated.shellIntegration.history": 0
|
||||
}
|
1
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":"2.0.0","tasks":[{"label":"Build All","type":"shell","command":"${workspaceFolder}/scripts/build-all ${workspaceFolder}","group":{"kind":"build","isDefault":true},"problemMatcher":[]}]}
|
5
Applets/Calendar.applet/Run.HC
Normal file
|
@ -0,0 +1,5 @@
|
|||
Gui.App();
|
||||
|
||||
U0 Main() { Suspend; }
|
||||
|
||||
Main;
|
32
Applets/ClipManager.applet/Run.HC
Normal file
|
@ -0,0 +1,32 @@
|
|||
Gui.App();
|
||||
|
||||
Context2DWidget* clipmanager_icon = SystemTray.RegisterItem();
|
||||
|
||||
Context2D* ctx_clip_icon = Image.FileToContext2D("M:/Media/Themes/Umami/Icon/clipboard.png");
|
||||
|
||||
CopyRect2D(clipmanager_icon->ctx, 0, 0, ctx_clip_icon);
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
I64 length = 0;
|
||||
I64 text_width = 0;
|
||||
while (1) {
|
||||
if (length < Clipboard.Length()) {
|
||||
CopyRect2D(clipmanager_icon->ctx, 0, 0, ctx_clip_icon);
|
||||
Rect2D(clipmanager_icon->ctx, 12, 12, 12, 12, Color(255, 0, 0));
|
||||
text_width = Print2D(NULL, Compositor.theme.font.sans, 0, 0,
|
||||
Color(255, 255, 255), , "%02d", Clipboard.Length());
|
||||
Print2D(clipmanager_icon->ctx, Compositor.theme.font.sans,
|
||||
11 + 6 - (text_width / 2), 13, Color(255, 255, 255), , "%02d",
|
||||
Clipboard.Length());
|
||||
Print2D(clipmanager_icon->ctx, Compositor.theme.font.sans,
|
||||
11 + 7 - (text_width / 2), 13, Color(255, 255, 255), , "%02d",
|
||||
Clipboard.Length());
|
||||
length = Clipboard.Length();
|
||||
Gui.Window.Refresh(Compositor.menubar.win);
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
Main;
|
101
Applets/NetworkStatus.applet/Run.HC
Normal file
|
@ -0,0 +1,101 @@
|
|||
Gui.App();
|
||||
|
||||
U64 flags = WIN_FLAGS_MOVABLE | WIN_FLAGS_ICON | WIN_FLAGS_TITLE_BAR | WIN_FLAGS_CLOSE_BUTTON | WIN_FLAGS_SKIP;
|
||||
Window* win = Compositor.CreateWindow(Display.Width() - 240, 33, 240, 120, flags);
|
||||
Gui.Window.SetIcon(win, Image.FileToContext2D("window_icon_16x16.png"));
|
||||
Gui.Window.Hide(win);
|
||||
Gui.Window.SetTitle(win, "Network Status");
|
||||
|
||||
TextLabelWidget* status_label1 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 16, 16, 192, 16);
|
||||
TextLabelWidget* status_label2 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 16, 32, 192, 16);
|
||||
TextLabelWidget* status_label3 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 16, 48, 192, 16);
|
||||
TextLabelWidget* status_label4 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 16, 64, 192, 16);
|
||||
|
||||
TextLabelWidget* status_label5 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 128, 16, 192, 16);
|
||||
TextLabelWidget* status_label6 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 128, 32, 192, 16);
|
||||
TextLabelWidget* status_label7 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 128, 48, 192, 16);
|
||||
TextLabelWidget* status_label8 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 128, 64, 192, 16);
|
||||
Gui.Widget.SetFont(status_label1, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label2, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label3, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label4, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label5, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label6, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label7, "Eight Bit Dragon");
|
||||
Gui.Widget.SetFont(status_label8, "Eight Bit Dragon");
|
||||
|
||||
Context2DWidget* network_icon = SystemTray.RegisterItem();
|
||||
|
||||
Context2D* ctx_network_error = Image.FileToContext2D("M:/Media/Themes/Umami/Icon/status/network-error.png");
|
||||
Context2D* ctx_network_idle = Image.FileToContext2D("M:/Media/Themes/Umami/Icon/status/network-idle.png");
|
||||
Context2D* ctx_network_offline = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/network-offline.png");
|
||||
Context2D* ctx_network_rx = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/network-receive.png");
|
||||
Context2D* ctx_network_tx = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/network-transmit.png");
|
||||
Context2D* ctx_network_txrx = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/network-transmit-receive.png");
|
||||
Context2D* ctx_network_wireless_enc = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/network-wireless-encrypted.png");
|
||||
|
||||
U0 @networkstatus_show(Widget*)
|
||||
{
|
||||
|
||||
NetInfoRequest* req = @net_info_request;
|
||||
|
||||
win->flags &= ~WIN_FLAGS_SKIP;
|
||||
|
||||
U8 status_ipaddr[128];
|
||||
U8 status_netmask[128];
|
||||
U8 status_gateway[128];
|
||||
U8 status_dns1[128];
|
||||
|
||||
StrPrint(&status_ipaddr, "%d.%d.%d.%d", req->ipv4_address.u8[3], req->ipv4_address.u8[2],
|
||||
req->ipv4_address.u8[1], req->ipv4_address.u8[0]);
|
||||
StrPrint(&status_netmask, "%d.%d.%d.%d", req->ipv4_netmask.u8[3], req->ipv4_netmask.u8[2],
|
||||
req->ipv4_netmask.u8[1], req->ipv4_netmask.u8[0]);
|
||||
StrPrint(&status_gateway, "%d.%d.%d.%d", req->ipv4_gateway.u8[3], req->ipv4_gateway.u8[2],
|
||||
req->ipv4_gateway.u8[1], req->ipv4_gateway.u8[0]);
|
||||
StrPrint(&status_dns1, "%d.%d.%d.%d", req->dns_server_address.u8[3], req->dns_server_address.u8[2],
|
||||
req->dns_server_address.u8[1], req->dns_server_address.u8[0], req->dns_server_port);
|
||||
|
||||
Gui.Widget.SetText(status_label1, "IP address:");
|
||||
Gui.Widget.SetText(status_label2, "Subnet mask:");
|
||||
Gui.Widget.SetText(status_label3, "Gateway:");
|
||||
Gui.Widget.SetText(status_label4, "DNS Server:");
|
||||
|
||||
Gui.Widget.SetText(status_label5, &status_ipaddr);
|
||||
Gui.Widget.SetText(status_label6, &status_netmask);
|
||||
Gui.Widget.SetText(status_label7, &status_gateway);
|
||||
Gui.Widget.SetText(status_label8, &status_dns1);
|
||||
|
||||
Gui.Window.SetFocus(win);
|
||||
Gui.Window.Refresh(win);
|
||||
while (!Gui.Window.IsVisible(win))
|
||||
Compositor.ShowWindow(win);
|
||||
}
|
||||
|
||||
U0 @networkstatus_hide(Window*)
|
||||
{
|
||||
win->flags |= WIN_FLAGS_SKIP;
|
||||
Compositor.HideWindow(win);
|
||||
}
|
||||
|
||||
network_icon->ctx = ctx_network_error;
|
||||
Gui.Window.Refresh(Compositor.menubar.win);
|
||||
Gui.Window.SetCallback(win, "close", &@networkstatus_hide);
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Gui.Widget.SetCallback(network_icon, "clicked", &@networkstatus_show);
|
||||
while (1) {
|
||||
if (network_icon->ctx == ctx_network_error) {
|
||||
network_icon->ctx = ctx_network_idle;
|
||||
Gui.Window.Refresh(Compositor.menubar.win);
|
||||
}
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
Main;
|
BIN
Applets/NetworkStatus.applet/window_icon_16x16.png
Normal file
After Width: | Height: | Size: 613 B |
71
Applets/VolumeSlider.applet/Run.HC
Normal file
|
@ -0,0 +1,71 @@
|
|||
Gui.App();
|
||||
|
||||
Window* win = Compositor.CreateWindow(Display.Width(), 32, 256, 32,
|
||||
WIN_FLAGS_NOHILIGHT | WIN_FLAGS_SKIP);
|
||||
|
||||
Context2DWidget* volume_slider_icon = Gui.CreateWidget(win, WIDGET_TYPE_CONTEXT2D, 0, 0, 24, 24);
|
||||
volume_slider_icon->ctx = NewContext2D(24, 24);
|
||||
HorizontalSliderWidget* volume_slider = Gui.CreateWidget(win, WIDGET_TYPE_HORZ_SLIDER, 32, 4, 212, 24);
|
||||
volume_slider->max = 100;
|
||||
volume_slider->scroll = volume_slider->width;
|
||||
|
||||
Context2DWidget* tray_icon = SystemTray.RegisterItem();
|
||||
|
||||
Context2D* ctx_volume_muted = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/audio-volume-muted.png");
|
||||
Context2D* ctx_volume_low = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/audio-volume-low.png");
|
||||
Context2D* ctx_volume_medium = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/audio-volume-medium.png");
|
||||
Context2D* ctx_volume_high = Image.FileToContext2D(
|
||||
"M:/Media/Themes/Umami/Icon/status/audio-volume-high.png");
|
||||
|
||||
U0 @volumeslider_show(Widget*)
|
||||
{
|
||||
win->x = Display.Width() - 256;
|
||||
Compositor.ShowWindow(win);
|
||||
Gui.Window.SetFocus(win);
|
||||
}
|
||||
|
||||
U0 @volumeslider_change(Widget*)
|
||||
{
|
||||
I64 volume = Min(ToI64(volume_slider->scroll * 0.47), 100);
|
||||
Audio.mixer.left = volume;
|
||||
Audio.mixer.right = volume;
|
||||
Context2D* update_slider_icon = NULL;
|
||||
switch (volume) {
|
||||
case 0:
|
||||
update_slider_icon = ctx_volume_muted;
|
||||
break;
|
||||
case 1...24:
|
||||
update_slider_icon = ctx_volume_low;
|
||||
break;
|
||||
case 25...74:
|
||||
update_slider_icon = ctx_volume_medium;
|
||||
break;
|
||||
case 75...100:
|
||||
default:
|
||||
update_slider_icon = ctx_volume_high;
|
||||
break;
|
||||
}
|
||||
CopyRect2D(volume_slider_icon->ctx, 0, 0, update_slider_icon);
|
||||
CopyRect2D(tray_icon->ctx, 0, 0, update_slider_icon);
|
||||
Gui.Window.Refresh(Compositor.menubar.win);
|
||||
}
|
||||
@volumeslider_change(NULL);
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Gui.Window.SetTitle(win, "VolumeSlider");
|
||||
Compositor.HideWindow(win);
|
||||
Gui.Widget.SetCallback(tray_icon, "clicked", &@volumeslider_show);
|
||||
Gui.Widget.SetCallback(volume_slider, "change", &@volumeslider_change);
|
||||
|
||||
while (1) {
|
||||
if (Gui.Window.IsVisible(win) && Compositor.active_win != win)
|
||||
Compositor.HideWindow(win);
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
Main;
|
100
Applications/Accessories/Calculator.app/Run.HC
Normal file
|
@ -0,0 +1,100 @@
|
|||
Gui.App();
|
||||
|
||||
#define CALC_OP_ADD 0
|
||||
#define CALC_OP_SUB 1
|
||||
#define CALC_OP_MUL 2
|
||||
#define CALC_OP_DIV 3
|
||||
|
||||
class @calc_entry
|
||||
{
|
||||
I64 op;
|
||||
F64 entry;
|
||||
};
|
||||
|
||||
Window* win = NULL;
|
||||
TextInputWidget* result = NULL;
|
||||
|
||||
U8* calc_font = "Eight Bit Dragon";
|
||||
U8* @calc_button_label[27] = { "Back", "CE", "C", "MC", "7", "8", "9",
|
||||
"/", "sqrt", "MR", "4", "5", "6", "*",
|
||||
"%", "MS", "1", "2", "3", "-", "1/x",
|
||||
"M+", "0", "+/-", ".", "+", "=" };
|
||||
|
||||
U0 @calc_keypress_callback(Window*, I64 key)
|
||||
{
|
||||
if (win != Compositor.active_win)
|
||||
return;
|
||||
U8* res_text = result->text;
|
||||
switch (ScanCode2Char(key)) {
|
||||
case '0' ... '9':
|
||||
StrPrint(res_text + StrLen(res_text), "%c", ScanCode2Char(key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @calc_btn_callback(ButtonWidget* widget)
|
||||
{
|
||||
U8* res_text = result->text;
|
||||
if (Str2I64(widget->text)) {
|
||||
StrCpy(res_text + StrLen(res_text), widget->text);
|
||||
}
|
||||
if (!StrCmp(widget->text, "0"))
|
||||
StrCpy(res_text + StrLen(res_text), widget->text);
|
||||
}
|
||||
|
||||
U0 window_close(Window* win)
|
||||
{
|
||||
if (win == Compositor.active_win)
|
||||
Gui.Window.SetFocus(Compositor.GetWindowByTitle("Wallpaper"));
|
||||
Compositor.UnregisterForGlobalInputEvents(win);
|
||||
Compositor.DestroyWindow(win);
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
I64 i;
|
||||
I64 j;
|
||||
I64 k;
|
||||
U64 flags = WIN_FLAGS_DEFAULT;
|
||||
flags &= ~WIN_FLAGS_RESIZABLE;
|
||||
flags &= ~WIN_FLAGS_MAX_BUTTON;
|
||||
win = Compositor.CreateWindow(224, 224, 233, 240, flags);
|
||||
Gui.Window.SetTitle(win, "Calculator");
|
||||
Compositor.RegisterForGlobalInputEvents(win);
|
||||
Gui.Window.SetIcon(win, Image.FileToContext2D("window_icon_16x16.png"));
|
||||
Gui.Window.SetFocus(win);
|
||||
Gui.Window.SetCallback(win, "close", &window_close);
|
||||
Gui.Window.SetCallback(win, "keypress", &@calc_keypress_callback);
|
||||
|
||||
result = Gui.CreateWidget(win, WIDGET_TYPE_INPUT, 4, 4, 246, 24);
|
||||
Gui.Widget.SetFont(result, calc_font);
|
||||
|
||||
ButtonWidget* calc_btn[27];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (i < 3) {
|
||||
calc_btn[i] = Gui.CreateWidget(win, WIDGET_TYPE_BUTTON, 46 + (60 * i), 32, 56, 32);
|
||||
calc_btn[i]->color = Color(255, 0, 0);
|
||||
Gui.Widget.SetText(calc_btn[i], @calc_button_label[i]);
|
||||
Gui.Widget.SetFont(calc_btn[i], calc_font);
|
||||
Gui.Widget.SetCallback(calc_btn[i], "clicked", &@calc_btn_callback);
|
||||
}
|
||||
j = 3 + (6 * i);
|
||||
calc_btn[j] = Gui.CreateWidget(win, WIDGET_TYPE_BUTTON, 4, 68 + (36 * i), 32, 32);
|
||||
calc_btn[j]->color = Color(255, 0, 0);
|
||||
Gui.Widget.SetText(calc_btn[j], @calc_button_label[j]);
|
||||
Gui.Widget.SetFont(calc_btn[j], calc_font);
|
||||
Gui.Widget.SetCallback(calc_btn[j], "clicked", &@calc_btn_callback);
|
||||
for (k = 1; k < 6; k++) {
|
||||
calc_btn[j + k] = Gui.CreateWidget(win, WIDGET_TYPE_BUTTON, 10 + (36 * k),
|
||||
68 + (36 * i), 32, 32);
|
||||
calc_btn[j + k]->color = T(k == 4 || k == 5 && i == 3, Color(255, 0, 0), Color(0, 0, 255));
|
||||
Gui.Widget.SetText(calc_btn[j + k], @calc_button_label[j + k]);
|
||||
Gui.Widget.SetFont(calc_btn[j + k], calc_font);
|
||||
Gui.Widget.SetCallback(calc_btn[j + k], "clicked", &@calc_btn_callback);
|
||||
}
|
||||
}
|
||||
Suspend;
|
||||
}
|
||||
|
||||
Main;
|
BIN
Applications/Accessories/Calculator.app/window_icon_16x16.png
Normal file
After Width: | Height: | Size: 619 B |
BIN
Applications/Accessories/Icon.png
Normal file
After Width: | Height: | Size: 850 B |
BIN
Applications/OS/Icon.png
Normal file
After Width: | Height: | Size: 1,010 B |
126
Applications/OS/MenuBar.app/Run.HC
Normal file
|
@ -0,0 +1,126 @@
|
|||
Gui.App();
|
||||
|
||||
Window* sys_menu = Menu.New("System Menu");
|
||||
|
||||
U0 @system_menu_item_clicked(MenuItemWidget* widget)
|
||||
{
|
||||
if (!widget->path)
|
||||
return;
|
||||
SystemStarter.CreateTask(widget->path, &widget->text);
|
||||
}
|
||||
|
||||
U0 @system_menu_init()
|
||||
{
|
||||
JsonObject* data = Json.ParseFile("M:/Settings/SystemMenu.json", erythros_mem_task);
|
||||
JsonArray* items = data->a("items");
|
||||
JsonArray* subitems = NULL;
|
||||
Window* submenu = NULL;
|
||||
I64 i;
|
||||
I64 j;
|
||||
// System Menu supports 2 levels of nesting to separate groups of Applications
|
||||
// into categories.
|
||||
for (i = 0; i < items->length; i++) {
|
||||
if (items->o(i)->@("name")) {
|
||||
if (items->o(i)->@("path")) {
|
||||
Menu.AddItem(
|
||||
sys_menu, items->o(i)->@("name"),
|
||||
@image_file_to_context2d(items->o(i)->@("icon")),
|
||||
&@system_menu_item_clicked,
|
||||
items->o(i)->@("path"));
|
||||
}
|
||||
if (items->o(i)->@("items")) {
|
||||
submenu = Menu.New(items->o(i)->@("name"));
|
||||
submenu->x = sys_menu->width;
|
||||
submenu->y = 35 + sys_menu->y + (MENU_ITEM_MIN_HEIGHT * i);
|
||||
subitems = items->o(i)->a("items");
|
||||
for (j = 0; j < subitems->length; j++) {
|
||||
if (subitems->o(j)->@("name")) {
|
||||
if (subitems->o(j)->@("path")) {
|
||||
Menu.AddItem(submenu,
|
||||
subitems->o(j)->@("name"),
|
||||
@image_file_to_context2d(
|
||||
subitems->o(j)->@("icon")),
|
||||
&@system_menu_item_clicked,
|
||||
subitems->o(j)->@("path"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Menu.AddItem(
|
||||
sys_menu, items->o(i)->@("name"),
|
||||
@image_file_to_context2d(items->o(i)->@("icon")),
|
||||
NULL, NULL, submenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 @system_menu_show(Context2DWidget* widget)
|
||||
{
|
||||
sys_menu->x = 0;
|
||||
sys_menu->y = 32;
|
||||
if (widget->width == 30 && widget->height == 30)
|
||||
Fill2D(widget->ctx, Color(192, 192, 192));
|
||||
Gui.Window.Show(sys_menu);
|
||||
Gui.Window.SetFocus(sys_menu);
|
||||
Gui.Window.Refresh(sys_menu);
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Window* win = Compositor.CreateWindow(0, 0, Display.Width(), 32,
|
||||
WIN_FLAGS_NOHILIGHT | WIN_FLAGS_SKIP);
|
||||
Gui.Window.SetTitle(win, "MenuBar");
|
||||
|
||||
ButtonWidget* system_menu_btn = Gui.CreateWidget(win, WIDGET_TYPE_BUTTON, 0, 0, 58, 24);
|
||||
Gui.Widget.SetText(system_menu_btn, "");
|
||||
system_menu_btn->image = @image_file_to_context2d("system_menu.png");
|
||||
system_menu_btn->width = system_menu_btn->image->width + 8;
|
||||
|
||||
Context2DWidget* separator = Gui.CreateWidget(
|
||||
win, WIDGET_TYPE_CONTEXT2D,
|
||||
system_menu_btn->x + system_menu_btn->width + 4, 2, 2, 20);
|
||||
separator->ctx = NewContext2D(2, 20);
|
||||
Line2D(separator->ctx, 0, 0, 0, 20, Color(224, 224, 224));
|
||||
Line2D(separator->ctx, 1, 0, 1, 20, Color(128, 128, 128));
|
||||
|
||||
TextInputWidget* active_app_title = Gui.CreateWidget(
|
||||
win, WIDGET_TYPE_LABEL, separator->x + separator->width + 8, 8, 192, 64);
|
||||
|
||||
if (!Compositor.active_win)
|
||||
Gui.Window.SetFocus(Compositor.GetWindowByTitle("Wallpaper"));
|
||||
|
||||
Gui.Widget.SetFont(active_app_title, "Eight Bit Dragon");
|
||||
Gui.Widget.SetText(active_app_title, Compositor.active_win->title);
|
||||
|
||||
CDateStruct ds;
|
||||
U8 clock_text[32];
|
||||
TextInputWidget* clock = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, Display.Width() - 94, 8, 64, 32);
|
||||
Gui.Widget.SetFont(clock, "Eight Bit Dragon");
|
||||
Gui.Window.Refresh(win);
|
||||
|
||||
// FIXME: This is an ugly way to do this...
|
||||
Compositor.menubar.win = win;
|
||||
Compositor.menubar.task = Fs;
|
||||
Compositor.menubar.title = active_app_title;
|
||||
|
||||
Gui.Widget.SetCallback(system_menu_btn, "clicked", &@system_menu_show);
|
||||
|
||||
// System Clock
|
||||
I64 min = -1;
|
||||
while (1) {
|
||||
Date2Struct(&ds, Now);
|
||||
if (ds.min != min) {
|
||||
StrPrint(&clock_text, "%02d %03tZ, %02d:%02d", ds.day_of_mon, ds.mon - 1,
|
||||
"ST_MONTHS", ds.hour, ds.min);
|
||||
Gui.Widget.SetText(clock, &clock_text);
|
||||
Gui.Window.Refresh(win);
|
||||
min = ds.min;
|
||||
}
|
||||
if (Compositor.active_win != sys_menu && Gui.Window.IsVisible(sys_menu))
|
||||
Gui.Window.Hide(sys_menu);
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
@system_menu_init;
|
||||
Main;
|
BIN
Applications/OS/MenuBar.app/system_menu.png
Normal file
After Width: | Height: | Size: 869 B |
BIN
Applications/OS/ShutDown.app/Icon.png
Normal file
After Width: | Height: | Size: 875 B |
25
Applications/OS/ShutDown.app/Run.HC
Normal file
|
@ -0,0 +1,25 @@
|
|||
Gui.App();
|
||||
|
||||
U0 @shutdown_callback(U64 o)
|
||||
{
|
||||
if (!o)
|
||||
return;
|
||||
if (o(Window*)->signature == WIN_SIGNATURE) {
|
||||
Compositor.DestroyWindow(o(Window*));
|
||||
Gui.Window.SetFocus(Compositor.GetWindowByTitle("Wallpaper"));
|
||||
return;
|
||||
}
|
||||
switch (o(Widget*)->tag) {
|
||||
case TRUE:
|
||||
System.PowerOff();
|
||||
break;
|
||||
default:
|
||||
Compositor.DestroyWindow(o(Widget*)->parent_win);
|
||||
Gui.Window.SetFocus(Compositor.GetWindowByTitle("Wallpaper"));
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MessageBox.Alert("Do you want to shut down this computer?",
|
||||
"[\"OK\",\"Cancel\"]", &@shutdown_callback);
|
198
Applications/OS/TaskSwitcher.app/Run.HC
Normal file
|
@ -0,0 +1,198 @@
|
|||
Gui.App();
|
||||
#define MAX_THUMBS_PER_LINE 10
|
||||
|
||||
Window* win = Compositor.CreateWindow(120, 120, 640, 192, WIN_FLAGS_SKIP);
|
||||
Window* to_be_focused_win = NULL;
|
||||
Bool task_switcher_active = FALSE;
|
||||
Bool task_switcher_invoke = FALSE;
|
||||
|
||||
I64 caption_width = 0;
|
||||
F64 win_scale = 0.0;
|
||||
I64 win_thumb_size = 128;
|
||||
I64 win_thumb_container_size = win_thumb_size + 32;
|
||||
I64 win_index = -1;
|
||||
I64 win_items = 0;
|
||||
I64 cur_index = 0;
|
||||
U8* cur_win_title = NULL;
|
||||
Context2D* win_scaled = NULL;
|
||||
|
||||
@compositor_windows_list* win_list = NULL;
|
||||
|
||||
TextLabelWidget* caption = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 8, 8, 256, 64);
|
||||
Gui.Widget.SetFont(caption, "Eight Bit Dragon");
|
||||
|
||||
Context2DWidget* cursor = NULL;
|
||||
|
||||
U0 keypress_callback(Window* win, I64)
|
||||
{
|
||||
I64 i;
|
||||
if (!task_switcher_active) {
|
||||
if ((KeyDown(SC_CTRL) && KeyDown(Char2ScanCode('w'))) || (KeyDown(SC_ALT) && KeyDown(SC_F4)))
|
||||
if (Compositor.active_win != win && Compositor.active_win->callback.close)
|
||||
Compositor.active_win->callback.close(Compositor.active_win);
|
||||
return;
|
||||
}
|
||||
if (KeyDown(SC_TAB)) {
|
||||
if (KeyDown(SC_SHIFT))
|
||||
win_index--;
|
||||
else
|
||||
win_index += T(win_items > 1 && task_switcher_invoke, 2, 1);
|
||||
}
|
||||
|
||||
if (!win_items)
|
||||
return;
|
||||
|
||||
@window_widgets_list* set_item = win->widget->next->next->next;
|
||||
if (win_index < 0)
|
||||
win_index = win_items - 1;
|
||||
if (win_index >= win_items)
|
||||
win_index = 0;
|
||||
for (i = 0; i < win_index; i++)
|
||||
set_item = set_item->next;
|
||||
|
||||
cursor->x = set_item->widget->x;
|
||||
cursor->y = set_item->widget->y;
|
||||
|
||||
to_be_focused_win = set_item->widget->id;
|
||||
Gui.Widget.SetText(caption, set_item->widget->tag);
|
||||
caption->width = Print2D(NULL, Compositor.theme.font.menu, 0, 0, , , &caption->text);
|
||||
caption->x = (win->width / 2) - (caption->width / 2);
|
||||
caption->y = win->height - 24;
|
||||
|
||||
Gui.Window.Refresh(win);
|
||||
task_switcher_invoke = FALSE;
|
||||
}
|
||||
|
||||
U0 @taskswitcher_clear_win_thumbs(Window* win)
|
||||
{
|
||||
@window_widgets_list* iter_widget = win->widget;
|
||||
@window_widgets_list* del_widget = NULL;
|
||||
while (iter_widget->next)
|
||||
iter_widget = iter_widget->next;
|
||||
while (iter_widget->widget->type == WIDGET_TYPE_CONTEXT2D) {
|
||||
iter_widget = iter_widget->prev;
|
||||
del_widget = iter_widget->next;
|
||||
iter_widget->next = NULL;
|
||||
if (del_widget->widget(Context2DWidget*)->ctx)
|
||||
DelContext2D(del_widget->widget(Context2DWidget*)->ctx);
|
||||
Free(del_widget->widget->tag);
|
||||
Free(del_widget->widget);
|
||||
Free(del_widget);
|
||||
}
|
||||
Gui.Widget.SetText(caption, "");
|
||||
}
|
||||
|
||||
U0 @taskswitcher_render_win_thumbs(Window* win)
|
||||
{
|
||||
@compositor_windows_list* origin_list;
|
||||
@compositor_windows_list* iter_list;
|
||||
Context2DWidget* widget = NULL;
|
||||
cursor = Gui.CreateWidget(win, WIDGET_TYPE_CONTEXT2D, -999, -999,
|
||||
win_thumb_container_size, win_thumb_container_size);
|
||||
cursor->ctx = NewContext2D(win_thumb_container_size, win_thumb_container_size);
|
||||
Fill2D(cursor->ctx, Compositor.theme.color.hilight);
|
||||
|
||||
I64 min_caption_width = 0;
|
||||
win_items = 0;
|
||||
I64 cur_item = 0;
|
||||
I64 item_offset = 0;
|
||||
|
||||
origin_list = Compositor.windows->next;
|
||||
while (origin_list->next)
|
||||
origin_list = origin_list->next;
|
||||
|
||||
iter_list = origin_list;
|
||||
while (iter_list) {
|
||||
if (iter_list->window)
|
||||
if (!@gui_window_flag_is_set(iter_list->window, WIN_FLAGS_SKIP)) {
|
||||
min_caption_width = Max(min_caption_width,
|
||||
Print2D(NULL, Compositor.theme.font.menu, 0, 0, , ,
|
||||
"%s - [%dx%d] at [%d, %d]", iter_list->window->title,
|
||||
iter_list->window->width, iter_list->window->height,
|
||||
iter_list->window->x, iter_list->window->y));
|
||||
win_items++;
|
||||
}
|
||||
iter_list = iter_list->prev;
|
||||
}
|
||||
|
||||
win->width = Max((win_thumb_container_size * win_items) + T(win_items, 4, 0),
|
||||
64 + min_caption_width);
|
||||
|
||||
item_offset = (win->width / 2) - (((win_thumb_container_size * win_items) + T(win_items, 0, 0)) / 2);
|
||||
|
||||
iter_list = origin_list;
|
||||
while (iter_list) {
|
||||
if (iter_list->window)
|
||||
if (!@gui_window_flag_is_set(iter_list->window, WIN_FLAGS_SKIP)) {
|
||||
widget = Gui.CreateWidget(
|
||||
win, WIDGET_TYPE_CONTEXT2D,
|
||||
(win_thumb_container_size * cur_item) + item_offset, 0,
|
||||
win_thumb_container_size, win_thumb_container_size);
|
||||
widget->ctx = NewContext2D(win_thumb_container_size, win_thumb_container_size);
|
||||
Fill2D(widget->ctx, NULL);
|
||||
win_scale = 1.0;
|
||||
while (iter_list->window->backing_store->width * win_scale > win_thumb_size || iter_list->window->backing_store->height * win_scale > win_thumb_size)
|
||||
win_scale -= 0.001;
|
||||
|
||||
win_scaled = Scale2D(iter_list->window->backing_store, win_scale, win_scale);
|
||||
Fill2D(widget->ctx, NULL);
|
||||
Blot2D(widget->ctx,
|
||||
(win_thumb_container_size / 2) - (win_scaled->width / 2),
|
||||
(win_thumb_container_size / 2) - (win_scaled->height / 2),
|
||||
win_scaled);
|
||||
DelContext2D(win_scaled);
|
||||
widget->tag = CAlloc(256);
|
||||
StrPrint(widget->tag, "%s - [%dx%d] at [%d, %d]",
|
||||
iter_list->window->title, iter_list->window->width,
|
||||
iter_list->window->height, iter_list->window->x,
|
||||
iter_list->window->y);
|
||||
widget->id = iter_list->window; // FIXME: We are abusing this property,
|
||||
// introduce a better way to do this
|
||||
|
||||
cur_item++;
|
||||
}
|
||||
iter_list = iter_list->prev;
|
||||
}
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Gui.Window.SetTitle(win, "TaskSwitcher");
|
||||
Gui.Window.EnableAlphaChannel(win);
|
||||
Gui.Window.SetOpacity(win, 224);
|
||||
Compositor.RegisterForGlobalInputEvents(win);
|
||||
Gui.Window.SetCallback(win, "keypress", &keypress_callback);
|
||||
Gui.Window.Hide(win);
|
||||
|
||||
while (1) {
|
||||
if (KeyDown(SC_ALT) && KeyDown(SC_TAB))
|
||||
task_switcher_active = TRUE;
|
||||
if (!KeyDown(SC_ALT))
|
||||
task_switcher_active = FALSE;
|
||||
switch (task_switcher_active) {
|
||||
case TRUE:
|
||||
if (!to_be_focused_win) {
|
||||
to_be_focused_win = Compositor.active_win;
|
||||
task_switcher_invoke = TRUE;
|
||||
@taskswitcher_render_win_thumbs(win);
|
||||
Gui.Window.Center(win);
|
||||
Gui.Window.SetFocus(win);
|
||||
Gui.Window.Show(win);
|
||||
}
|
||||
break;
|
||||
case FALSE:
|
||||
if (to_be_focused_win) {
|
||||
Gui.Window.SetFocus(to_be_focused_win);
|
||||
Gui.Window.Show(to_be_focused_win);
|
||||
to_be_focused_win = NULL;
|
||||
Gui.Window.Hide(win);
|
||||
@taskswitcher_clear_win_thumbs(win);
|
||||
win_index = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
Main;
|
127
Applications/OS/TempleOS.app/Run.HC
Normal file
|
@ -0,0 +1,127 @@
|
|||
Gui.App();
|
||||
|
||||
U32 tos_palette_std[16] = {
|
||||
Color(0, 0, 0), Color(0, 0, 170), Color(0, 170, 0),
|
||||
Color(0, 170, 170), Color(170, 0, 0), Color(170, 0, 170),
|
||||
Color(170, 85, 0), Color(170, 170, 170), Color(85, 85, 85),
|
||||
Color(85, 85, 255), Color(85, 255, 85), Color(85, 255, 255),
|
||||
Color(255, 85, 85), Color(255, 85, 255), Color(255, 255, 85),
|
||||
Color(255, 255, 255)
|
||||
};
|
||||
|
||||
I64 win_mouse_x = ms.pos.x;
|
||||
I64 win_mouse_y = ms.pos.y;
|
||||
|
||||
CTask* templeos_winmgr_task = NULL;
|
||||
|
||||
U0 @templeos_close_callback(Window* win)
|
||||
{
|
||||
Kill(templeos_winmgr_task);
|
||||
Compositor.UnregisterForGlobalInputEvents(win);
|
||||
Compositor.DestroyWindow(win);
|
||||
win = NULL;
|
||||
Exit;
|
||||
}
|
||||
|
||||
Context2D* win_hide_pointer_ctx = NewContext2D(4, 4);
|
||||
|
||||
U0 @templeos_mouseat_callback(Window* win)
|
||||
{
|
||||
win_mouse_x = win->mouse.x - 4;
|
||||
win_mouse_y = win->mouse.y - 24;
|
||||
if (win_mouse_x > 0 && win_mouse_x < 640 && win_mouse_y > 0 && win_mouse_y < 480) {
|
||||
win->pointer = win_hide_pointer_ctx;
|
||||
} else {
|
||||
win->pointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @templeos_keypress_callback(Window* win, I64 key)
|
||||
{
|
||||
if (win != Compositor.active_win)
|
||||
return;
|
||||
if (!KeyDown(SC_GUI) && key) {
|
||||
if (KeyDown(SC_CURSOR_UP)) {
|
||||
PostMsg(sys_focus_task, MSG_KEY_DOWN_UP, 0, SC_CURSOR_UP);
|
||||
return;
|
||||
}
|
||||
if (KeyDown(SC_CURSOR_DOWN)) {
|
||||
PostMsg(sys_focus_task, MSG_KEY_DOWN_UP, 0, SC_CURSOR_DOWN);
|
||||
return;
|
||||
}
|
||||
if (KeyDown(SC_CURSOR_LEFT)) {
|
||||
PostMsg(sys_focus_task, MSG_KEY_DOWN_UP, 0, SC_CURSOR_LEFT);
|
||||
return;
|
||||
}
|
||||
if (KeyDown(SC_CURSOR_RIGHT)) {
|
||||
PostMsg(sys_focus_task, MSG_KEY_DOWN_UP, 0, SC_CURSOR_RIGHT);
|
||||
return;
|
||||
}
|
||||
// FIXME: Ctrl-key combinations
|
||||
if (KeyDown(SC_SHIFT)) {
|
||||
XTalkWait(sys_focus_task, "%c", SHIFT_KEY_SCAN_DECODE_TABLE(U8*)[key]);
|
||||
} else {
|
||||
XTalkWait(sys_focus_task, "%c", NORMAL_KEY_SCAN_DECODE_TABLE(U8*)[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context2D* icon = Image.FileToContext2D("window_icon_16x16.png");
|
||||
|
||||
Window* win = Compositor.CreateWindow(
|
||||
18, 554, 649, 508,
|
||||
(WIN_FLAGS_MOVABLE | WIN_FLAGS_ICON | WIN_FLAGS_TITLE_BAR | WIN_FLAGS_MIN_BUTTON | WIN_FLAGS_CLOSE_BUTTON),
|
||||
"TempleOS Window Manager", icon);
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Gui.Window.Refresh(win);
|
||||
Compositor.RegisterForGlobalInputEvents(win);
|
||||
Gui.Window.SetCallback(win, "close", &@templeos_close_callback);
|
||||
Gui.Window.SetCallback(win, "keypress", &@templeos_keypress_callback);
|
||||
Gui.Window.SetCallback(win, "mouseat", &@templeos_mouseat_callback);
|
||||
|
||||
Gui.Window.SetFocus(win);
|
||||
|
||||
while (win) {
|
||||
if (win == Compositor.active_win) {
|
||||
win->flags |= WIN_FLAGS_NOFILL;
|
||||
if (IsSuspended(sys_winmgr_task)) {
|
||||
keydev.fp_ctrl_alt_cbs = tos_fp_cbs_enabled;
|
||||
Suspend(sys_winmgr_task, FALSE);
|
||||
}
|
||||
ms.pos.x = win_mouse_x;
|
||||
ms.pos.y = win_mouse_y;
|
||||
} else {
|
||||
if (!IsSuspended(sys_winmgr_task)) {
|
||||
keydev.fp_ctrl_alt_cbs = tos_fp_cbs_disabled;
|
||||
Suspend(sys_winmgr_task, TRUE);
|
||||
}
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
U0 @templeos_winmgr_redraw()
|
||||
{
|
||||
CDC* dc;
|
||||
I64 x, y;
|
||||
while (1) {
|
||||
dc = DCScrnCapture;
|
||||
for (y = 0; y < GR_HEIGHT; y++) {
|
||||
for (x = 0; x < GR_WIDTH; x++) {
|
||||
Plot2D(win->render_ctx, x + 4, y + 24,
|
||||
tos_palette_std[dc->body[(y * dc->width) + x]]);
|
||||
Plot2D(win->backing_store, x + 4, y + 24,
|
||||
tos_palette_std[dc->body[(y * dc->width) + x]]);
|
||||
}
|
||||
}
|
||||
DCDel(dc);
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
templeos_winmgr_task = Spawn(&@templeos_winmgr_redraw, , , 3);
|
||||
// Adam("blkdev.boot_drv_let='C';WinFocus(User(\"WinMax;\n\"));\n");
|
||||
|
||||
Main;
|
BIN
Applications/OS/TempleOS.app/window_icon_16x16.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
Applications/OS/Terminal.app/Icon.png
Normal file
After Width: | Height: | Size: 689 B |
205
Applications/OS/Terminal.app/Run.HC
Normal file
|
@ -0,0 +1,205 @@
|
|||
Gui.App();
|
||||
|
||||
Window* win = Compositor.CreateWindow(18, 62, 684, 474, WIN_FLAGS_DEFAULT);
|
||||
Gui.Window.EnableAlphaChannel(win);
|
||||
Gui.Window.SetOpacity(win, 224);
|
||||
Gui.Window.SetIcon(win, Image.FileToContext2D("Icon.png"));
|
||||
Gui.Window.SetTitle(win, "Terminal");
|
||||
|
||||
TerminalWidget* active_term = NULL;
|
||||
@shell* sh = NULL;
|
||||
|
||||
U0 @terminal_keypress_callback(Window* win, I64 key)
|
||||
{
|
||||
if (!active_term || Compositor.active_win != win)
|
||||
return;
|
||||
I64 i;
|
||||
U8 send_key[4];
|
||||
MemSetU32(&send_key, 0, 1);
|
||||
switch (key) {
|
||||
case SC_CURSOR_UP:
|
||||
send_key[0] = '\x1b';
|
||||
send_key[1] = '[';
|
||||
send_key[2] = 'A';
|
||||
break;
|
||||
case SC_CURSOR_DOWN:
|
||||
send_key[0] = '\x1b';
|
||||
send_key[1] = '[';
|
||||
send_key[2] = 'B';
|
||||
break;
|
||||
case SC_CURSOR_LEFT:
|
||||
send_key[0] = '\x1b';
|
||||
send_key[1] = '[';
|
||||
send_key[2] = 'D';
|
||||
break;
|
||||
case SC_CURSOR_RIGHT:
|
||||
send_key[0] = '\x1b';
|
||||
send_key[1] = '[';
|
||||
send_key[2] = 'C';
|
||||
break;
|
||||
case SC_DELETE:
|
||||
send_key[0] = 21;
|
||||
break;
|
||||
case SC_BACKSPACE:
|
||||
send_key[0] = 8;
|
||||
break;
|
||||
case SC_TAB:
|
||||
send_key[0] = 9;
|
||||
break;
|
||||
case SC_ENTER:
|
||||
send_key[0] = 10;
|
||||
break;
|
||||
case SC_HOME:
|
||||
send_key[0] = 22;
|
||||
break;
|
||||
case SC_END:
|
||||
send_key[0] = 23;
|
||||
break;
|
||||
case SC_PAGE_UP:
|
||||
send_key[0] = 24;
|
||||
break;
|
||||
case SC_PAGE_DOWN:
|
||||
send_key[0] = 25;
|
||||
break;
|
||||
case SC_ESC:
|
||||
send_key[0] = 27;
|
||||
break;
|
||||
case 0x02 ... 0x0D:
|
||||
case 0x10 ... 0x1B:
|
||||
case 0x1E ... 0x29:
|
||||
case 0x2B ... 0x35:
|
||||
case 0x39:
|
||||
if (!KeyDown(SC_SHIFT)) {
|
||||
if (KeyDown(SC_CTRL)) {
|
||||
switch (key) {
|
||||
case Char2ScanCode('c'):
|
||||
send_key[0] = 0x03;
|
||||
sh->break = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
send_key[0] = NORMAL_KEY_SCAN_DECODE_TABLE(U8*)[key];
|
||||
}
|
||||
} else {
|
||||
if (key == 0x39) // Handle TempleOS SHIFT-SPACE character.
|
||||
send_key[0] = ' ';
|
||||
else {
|
||||
if (KeyDown(SC_CTRL)) {
|
||||
// terminal copy paste handling
|
||||
} else {
|
||||
send_key[0] = SHIFT_KEY_SCAN_DECODE_TABLE(U8*)[key];
|
||||
}
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
if (send_key[i] && active_term->output)
|
||||
FifoU8Ins(active_term->output, send_key[i]);
|
||||
}
|
||||
|
||||
TerminalWidget* t = Gui.CreateWidget(win, WIDGET_TYPE_TERMINAL, 0, 0, 120, 120);
|
||||
t->pointer = Compositor.theme.pointer.text;
|
||||
VerticalScrollBarWidget* vscroll = Gui.CreateWidget(win, WIDGET_TYPE_VERT_SCROLLBAR, 0, 0, 16, 128);
|
||||
vscroll->height = 128;
|
||||
Context2DWidget* status = Gui.CreateWidget(win, WIDGET_TYPE_CONTEXT2D, 0, 0, Display.Width(), 44);
|
||||
status->ctx = NewContext2D(Display.Width(), 44);
|
||||
Fill2D(status->ctx, Color(204, 204, 204, win->opacity));
|
||||
|
||||
U0 @terminal_create_new_instance()
|
||||
{
|
||||
U32 init_bg_color = t->color.background;
|
||||
init_bg_color.u8[3] = win->opacity;
|
||||
Fill2D(t->backing_store, init_bg_color);
|
||||
active_term = t;
|
||||
sh = @shell_new;
|
||||
sh->session = &Compositor.session;
|
||||
t->output = sh->input;
|
||||
sh->output = t->input;
|
||||
}
|
||||
|
||||
U0 window_close(Window* win)
|
||||
{
|
||||
if (sh)
|
||||
if (sh->task && sh->exit)
|
||||
Free(sh);
|
||||
if (win == Compositor.active_win)
|
||||
Gui.Window.SetFocus(Compositor.GetWindowByTitle("Wallpaper"));
|
||||
Compositor.UnregisterForGlobalInputEvents(win);
|
||||
Compositor.DestroyWindow(win);
|
||||
}
|
||||
|
||||
U0 @terminal_vscroll_change(Widget*)
|
||||
{
|
||||
I64 i = 0;
|
||||
I64 max_scroll = vscroll->height - 32;
|
||||
F64 f1 = (ToF64(max_scroll) / ToF64(t->cursor.y + t->max.y - 2));
|
||||
while (vscroll->scroll > ToI64(i * f1))
|
||||
i++;
|
||||
t->scroll.y = i;
|
||||
t->refresh = TRUE;
|
||||
Gui.Window.Refresh(win);
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Compositor.RegisterForGlobalInputEvents(win);
|
||||
Gui.Window.SetCallback(win, "keypress", &@terminal_keypress_callback);
|
||||
Gui.Widget.SetCallback(vscroll, "change", &@terminal_vscroll_change);
|
||||
I64 prev_width = -1;
|
||||
I64 prev_height = -1;
|
||||
I64 prev_max_x = -1;
|
||||
I64 prev_max_y = -1;
|
||||
F64 f1;
|
||||
Gui.Window.SetFocus(win);
|
||||
Gui.Window.SetCallback(win, "close", &window_close);
|
||||
|
||||
@terminal_create_new_instance;
|
||||
|
||||
while (win) {
|
||||
// FIXME: This should be event-driven...
|
||||
if (win->width != prev_width || win->height != prev_height) {
|
||||
win->width = 3 + RoundI64(win->width, 8);
|
||||
win->height = RoundI64(win->height, 16);
|
||||
prev_width = win->width;
|
||||
prev_height = win->height;
|
||||
if (active_term) {
|
||||
active_term->width = win->width;
|
||||
active_term->height = win->height;
|
||||
}
|
||||
status->y = win->height - 44;
|
||||
goto terminal_update_vscroll;
|
||||
}
|
||||
if (prev_max_x != t->max.x || prev_max_y != t->max.y) {
|
||||
terminal_update_vscroll:
|
||||
if (!t->max.y) {
|
||||
vscroll->x = Display.Width(); // Hide
|
||||
} else {
|
||||
vscroll->x = win->width - vscroll->width - 9;
|
||||
vscroll->height = win->height - 44;
|
||||
f1 = (ToF64(t->size.rows) / ToF64(1 + t->cursor.y + t->max.y));
|
||||
vscroll->length = ToI64((vscroll->height - 32) * f1);
|
||||
vscroll->scroll = vscroll->height;
|
||||
}
|
||||
prev_max_x = t->max.x;
|
||||
prev_max_y = t->max.y;
|
||||
// System.Log(Fs, "vscroll->scroll: %d", vscroll->scroll);
|
||||
|
||||
Gui.Window.Refresh(win);
|
||||
}
|
||||
if (FifoU8Cnt(active_term->input))
|
||||
Gui.Window.Refresh(win);
|
||||
if (sh->exit) {
|
||||
win->callback.close(win);
|
||||
return;
|
||||
}
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
Main;
|
29
Applications/OS/Wallpaper.app/Run.HC
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Gui.App();
|
||||
|
||||
U0 @event_loop(CTask* task)
|
||||
{
|
||||
Fs->ipc = task->ipc;
|
||||
IpcMessage* msg;
|
||||
while (1) {
|
||||
msg = Ipc.MsgRecv();
|
||||
if (msg) {
|
||||
Free(msg);
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ipc.InitQueue(Fs);
|
||||
Spawn(&@event_loop, Fs);
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
System.Log(Fs, "Task running at 0x%08x", Fs);
|
||||
Window* win = Compositor.CreateWindow(0, 0, Display.Width(), Display.Height(),
|
||||
WIN_FLAGS_NO_REINDEX | WIN_FLAGS_SKIP,
|
||||
"Wallpaper");
|
||||
Compositor.SetWallpaper(Compositor.theme.wallpaper);
|
||||
Suspend;
|
||||
}
|
||||
|
||||
Main;
|
96
Applications/TestApplication.app/Run.HC
Normal file
|
@ -0,0 +1,96 @@
|
|||
#include "M:/Include/Gui";
|
||||
|
||||
U0 window_close(Window* win) { Compositor.DestroyWindow(win); }
|
||||
|
||||
U0 btn1_click(Widget* widget)
|
||||
{
|
||||
no_warn widget;
|
||||
Window* win = Compositor.CreateWindow(Rand * Display.Width(), Rand * Display.Height(),
|
||||
320, 240, WIN_FLAGS_DEFAULT);
|
||||
win->callback.close = &window_close;
|
||||
Gui.Window.SetTitle(win, "New Window");
|
||||
Gui.Window.SetFocus(win);
|
||||
}
|
||||
|
||||
U0 btn2_click(Widget*)
|
||||
{
|
||||
System.text_mode = TRUE;
|
||||
Dbg;
|
||||
}
|
||||
|
||||
U0 hs1_change(HorizontalSliderWidget* widget)
|
||||
{
|
||||
Gui.Window.SetOpacity(widget->parent_win,
|
||||
ClampI64(1.4 * widget->scroll, 0, 255));
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
Window* win = Compositor.CreateWindow(240, 240, 662, 504, WIN_FLAGS_DEFAULT);
|
||||
win->alpha = TRUE;
|
||||
Gui.Window.Center(win);
|
||||
Gui.Window.SetTitle(win, "Test Application");
|
||||
|
||||
TextInputWidget* label1 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 8, 0, 192, 64);
|
||||
Gui.Widget.SetText(label1,
|
||||
"\n"
|
||||
"Welcome to Erythros desktop environment for TempleOS!\n"
|
||||
"\n"
|
||||
"This is a test application for Gui Widgets. "
|
||||
"There will be bugs. Please report them! :)\n"
|
||||
"\n");
|
||||
|
||||
ButtonWidget* btn1 = Gui.CreateWidget(win, WIDGET_TYPE_BUTTON, 8, 56, 192, 32);
|
||||
Gui.Widget.SetText(btn1, "Click me for a new Window");
|
||||
|
||||
ButtonWidget* btn2 = Gui.CreateWidget(win, WIDGET_TYPE_BUTTON, 224, 56, 256, 32);
|
||||
Gui.Widget.SetText(btn2, "Click me to open TempleOS Debugger");
|
||||
|
||||
btn1->callback.clicked = &btn1_click;
|
||||
btn2->callback.clicked = &btn2_click;
|
||||
|
||||
CheckBoxWidget* cb1 = Gui.CreateWidget(win, WIDGET_TYPE_CHECKBOX, 8, 160, 14, 14);
|
||||
TextInputWidget* label2 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 32, 162, 100, 14);
|
||||
Gui.Widget.SetText(label2, "Some random checkbox");
|
||||
|
||||
RadioButtonWidget* radio1 = Gui.CreateWidget(win, WIDGET_TYPE_RADIO, 192, 160, 14, 14);
|
||||
RadioButtonWidget* radio2 = Gui.CreateWidget(win, WIDGET_TYPE_RADIO, 192, 180, 14, 14);
|
||||
RadioButtonWidget* radio3 = Gui.CreateWidget(win, WIDGET_TYPE_RADIO, 192, 200, 14, 14);
|
||||
TextInputWidget* label3 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 216, 162, 192, 14);
|
||||
Gui.Widget.SetText(label3, "Radio #1");
|
||||
TextInputWidget* label4 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 216, 182, 192, 14);
|
||||
Gui.Widget.SetText(label4, "Radio #2");
|
||||
TextInputWidget* label5 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 216, 202, 192, 14);
|
||||
Gui.Widget.SetText(label5, "Radio #3");
|
||||
|
||||
Gui.Widget.SetEcho(label2, cb1);
|
||||
Gui.Widget.SetEcho(label3, radio1);
|
||||
Gui.Widget.SetEcho(label4, radio2);
|
||||
Gui.Widget.SetEcho(label5, radio3);
|
||||
|
||||
HorizontalSliderWidget* hs1 = Gui.CreateWidget(win, WIDGET_TYPE_HORZ_SLIDER, 338, 192, 192, 64);
|
||||
hs1->max = 100;
|
||||
hs1->scroll = (hs1->width / 5) * 4.25;
|
||||
hs1->callback.change = &hs1_change;
|
||||
TextInputWidget* label6 = Gui.CreateWidget(win, WIDGET_TYPE_LABEL, 398, 220, 192, 64);
|
||||
Gui.Widget.SetText(label6, "Window Opacity");
|
||||
|
||||
VerticalSliderWidget* vs1 = Gui.CreateWidget(win, WIDGET_TYPE_VERT_SLIDER, 576, 192, 64, 192);
|
||||
vs1->max = 100;
|
||||
vs1->scroll = hs1->height / 2;
|
||||
|
||||
Gui.Widget.SetEcho(vs1, hs1);
|
||||
|
||||
TextInputWidget* input1 = Gui.CreateWidget(win, WIDGET_TYPE_INPUT, 8, 320, 256, 64);
|
||||
input1->font = BitmapFonts.GetByName("Eight Bit Dragon");
|
||||
Gui.Widget.SetText(input1, "this is some sample text");
|
||||
|
||||
Gui.Window.SetFocus(win);
|
||||
Gui.Window.Refresh(win);
|
||||
|
||||
Gui.Window.SetOpacity(win, ClampI64(1.4 * hs1->scroll, 0, 255));
|
||||
|
||||
Suspend;
|
||||
}
|
||||
|
||||
Main;
|
53
Include/Gui.HC
Normal file
|
@ -0,0 +1,53 @@
|
|||
U0 @gui_event_loop(CTask* task)
|
||||
{
|
||||
Fs->ipc = task->ipc;
|
||||
IpcMessage* msg;
|
||||
while (1) {
|
||||
msg = Ipc.MsgRecv();
|
||||
if (msg) {
|
||||
switch (msg->type) {
|
||||
// TODO:
|
||||
case CPZ_MSG_WIN_WIDGET_DESTROY:
|
||||
@gui_widget_destroy(msg->payload);
|
||||
case CPZ_MSG_WIN_MOVE_TO:
|
||||
break;
|
||||
case CPZ_MSG_WIN_KEY_PRESS:
|
||||
if (msg->payload(Window*)->callback.keypress)
|
||||
msg->payload(Window*)->callback.keypress(msg->payload, msg->i64);
|
||||
@gui_window_repaint(msg->payload, msg->type);
|
||||
Compositor.theme.window_repaint(msg->payload, msg->type);
|
||||
if (msg->payload(Window*)->callback.repaint)
|
||||
msg->payload(Window*)->callback.repaint(msg->payload);
|
||||
break;
|
||||
case CPZ_MSG_WIN_MOUSE_AT:
|
||||
if (msg->payload(Window*)->callback.mouseat)
|
||||
msg->payload(Window*)->callback.mouseat(msg->payload);
|
||||
@gui_window_repaint(msg->payload, msg->type);
|
||||
Compositor.theme.window_repaint(msg->payload, msg->type);
|
||||
if (msg->payload(Window*)->callback.repaint)
|
||||
msg->payload(Window*)->callback.repaint(msg->payload);
|
||||
break;
|
||||
case CPZ_MSG_WIN_MOUSE_WHEEL:
|
||||
case CPZ_MSG_WIN_LEFT_BTN_UP:
|
||||
case CPZ_MSG_WIN_LEFT_BTN_DOWN:
|
||||
case CPZ_MSG_WIN_RIGHT_BTN_UP:
|
||||
case CPZ_MSG_WIN_RIGHT_BTN_DOWN:
|
||||
case CPZ_MSG_WIN_REPAINT:
|
||||
@gui_window_repaint(msg->payload, msg->type);
|
||||
Compositor.theme.window_repaint(msg->payload, msg->type);
|
||||
if (msg->payload(Window*)->callback.repaint)
|
||||
msg->payload(Window*)->callback.repaint(msg->payload);
|
||||
break;
|
||||
// FIXME: add CPZ_MSG_WIN_RESIZE
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Free(msg);
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ipc.InitQueue(Fs);
|
||||
Spawn(&@gui_event_loop, Fs, Fs->task_name, 1);
|
||||
System.Log(Fs, "Task running at 0x%08x", Fs);
|
BIN
Media/Sounds/Beep.wav
Normal file
BIN
Media/Themes/Umami/BitmapFont/menu.png
Normal file
After Width: | Height: | Size: 726 B |
BIN
Media/Themes/Umami/BitmapFont/monospace.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Media/Themes/Umami/BitmapFont/sans.png
Normal file
After Width: | Height: | Size: 606 B |
BIN
Media/Themes/Umami/Icon/actions/add.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
Media/Themes/Umami/Icon/actions/address-book-new.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/appointment-new.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Media/Themes/Umami/Icon/actions/appointment.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Media/Themes/Umami/Icon/actions/back.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/bookmark-new.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/bookmark_add.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/bookmarks_list_add.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/bottom.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/centrejust.png
Normal file
After Width: | Height: | Size: 694 B |
BIN
Media/Themes/Umami/Icon/actions/contact-new.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/document-new.png
Normal file
After Width: | Height: | Size: 851 B |
BIN
Media/Themes/Umami/Icon/actions/document-open.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/document-print-preview.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Media/Themes/Umami/Icon/actions/document-print.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/document-properties.png
Normal file
After Width: | Height: | Size: 767 B |
BIN
Media/Themes/Umami/Icon/actions/document-save-as.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/document-save.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/down.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/edit-clear.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Media/Themes/Umami/Icon/actions/edit-copy.png
Normal file
After Width: | Height: | Size: 891 B |
BIN
Media/Themes/Umami/Icon/actions/edit-cut.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/edit-delete.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Media/Themes/Umami/Icon/actions/edit-find-replace.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/edit-find.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/edit-paste.png
Normal file
After Width: | Height: | Size: 945 B |
BIN
Media/Themes/Umami/Icon/actions/edit-redo.png
Normal file
After Width: | Height: | Size: 960 B |
BIN
Media/Themes/Umami/Icon/actions/edit-select-all.png
Normal file
After Width: | Height: | Size: 781 B |
BIN
Media/Themes/Umami/Icon/actions/edit-undo.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/editclear.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Media/Themes/Umami/Icon/actions/editcopy.png
Normal file
After Width: | Height: | Size: 891 B |
BIN
Media/Themes/Umami/Icon/actions/editcut.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/editdelete.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Media/Themes/Umami/Icon/actions/editpaste.png
Normal file
After Width: | Height: | Size: 945 B |
BIN
Media/Themes/Umami/Icon/actions/exit.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/filefind.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/filenew.png
Normal file
After Width: | Height: | Size: 851 B |
BIN
Media/Themes/Umami/Icon/actions/fileopen.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/fileprint.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/filequickprint.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Media/Themes/Umami/Icon/actions/filesave.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/filesaveas.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/find.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/finish.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/folder-new.png
Normal file
After Width: | Height: | Size: 1,014 B |
BIN
Media/Themes/Umami/Icon/actions/folder_new.png
Normal file
After Width: | Height: | Size: 1,014 B |
BIN
Media/Themes/Umami/Icon/actions/format-indent-less.png
Normal file
After Width: | Height: | Size: 840 B |
BIN
Media/Themes/Umami/Icon/actions/format-indent-more.png
Normal file
After Width: | Height: | Size: 854 B |
BIN
Media/Themes/Umami/Icon/actions/format-justify-center.png
Normal file
After Width: | Height: | Size: 694 B |
BIN
Media/Themes/Umami/Icon/actions/format-justify-fill.png
Normal file
After Width: | Height: | Size: 683 B |
BIN
Media/Themes/Umami/Icon/actions/format-justify-left.png
Normal file
After Width: | Height: | Size: 684 B |
BIN
Media/Themes/Umami/Icon/actions/format-justify-right.png
Normal file
After Width: | Height: | Size: 696 B |
BIN
Media/Themes/Umami/Icon/actions/format-text-bold.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/format-text-italic.png
Normal file
After Width: | Height: | Size: 952 B |
BIN
Media/Themes/Umami/Icon/actions/format-text-strikethrough.png
Normal file
After Width: | Height: | Size: 948 B |
BIN
Media/Themes/Umami/Icon/actions/format-text-underline.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/forward.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-lockscreen.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-logout.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-searchtool.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-session-logout.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-shutdown.png
Normal file
After Width: | Height: | Size: 883 B |
BIN
Media/Themes/Umami/Icon/actions/gnome-stock-mail-fwd.png
Normal file
After Width: | Height: | Size: 985 B |
BIN
Media/Themes/Umami/Icon/actions/gnome-stock-mail-new.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-stock-mail-rpl.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Media/Themes/Umami/Icon/actions/gnome-stock-text-indent.png
Normal file
After Width: | Height: | Size: 854 B |
BIN
Media/Themes/Umami/Icon/actions/gnome-stock-text-unindent.png
Normal file
After Width: | Height: | Size: 840 B |
BIN
Media/Themes/Umami/Icon/actions/go-bottom.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Media/Themes/Umami/Icon/actions/go-down.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Media/Themes/Umami/Icon/actions/go-first.png
Normal file
After Width: | Height: | Size: 1.1 KiB |