mirror of https://gitlab.com/nakst/essence
desktop: use color scheme to determine wallpaper background; fade transition when changing color scheme
This commit is contained in:
parent
6f074e12f9
commit
d9a8557568
|
@ -201,9 +201,12 @@ struct {
|
|||
HashStore<EsObjectID, OpenDocument> openDocuments;
|
||||
|
||||
TaskBar taskBar;
|
||||
EsWindow *wallpaperWindow;
|
||||
EsButton *tasksButton;
|
||||
|
||||
EsWindow *wallpaperWindow;
|
||||
uint32_t wallpaperBackgroundColor;
|
||||
bool isWallpaperBackgroundColorVisible; // If true, then the wallpaper needs to be reloaded when the background color changes.
|
||||
|
||||
bool setupDesktopUIComplete;
|
||||
uint8_t installationState;
|
||||
bool desktopInspectorOpen;
|
||||
|
@ -634,8 +637,8 @@ int CursorLocatorMessage(EsElement *element, EsMessage *message) {
|
|||
EsWindow *window = element->window;
|
||||
|
||||
if (message->type == ES_MSG_ANIMATE) {
|
||||
window->announcementTimeMs += message->animate.deltaMs;
|
||||
double progress = window->announcementTimeMs / GetConstantNumber("cursorLocatorDuration");
|
||||
window->animationTime += message->animate.deltaMs;
|
||||
double progress = window->animationTime / GetConstantNumber("cursorLocatorDuration");
|
||||
|
||||
if (progress > 1) {
|
||||
EsElementDestroy(window);
|
||||
|
@ -646,7 +649,7 @@ int CursorLocatorMessage(EsElement *element, EsMessage *message) {
|
|||
}
|
||||
} else if (message->type == ES_MSG_LAYOUT) {
|
||||
EsElement *child = element->GetChild(0);
|
||||
double progress = 1.0 - window->announcementTimeMs / GetConstantNumber("cursorLocatorDuration");
|
||||
double progress = 1.0 - window->animationTime / GetConstantNumber("cursorLocatorDuration");
|
||||
int width = progress * child->GetWidth(0), height = progress * child->GetHeight(0);
|
||||
child->InternalMove(width, height, (element->width - width) / 2, (element->height - height) / 2);
|
||||
}
|
||||
|
@ -2600,17 +2603,23 @@ void WallpaperLoad(EsGeneric) {
|
|||
size_t pathBytes;
|
||||
char *path = EsSystemConfigurationReadString(EsLiteral("general"), EsLiteral("wallpaper"), &pathBytes);
|
||||
|
||||
if (path) {
|
||||
void *buffer = EsHeapAllocate(desktop.wallpaperWindow->windowWidth * desktop.wallpaperWindow->windowHeight * 4, false);
|
||||
LoadImage(path, pathBytes, buffer, desktop.wallpaperWindow->windowWidth, desktop.wallpaperWindow->windowHeight, false);
|
||||
EsHeapFree(path);
|
||||
void *buffer = EsHeapAllocate(desktop.wallpaperWindow->windowWidth * desktop.wallpaperWindow->windowHeight * 4, false);
|
||||
|
||||
EsRectangle region = ES_RECT_2S(desktop.wallpaperWindow->windowWidth, desktop.wallpaperWindow->windowHeight);
|
||||
EsSyscall(ES_SYSCALL_WINDOW_SET_BITS, desktop.wallpaperWindow->handle, (uintptr_t) ®ion, (uintptr_t) buffer, 0);
|
||||
EsSyscall(ES_SYSCALL_SCREEN_FORCE_UPDATE, true, 0, 0, 0);
|
||||
for (uintptr_t i = 0; i < desktop.wallpaperWindow->windowWidth * desktop.wallpaperWindow->windowHeight; i++) {
|
||||
((uint32_t *) buffer)[i] = desktop.wallpaperBackgroundColor;
|
||||
}
|
||||
|
||||
bool coversDestination;
|
||||
if (path) LoadImage(path, pathBytes, buffer, desktop.wallpaperWindow->windowWidth, desktop.wallpaperWindow->windowHeight, false, &coversDestination);
|
||||
desktop.isWallpaperBackgroundColorVisible = !coversDestination;
|
||||
|
||||
EsRectangle region = ES_RECT_2S(desktop.wallpaperWindow->windowWidth, desktop.wallpaperWindow->windowHeight);
|
||||
EsSyscall(ES_SYSCALL_WINDOW_SET_BITS, desktop.wallpaperWindow->handle, (uintptr_t) ®ion, (uintptr_t) buffer, 0);
|
||||
EsSyscall(ES_SYSCALL_SCREEN_FORCE_UPDATE, true, 0, 0, 0);
|
||||
|
||||
// TODO Fade wallpaper in.
|
||||
|
||||
EsHeapFree(path);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
|
|
@ -499,9 +499,12 @@ struct EsWindow : EsElement {
|
|||
Array<EsElement *> checkVisible;
|
||||
bool processCheckVisible;
|
||||
|
||||
double animationTime;
|
||||
|
||||
EsRectangle beforeMaximiseBounds, targetBounds, animateFromBounds;
|
||||
bool animateToTargetBoundsAfterResize;
|
||||
double animateToTargetBoundsTimeMs;
|
||||
|
||||
EsPoint announcementBase;
|
||||
|
||||
EsRectangle updateRegion;
|
||||
EsRectangle updateRegionInProgress; // For visualizePaintSteps.
|
||||
|
@ -511,9 +514,6 @@ struct EsWindow : EsElement {
|
|||
|
||||
EsElement *source; // Menu source.
|
||||
EsWindow *targetMenu; // The menu that keyboard events should be sent to.
|
||||
|
||||
EsPoint announcementBase;
|
||||
double announcementTimeMs;
|
||||
};
|
||||
|
||||
struct UpdateAction {
|
||||
|
@ -634,7 +634,7 @@ void WindowChangeBounds(int direction, int newX, int newY, int *originalX, int *
|
|||
|
||||
window->isMaximised = false;
|
||||
window->animateToTargetBoundsAfterResize = false;
|
||||
window->animateToTargetBoundsTimeMs = -1;
|
||||
window->animationTime = -1;
|
||||
|
||||
if (direction == RESIZE_MOVE) {
|
||||
if (newY < screen.t + windowSnapRange && canSnap) {
|
||||
|
@ -758,14 +758,14 @@ int ProcessWindowBorderMessage(EsWindow *window, EsMessage *message, EsRectangle
|
|||
}
|
||||
|
||||
if (window->animateToTargetBoundsAfterResize) {
|
||||
window->animateToTargetBoundsTimeMs = 0;
|
||||
window->animationTime = 0;
|
||||
window->StartAnimating();
|
||||
}
|
||||
|
||||
gui.resizing = false;
|
||||
} else if (message->type == ES_MSG_ANIMATE && window->animateToTargetBoundsAfterResize) {
|
||||
double progress = window->animateToTargetBoundsTimeMs / 100.0;
|
||||
window->animateToTargetBoundsTimeMs += message->animate.deltaMs;
|
||||
double progress = window->animationTime / 100.0;
|
||||
window->animationTime += message->animate.deltaMs;
|
||||
|
||||
if (progress > 1 || progress < 0) {
|
||||
message->animate.complete = true;
|
||||
|
@ -4318,9 +4318,9 @@ int AnnouncementMessage(EsElement *element, EsMessage *message) {
|
|||
EsWindow *window = (EsWindow *) element;
|
||||
|
||||
if (message->type == ES_MSG_ANIMATE) {
|
||||
window->announcementTimeMs += message->animate.deltaMs;
|
||||
window->animationTime += message->animate.deltaMs;
|
||||
|
||||
double progress = window->announcementTimeMs / GetConstantNumber("announcementDuration");
|
||||
double progress = window->animationTime / GetConstantNumber("announcementDuration");
|
||||
|
||||
if (progress > 1) {
|
||||
EsElementDestroy(window);
|
||||
|
|
|
@ -953,6 +953,7 @@ private inttype EsSyscallType enum none {
|
|||
ES_SYSCALL_SCREEN_WORK_AREA_SET
|
||||
ES_SYSCALL_SCREEN_WORK_AREA_GET
|
||||
ES_SYSCALL_SCREEN_BOUNDS_GET
|
||||
ES_SYSCALL_SCREEN_GET_BITS
|
||||
ES_SYSCALL_SCREEN_FORCE_UPDATE
|
||||
|
||||
ES_SYSCALL_WINDOW_CREATE
|
||||
|
|
|
@ -58,17 +58,17 @@ const EsStyle styleSettingsGroupContainer2 = {
|
|||
},
|
||||
};
|
||||
|
||||
const uint32_t windowColors[][7] = {
|
||||
{ 0xFF67EFC4, 0xFFA9E7D3, 0xFF94D1BD, 0xFF6BA996, 0xFFD0E2DD, 0xFFD1EAE2, 0xFFBAD1C9 },
|
||||
{ 0xFF54ACE5, 0xFF9BC3DD, 0xFF87AEC8, 0xFF6784A2, 0xFFC5D1D9, 0xFFC6D6E0, 0xFFB0BEC8 },
|
||||
{ 0xFF448CF5, 0xFF9CBDED, 0xFF87A7D6, 0xFF5E7FB8, 0xFFD0DAE8, 0xFFD0DDF0, 0xFFB9C4D6 },
|
||||
{ 0xFF044CF5, 0xFF7FA0ED, 0xFF6A8AD6, 0xFF4065B4, 0xFFC8D1E8, 0xFFC4D1F0, 0xFFAEBAD6 },
|
||||
{ 0xFFAC00FF, 0xFFD183F7, 0xFFB96DDF, 0xFF8F41B5, 0xFFE6D0F2, 0xFFEBCCFA, 0xFFD1B5DF },
|
||||
{ 0xFFFF0032, 0xFFF78399, 0xFFDF6D83, 0xFFC0436B, 0xFFF2D0D6, 0xFFFACCD5, 0xFFDFB5BD },
|
||||
{ 0xFFFF6042, 0xFFF7AEA1, 0xFFDF978A, 0xFFB5525F, 0xFFF2DCD8, 0xFFFADDD7, 0xFFDFC4BF },
|
||||
{ 0xFFFF7F24, 0xFFF7BC93, 0xFFDFA57D, 0xFFC7825F, 0xFFF2E0D4, 0xFFFAE2D2, 0xFFDFC9BA },
|
||||
{ 0xFFE8ECF9, 0xFFE9EBF1, 0xFFD2D3D9, 0xFFA9AAB0, 0xFFEAEAEC, 0xFFF1F1F4, 0xFFD6D7D9 },
|
||||
{ 0xFFB7BBC5, 0xFFB8BABE, 0xFF9A9BA0, 0xFF85878B, 0xFFE9E9EA, 0xFFDEDFE1, 0xFFB9BABC },
|
||||
const uint32_t windowColors[][8] = {
|
||||
{ 0xFF67EFC4, 0xCEF2E6, 0xFFA9E7D3, 0xFF94D1BD, 0xFF6BA996, 0xFFD0E2DD, 0xFFD1EAE2, 0xFFBAD1C9 },
|
||||
{ 0xFF54ACE5, 0xB1CEE1, 0xFF9BC3DD, 0xFF87AEC8, 0xFF6784A2, 0xFFC5D1D9, 0xFFC6D6E0, 0xFFB0BEC8 },
|
||||
{ 0xFF448CF5, 0x77B9F9, 0xFF9CBDED, 0xFF87A7D6, 0xFF5E7FB8, 0xFFD0DAE8, 0xFFD0DDF0, 0xFFB9C4D6 },
|
||||
{ 0xFF044CF5, 0x8FABEB, 0xFF7FA0ED, 0xFF6A8AD6, 0xFF4065B4, 0xFFC8D1E8, 0xFFC4D1F0, 0xFFAEBAD6 },
|
||||
{ 0xFFAC00FF, 0xD899F6, 0xFFD183F7, 0xFFB96DDF, 0xFF8F41B5, 0xFFE6D0F2, 0xFFEBCCFA, 0xFFD1B5DF },
|
||||
{ 0xFFFF0032, 0xF9A0B1, 0xFFF78399, 0xFFDF6D83, 0xFFC0436B, 0xFFF2D0D6, 0xFFFACCD5, 0xFFDFB5BD },
|
||||
{ 0xFFFF6042, 0xF9BBAF, 0xFFF7AEA1, 0xFFDF978A, 0xFFB5525F, 0xFFF2DCD8, 0xFFFADDD7, 0xFFDFC4BF },
|
||||
{ 0xFFFF7F24, 0xF5C5A3, 0xFFF7BC93, 0xFFDFA57D, 0xFFC7825F, 0xFFF2E0D4, 0xFFFAE2D2, 0xFFDFC9BA },
|
||||
{ 0xFFE8ECF9, 0xE5E7ED, 0xFFE9EBF1, 0xFFD2D3D9, 0xFFA9AAB0, 0xFFEAEAEC, 0xFFF1F1F4, 0xFFD6D7D9 },
|
||||
{ 0xFFB7BBC5, 0xA4A5AA, 0xFFB8BABE, 0xFF9A9BA0, 0xFF85878B, 0xFFE9E9EA, 0xFFDEDFE1, 0xFFB9BABC },
|
||||
};
|
||||
|
||||
const EsStyle styleSettingsCheckboxGroup = {
|
||||
|
@ -710,14 +710,74 @@ int SettingsColorButtonMessage(EsElement *element, EsMessage *message) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int SettingsTransitionWindowMessage(EsElement *element, EsMessage *message) {
|
||||
EsWindow *window = element->window;
|
||||
|
||||
if (message->type == ES_MSG_ANIMATE) {
|
||||
window->animationTime += message->animate.deltaMs;
|
||||
double progress = window->animationTime / GetConstantNumber("settingsTransitionDuration");
|
||||
|
||||
if (progress > 1) {
|
||||
EsElementDestroy(window);
|
||||
} else {
|
||||
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, 0xFF * (1 - progress), 0, ES_WINDOW_PROPERTY_ALPHA);
|
||||
EsSyscall(ES_SYSCALL_SCREEN_FORCE_UPDATE, true, 0, 0, 0);
|
||||
message->animate.complete = false;
|
||||
message->animate.waitMs = 10;
|
||||
return ES_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SettingsCreateTransitionWindow() {
|
||||
if (!desktop.setupDesktopUIComplete) {
|
||||
return;
|
||||
}
|
||||
|
||||
EsRectangle screen;
|
||||
EsSyscall(ES_SYSCALL_SCREEN_BOUNDS_GET, 0, (uintptr_t) &screen, 0, 0);
|
||||
EsRectangle region = ES_RECT_2S(ES_RECT_WIDTH(screen), ES_RECT_HEIGHT(screen));
|
||||
|
||||
uint32_t *screenshot = (uint32_t *) EsHeapAllocate(region.r * region.b * 4, false);
|
||||
|
||||
if (!screenshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
EsSyscall(ES_SYSCALL_SCREEN_GET_BITS, 0, (uintptr_t) ®ion, (uintptr_t) screenshot, 0);
|
||||
|
||||
for (intptr_t i = 0; i < region.r * region.b; i++) {
|
||||
screenshot[i] |= 0xFF000000;
|
||||
}
|
||||
|
||||
EsWindow *transition = EsWindowCreate(nullptr, ES_WINDOW_PLAIN);
|
||||
|
||||
if (transition) {
|
||||
transition->messageUser = SettingsTransitionWindowMessage;
|
||||
transition->doNotPaint = true;
|
||||
transition->StartAnimating();
|
||||
EsSyscall(ES_SYSCALL_WINDOW_MOVE, transition->handle, (uintptr_t) &screen, 0, ES_WINDOW_MOVE_ALWAYS_ON_TOP);
|
||||
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, transition->handle, 0, 0, ES_WINDOW_PROPERTY_SOLID);
|
||||
EsSyscall(ES_SYSCALL_WINDOW_SET_BITS, transition->handle, (uintptr_t) ®ion, (uintptr_t) screenshot, 0);
|
||||
EsSyscall(ES_SYSCALL_SCREEN_FORCE_UPDATE, true, 0, 0, 0);
|
||||
}
|
||||
|
||||
EsHeapFree(screenshot);
|
||||
}
|
||||
|
||||
void SettingsWindowColorUpdated() {
|
||||
SettingsCreateTransitionWindow();
|
||||
|
||||
uint8_t index = EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("window_color"));
|
||||
|
||||
if (index > sizeof(windowColors) / sizeof(windowColors[0])) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
EsMemoryCopy(theming.windowColors, &windowColors[index][1], sizeof(theming.windowColors));
|
||||
EsMemoryCopy(theming.windowColors, &windowColors[index][2], sizeof(theming.windowColors));
|
||||
desktop.wallpaperBackgroundColor = windowColors[index][1];
|
||||
|
||||
for (uintptr_t i = 0; i < gui.allWindows.Length(); i++) {
|
||||
if (gui.allWindows[i]->windowStyle == ES_WINDOW_CONTAINER) {
|
||||
|
@ -725,6 +785,10 @@ void SettingsWindowColorUpdated() {
|
|||
UIWindowNeedsUpdate(gui.allWindows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (desktop.isWallpaperBackgroundColorVisible) {
|
||||
EsThreadCreate(WallpaperLoad, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsColorButtonCommand(EsInstance *, EsElement *element, EsCommand *) {
|
||||
|
|
|
@ -1359,14 +1359,42 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PROCESS_GET_TLS) {
|
|||
SYSCALL_RETURN(currentThread->tlsAddress, false);
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_SCREEN_GET_BITS) {
|
||||
SYSCALL_PERMISSION(ES_PERMISSION_SCREEN_MODIFY);
|
||||
EsRectangle rectangle;
|
||||
SYSCALL_READ(&rectangle, argument1, sizeof(EsRectangle));
|
||||
SYSCALL_BUFFER(argument2, Width(rectangle) * Height(rectangle) * 4, 1, false);
|
||||
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
|
||||
EsRectangle source = EsRectangleIntersection(rectangle, ES_RECT_2S(graphics.frameBuffer.width, graphics.frameBuffer.height));
|
||||
uint32_t *bits = (uint32_t *) graphics.frameBuffer.bits;
|
||||
uint32_t *destination = (uint32_t *) argument2;
|
||||
|
||||
if (ES_RECT_VALID(source)) {
|
||||
for (int32_t y = source.t; y < source.b; y++) {
|
||||
for (int32_t x = source.l; x < source.r; x++) {
|
||||
uint32_t p = bits[x + y * graphics.frameBuffer.stride / sizeof(uint32_t)];
|
||||
destination[(x - (source.l - rectangle.l)) + (y - (source.t - rectangle.t)) * (rectangle.r - rectangle.l)] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_SCREEN_BOUNDS_GET) {
|
||||
EsRectangle rectangle;
|
||||
EsMemoryZero(&rectangle, sizeof(EsRectangle));
|
||||
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
rectangle.l = 0;
|
||||
rectangle.t = 0;
|
||||
rectangle.r = graphics.width;
|
||||
rectangle.b = graphics.height;
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
|
||||
SYSCALL_WRITE(argument1, &rectangle, sizeof(EsRectangle));
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
|
|
Binary file not shown.
|
@ -1608,7 +1608,8 @@ uint8_t *EsImageLoad(const void *file, size_t fileSize, uint32_t *imageX, uint32
|
|||
#endif
|
||||
}
|
||||
|
||||
void LoadImage(const void *path, ptrdiff_t pathBytes, void *destination, int destinationWidth, int destinationHeight, bool fromMemory) {
|
||||
void LoadImage(const void *path, ptrdiff_t pathBytes, void *destination, int destinationWidth, int destinationHeight,
|
||||
bool fromMemory, bool *_coversDestination = nullptr) {
|
||||
int width = 0, height = 0;
|
||||
uint32_t *image = nullptr;
|
||||
|
||||
|
@ -1625,19 +1626,21 @@ void LoadImage(const void *path, ptrdiff_t pathBytes, void *destination, int des
|
|||
}
|
||||
|
||||
int cx = destinationWidth / 2 - width / 2, cy = destinationHeight / 2 - height / 2;
|
||||
bool coversDestination = true;
|
||||
|
||||
for (int j = 0; j < destinationHeight; j++) {
|
||||
uint32_t *pixel = (uint32_t *) ((uint8_t *) destination + j * destinationWidth * 4);
|
||||
|
||||
for (int i = 0; i < destinationWidth; i++, pixel++) {
|
||||
if (i - cx < 0 || i - cx >= width || j - cy < 0 || j - cy >= height) {
|
||||
*pixel = 0x77B9F9;
|
||||
} else {
|
||||
if (i - cx >= 0 && i - cx < width && j - cy >= 0 && j - cy < height) {
|
||||
*pixel = image[i - cx + (j - cy) * width];
|
||||
} else {
|
||||
coversDestination = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_coversDestination) *_coversDestination = coversDestination;
|
||||
EsHeapFree(image);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -326,7 +326,7 @@ Option options[] = {
|
|||
{ "BuildCore.RequiredFontsOnly", OPTION_TYPE_BOOL, { .b = false } },
|
||||
{ "General.first_application", OPTION_TYPE_STRING, { .s = NULL } },
|
||||
{ "General.wallpaper", OPTION_TYPE_STRING, { .s = NULL } },
|
||||
{ "General.window_color", OPTION_TYPE_STRING, { .s = "9" } },
|
||||
{ "General.window_color", OPTION_TYPE_STRING, { .s = "2" } },
|
||||
{ "General.installation_state", OPTION_TYPE_STRING, { .s = "0" } },
|
||||
{ "General.ui_scale", OPTION_TYPE_STRING, { .s = "100" } },
|
||||
{ "General.keyboard_layout", OPTION_TYPE_STRING, { .s = "us" } },
|
||||
|
|
Loading…
Reference in New Issue