mirror of https://gitlab.com/nakst/essence
opening files in new tab; ReorderItem exiting
This commit is contained in:
parent
c2dc5adbe7
commit
02cc8d14fb
|
@ -821,7 +821,8 @@ int ListCallback(EsElement *element, EsMessage *message) {
|
||||||
request.id = fileType->openHandler;
|
request.id = fileType->openHandler;
|
||||||
request.filePath = path.text;
|
request.filePath = path.text;
|
||||||
request.filePathBytes = path.bytes;
|
request.filePathBytes = path.bytes;
|
||||||
EsApplicationStart(&request);
|
request.flags = EsKeyboardIsCtrlHeld() ? ES_APPLICATION_STARTUP_IN_SAME_CONTAINER : ES_FLAGS_DEFAULT;
|
||||||
|
EsApplicationStart(instance, &request);
|
||||||
StringDestroy(&path);
|
StringDestroy(&path);
|
||||||
} else {
|
} else {
|
||||||
EsDialogShow(instance->window, INTERFACE_STRING(FileManagerOpenFileError),
|
EsDialogShow(instance->window, INTERFACE_STRING(FileManagerOpenFileError),
|
||||||
|
|
|
@ -252,6 +252,29 @@ struct APIInstance {
|
||||||
EsTextbox *fileMenuNameTextbox; // Also used by the file save dialog.
|
EsTextbox *fileMenuNameTextbox; // Also used by the file save dialog.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CHARACTER_MONO (1) // 1 bit per pixel.
|
||||||
|
#define CHARACTER_SUBPIXEL (2) // 24 bits per pixel; each byte specifies the alpha of each RGB channel.
|
||||||
|
#define CHARACTER_IMAGE (3) // 32 bits per pixel, ARGB.
|
||||||
|
#define CHARACTER_RECOLOR (4) // 32 bits per pixel, AXXX.
|
||||||
|
|
||||||
|
#include "renderer.cpp"
|
||||||
|
#include "theme.cpp"
|
||||||
|
|
||||||
|
#define TEXT_RENDERER
|
||||||
|
#include "text.cpp"
|
||||||
|
#undef TEXT_RENDERER
|
||||||
|
|
||||||
|
#include "gui.cpp"
|
||||||
|
|
||||||
|
#ifndef NO_API_TABLE
|
||||||
|
const void *const apiTable[] = {
|
||||||
|
#include <bin/api_array.h>
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" void _init();
|
||||||
|
typedef void (*StartFunction)();
|
||||||
|
|
||||||
MountPoint *NodeAddMountPoint(const char *prefix, size_t prefixBytes, EsHandle base, bool queryInformation) {
|
MountPoint *NodeAddMountPoint(const char *prefix, size_t prefixBytes, EsHandle base, bool queryInformation) {
|
||||||
MountPoint mountPoint = {};
|
MountPoint mountPoint = {};
|
||||||
EsAssert(prefixBytes < sizeof(mountPoint.prefix));
|
EsAssert(prefixBytes < sizeof(mountPoint.prefix));
|
||||||
|
@ -485,7 +508,7 @@ _EsApplicationStartupInformation *ApplicationStartupInformationParse(const void
|
||||||
return startupInformation;
|
return startupInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsApplicationStart(const EsApplicationStartupRequest *request) {
|
void EsApplicationStart(EsInstance *instance, const EsApplicationStartupRequest *request) {
|
||||||
EsApplicationStartupRequest copy = *request;
|
EsApplicationStartupRequest copy = *request;
|
||||||
|
|
||||||
if (copy.filePathBytes == -1) {
|
if (copy.filePathBytes == -1) {
|
||||||
|
@ -498,7 +521,7 @@ void EsApplicationStart(const EsApplicationStartupRequest *request) {
|
||||||
EsBufferWrite(&buffer, copy.filePath, copy.filePathBytes);
|
EsBufferWrite(&buffer, copy.filePath, copy.filePathBytes);
|
||||||
|
|
||||||
if (!buffer.error) {
|
if (!buffer.error) {
|
||||||
MessageDesktop(buffer.out, buffer.position);
|
MessageDesktop(buffer.out, buffer.position, instance ? instance->window->handle : ES_INVALID_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
EsHeapFree(buffer.out);
|
EsHeapFree(buffer.out);
|
||||||
|
@ -523,29 +546,6 @@ void EsInstanceSetClassViewer(EsInstance *_instance, const EsInstanceClassViewer
|
||||||
instance->instanceClass = ES_INSTANCE_CLASS_VIEWER;
|
instance->instanceClass = ES_INSTANCE_CLASS_VIEWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHARACTER_MONO (1) // 1 bit per pixel.
|
|
||||||
#define CHARACTER_SUBPIXEL (2) // 24 bits per pixel; each byte specifies the alpha of each RGB channel.
|
|
||||||
#define CHARACTER_IMAGE (3) // 32 bits per pixel, ARGB.
|
|
||||||
#define CHARACTER_RECOLOR (4) // 32 bits per pixel, AXXX.
|
|
||||||
|
|
||||||
#include "renderer.cpp"
|
|
||||||
#include "theme.cpp"
|
|
||||||
|
|
||||||
#define TEXT_RENDERER
|
|
||||||
#include "text.cpp"
|
|
||||||
#undef TEXT_RENDERER
|
|
||||||
|
|
||||||
#include "gui.cpp"
|
|
||||||
|
|
||||||
#ifndef NO_API_TABLE
|
|
||||||
const void *const apiTable[] = {
|
|
||||||
#include <bin/api_array.h>
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C" void _init();
|
|
||||||
typedef void (*StartFunction)();
|
|
||||||
|
|
||||||
const char *EnumLookupNameFromValue(const EnumString *array, int value) {
|
const char *EnumLookupNameFromValue(const EnumString *array, int value) {
|
||||||
if (array[0].value == -1) {
|
if (array[0].value == -1) {
|
||||||
return array[value].cName;
|
return array[value].cName;
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
struct ReorderItem : EsElement {
|
struct ReorderItem : EsElement {
|
||||||
double sizeProgress, sizeTarget;
|
double sizeProgress, sizeTarget;
|
||||||
double offsetProgress, offsetTarget;
|
double offsetProgress, offsetTarget;
|
||||||
bool dragging;
|
bool dragging, exiting;
|
||||||
int dragOffset, dragPosition;
|
int dragOffset, dragPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,6 +70,12 @@ struct WindowTab : ReorderItem {
|
||||||
struct ApplicationInstance *applicationInstance;
|
struct ApplicationInstance *applicationInstance;
|
||||||
struct ApplicationInstance *notRespondingInstance;
|
struct ApplicationInstance *notRespondingInstance;
|
||||||
EsButton *closeButton;
|
EsButton *closeButton;
|
||||||
|
|
||||||
|
// Copied from ApplicationInstance.
|
||||||
|
// This needs to store a copy so it can be used during the exit animation.
|
||||||
|
char title[128];
|
||||||
|
size_t titleBytes;
|
||||||
|
uint32_t iconID;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WindowTabBand : ReorderList {
|
struct WindowTabBand : ReorderList {
|
||||||
|
@ -91,6 +97,7 @@ struct TaskBar : EsElement {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContainerWindow {
|
struct ContainerWindow {
|
||||||
|
Array<WindowTab *> openTabs;
|
||||||
WindowTabBand *tabBand;
|
WindowTabBand *tabBand;
|
||||||
TaskBarButton *taskBarButton; // Might be null. For example, in the installer there is no task bar.
|
TaskBarButton *taskBarButton; // Might be null. For example, in the installer there is no task bar.
|
||||||
EsWindow *window;
|
EsWindow *window;
|
||||||
|
@ -247,10 +254,13 @@ void ShutdownModalCreate();
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool ReorderItemAnimate(ReorderItem *item, uint64_t deltaMs, const char *entranceDuration) {
|
bool ReorderItemAnimate(ReorderItem *item, uint64_t deltaMs, const char *entranceDuration) {
|
||||||
|
const float speed = -3.0f;
|
||||||
|
// const float speed = -0.3f;
|
||||||
|
|
||||||
item->sizeProgress += (item->sizeTarget - item->sizeProgress)
|
item->sizeProgress += (item->sizeTarget - item->sizeProgress)
|
||||||
* (1 - EsCRTexp(deltaMs * -3.0f / GetConstantNumber(entranceDuration)));
|
* (1 - EsCRTexp(deltaMs * speed / GetConstantNumber(entranceDuration)));
|
||||||
item->offsetProgress += (item->offsetTarget - item->offsetProgress)
|
item->offsetProgress += (item->offsetTarget - item->offsetProgress)
|
||||||
* (1 - EsCRTexp(deltaMs * -3.0f / GetConstantNumber("taskBarButtonMoveDuration")));
|
* (1 - EsCRTexp(deltaMs * speed / GetConstantNumber("taskBarButtonMoveDuration")));
|
||||||
|
|
||||||
bool complete = true;
|
bool complete = true;
|
||||||
|
|
||||||
|
@ -266,11 +276,19 @@ bool ReorderItemAnimate(ReorderItem *item, uint64_t deltaMs, const char *entranc
|
||||||
complete = false;
|
complete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item->sizeProgress <= 1 && item->exiting) {
|
||||||
|
EsElementDestroy(item);
|
||||||
|
}
|
||||||
|
|
||||||
EsElementRelayout(item->parent);
|
EsElementRelayout(item->parent);
|
||||||
return complete;
|
return complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReorderItemDragged(ReorderItem *item, int mouseX) {
|
void ReorderItemDragged(ReorderItem *item, int mouseX) {
|
||||||
|
if (item->exiting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ReorderList *list = (ReorderList *) item->parent;
|
ReorderList *list = (ReorderList *) item->parent;
|
||||||
size_t childCount = list->items.Length();
|
size_t childCount = list->items.Length();
|
||||||
|
|
||||||
|
@ -295,12 +313,13 @@ bool ReorderItemDragged(ReorderItem *item, int mouseX) {
|
||||||
|
|
||||||
EsAssert(currentIndex != -1);
|
EsAssert(currentIndex != -1);
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
if (draggedIndex != currentIndex) {
|
if (draggedIndex != currentIndex) {
|
||||||
list->items.Delete(currentIndex);
|
list->items.Delete(currentIndex);
|
||||||
list->items.Insert(item, draggedIndex);
|
list->items.Insert(item, draggedIndex);
|
||||||
|
|
||||||
|
EsMessage m = { .type = ES_MSG_REORDER_ITEM_MOVED, .child = item };
|
||||||
|
EsMessageSend(list, &m);
|
||||||
|
|
||||||
for (uintptr_t i = 0, x = list->style->insets.l; i < childCount; i++) {
|
for (uintptr_t i = 0, x = list->style->insets.l; i < childCount; i++) {
|
||||||
ReorderItem *child = (ReorderItem *) list->items[i];
|
ReorderItem *child = (ReorderItem *) list->items[i];
|
||||||
|
|
||||||
|
@ -315,18 +334,14 @@ bool ReorderItemDragged(ReorderItem *item, int mouseX) {
|
||||||
|
|
||||||
x += child->sizeProgress;
|
x += child->sizeProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item->dragging = true;
|
item->dragging = true;
|
||||||
EsElementRelayout(item->parent);
|
EsElementRelayout(list);
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReorderItemDragComplete(ReorderItem *item) {
|
void ReorderItemDragComplete(ReorderItem *item) {
|
||||||
if (!item->dragging) {
|
if (!item->dragging || item->exiting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,10 +376,15 @@ int ReorderListLayout(ReorderList *list, int additionalRightMargin, bool clampDr
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalWidth = 0;
|
int totalWidth = 0;
|
||||||
|
uintptr_t nonExitingChildCount = 0;
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < childCount; i++) {
|
for (uintptr_t i = 0; i < childCount; i++) {
|
||||||
ReorderItem *child = list->items[i];
|
ReorderItem *child = list->items[i];
|
||||||
totalWidth += child->style->metrics->maximumWidth + list->style->metrics->gapMinor;
|
|
||||||
|
if (!child->exiting) {
|
||||||
|
totalWidth += child->style->metrics->maximumWidth + list->style->metrics->gapMinor;
|
||||||
|
nonExitingChildCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool widthClamped = false;
|
bool widthClamped = false;
|
||||||
|
@ -374,17 +394,20 @@ int ReorderListLayout(ReorderList *list, int additionalRightMargin, bool clampDr
|
||||||
widthClamped = true;
|
widthClamped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int targetWidth = totalWidth / childCount;
|
int targetWidth = totalWidth / nonExitingChildCount;
|
||||||
int extraWidth = totalWidth % childCount;
|
int extraWidth = totalWidth % nonExitingChildCount;
|
||||||
|
|
||||||
list->targetWidth = targetWidth;
|
list->targetWidth = targetWidth;
|
||||||
list->extraWidth = extraWidth;
|
list->extraWidth = extraWidth;
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < childCount; i++) {
|
for (uintptr_t i = 0; i < childCount; i++) {
|
||||||
ReorderItem *child = list->items[i];
|
ReorderItem *child = list->items[i];
|
||||||
|
int sizeTarget = 0;
|
||||||
|
|
||||||
int sizeTarget = targetWidth;
|
if (!child->exiting) {
|
||||||
if (extraWidth) sizeTarget++, extraWidth--;
|
sizeTarget = targetWidth;
|
||||||
|
if (extraWidth) sizeTarget++, extraWidth--;
|
||||||
|
}
|
||||||
|
|
||||||
if (preventTabSizeAnimation) {
|
if (preventTabSizeAnimation) {
|
||||||
child->sizeTarget = child->sizeProgress = sizeTarget;
|
child->sizeTarget = child->sizeProgress = sizeTarget;
|
||||||
|
@ -400,9 +423,13 @@ int ReorderListLayout(ReorderList *list, int additionalRightMargin, bool clampDr
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < childCount; i++) {
|
for (uintptr_t i = 0; i < childCount; i++) {
|
||||||
ReorderItem *child = list->items[i];
|
ReorderItem *child = list->items[i];
|
||||||
int width = (i == childCount - 1 && widthClamped) ? (totalWidth - x) : child->sizeProgress;
|
int width = child->sizeProgress;
|
||||||
int gap = list->style->metrics->gapMinor;
|
int gap = list->style->metrics->gapMinor;
|
||||||
|
|
||||||
|
if (i == childCount - 1 && widthClamped && width > totalWidth - x) {
|
||||||
|
width = totalWidth - x;
|
||||||
|
}
|
||||||
|
|
||||||
if (child->dragging) {
|
if (child->dragging) {
|
||||||
int p = child->dragPosition;
|
int p = child->dragPosition;
|
||||||
|
|
||||||
|
@ -513,6 +540,10 @@ void DesktopInspectorThread(EsGeneric) {
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
void WindowTabClose(WindowTab *tab) {
|
void WindowTabClose(WindowTab *tab) {
|
||||||
|
if (!tab->applicationInstance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (tab->notRespondingInstance) {
|
if (tab->notRespondingInstance) {
|
||||||
// The application is not responding, so force quit the process.
|
// The application is not responding, so force quit the process.
|
||||||
EsProcessTerminate(tab->applicationInstance->process->handle, 1);
|
EsProcessTerminate(tab->applicationInstance->process->handle, 1);
|
||||||
|
@ -522,6 +553,10 @@ void WindowTabClose(WindowTab *tab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowTabActivate(WindowTab *tab, bool force = false) {
|
void WindowTabActivate(WindowTab *tab, bool force = false) {
|
||||||
|
if (!tab->applicationInstance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (tab->container->active != tab || force) {
|
if (tab->container->active != tab || force) {
|
||||||
tab->container->active = tab;
|
tab->container->active = tab;
|
||||||
EsElementRelayout(tab->container->tabBand);
|
EsElementRelayout(tab->container->tabBand);
|
||||||
|
@ -534,26 +569,42 @@ void WindowTabActivate(WindowTab *tab, bool force = false) {
|
||||||
void WindowTabDestroy(WindowTab *tab) {
|
void WindowTabDestroy(WindowTab *tab) {
|
||||||
ContainerWindow *container = tab->container;
|
ContainerWindow *container = tab->container;
|
||||||
|
|
||||||
if (container->tabBand->items.Length() == 1) {
|
if (container->openTabs.Length() == 1) {
|
||||||
EsElementDestroy(container->window);
|
EsElementDestroy(container->window);
|
||||||
if (container->taskBarButton) EsElementDestroy(container->taskBarButton);
|
|
||||||
|
if (container->taskBarButton) {
|
||||||
|
container->taskBarButton->exiting = true;
|
||||||
|
container->taskBarButton->containerWindow = nullptr;
|
||||||
|
EsElementRelayout(&desktop.taskBar);
|
||||||
|
// The button is destroyed by ReorderItemAnimate, once the exit animation completes.
|
||||||
|
}
|
||||||
|
|
||||||
desktop.allContainerWindows.FindAndDeleteSwap(container, true);
|
desktop.allContainerWindows.FindAndDeleteSwap(container, true);
|
||||||
} else {
|
} else {
|
||||||
if (container->active == tab) {
|
if (container->active == tab) {
|
||||||
container->active = nullptr;
|
container->active = nullptr;
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < container->tabBand->items.Length(); i++) {
|
for (uintptr_t i = 0; i < container->openTabs.Length(); i++) {
|
||||||
if (container->tabBand->items[i] != tab) continue;
|
if (container->openTabs[i] != tab) continue;
|
||||||
WindowTabActivate((WindowTab *) container->tabBand->items[i ? (i - 1) : 1]);
|
WindowTabActivate(container->openTabs[i ? (i - 1) : 1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EsElementDestroy(tab);
|
tab->applicationInstance = nullptr;
|
||||||
|
tab->exiting = true;
|
||||||
|
tab->SetStyle(ES_STYLE_WINDOW_TAB_INACTIVE);
|
||||||
|
container->openTabs.FindAndDelete(tab, true);
|
||||||
|
EsElementRelayout(container->tabBand);
|
||||||
|
// The tab is destroyed by ReorderItemAnimate, once the exit animation completes.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowTab *WindowTabMoveToNewContainer(WindowTab *tab, ContainerWindow *container, int32_t width, int32_t height) {
|
WindowTab *WindowTabMoveToNewContainer(WindowTab *tab, ContainerWindow *container, int32_t width, int32_t height) {
|
||||||
|
if (!tab->applicationInstance) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!container) {
|
if (!container) {
|
||||||
// Create a new container.
|
// Create a new container.
|
||||||
container = ContainerWindowCreate();
|
container = ContainerWindowCreate();
|
||||||
|
@ -674,17 +725,17 @@ int ContainerWindowMessage(EsElement *element, EsMessage *message) {
|
||||||
if (((message->keyboard.modifiers & ~ES_MODIFIER_SHIFT) == ES_MODIFIER_CTRL) && message->keyboard.scancode == ES_SCANCODE_TAB) {
|
if (((message->keyboard.modifiers & ~ES_MODIFIER_SHIFT) == ES_MODIFIER_CTRL) && message->keyboard.scancode == ES_SCANCODE_TAB) {
|
||||||
int tab = -1;
|
int tab = -1;
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < container->tabBand->items.Length(); i++) {
|
for (uintptr_t i = 0; i < container->openTabs.Length(); i++) {
|
||||||
if (container->tabBand->items[i] == container->active) {
|
if (container->openTabs[i] == container->active) {
|
||||||
tab = i;
|
tab = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EsAssert(tab != -1);
|
EsAssert(tab != -1);
|
||||||
tab += ((message->keyboard.modifiers & ES_MODIFIER_SHIFT) ? -1 : 1);
|
tab += ((message->keyboard.modifiers & ES_MODIFIER_SHIFT) ? -1 : 1);
|
||||||
if (tab == -1) tab = container->tabBand->items.Length() - 1;
|
if (tab == -1) tab = container->openTabs.Length() - 1;
|
||||||
if (tab == (int) container->tabBand->items.Length()) tab = 0;
|
if (tab == (int) container->openTabs.Length()) tab = 0;
|
||||||
WindowTabActivate((WindowTab *) container->tabBand->items[tab]);
|
WindowTabActivate(container->openTabs[tab]);
|
||||||
} else if (ctrlOnly && scancode == ES_SCANCODE_T && !message->keyboard.repeat) {
|
} else if (ctrlOnly && scancode == ES_SCANCODE_T && !message->keyboard.repeat) {
|
||||||
ApplicationInstanceCreate(APPLICATION_ID_DESKTOP_BLANK_TAB, nullptr, container);
|
ApplicationInstanceCreate(APPLICATION_ID_DESKTOP_BLANK_TAB, nullptr, container);
|
||||||
} else if (ctrlOnly && scancode == ES_SCANCODE_W && !message->keyboard.repeat) {
|
} else if (ctrlOnly && scancode == ES_SCANCODE_W && !message->keyboard.repeat) {
|
||||||
|
@ -713,8 +764,8 @@ int ContainerWindowMessage(EsElement *element, EsMessage *message) {
|
||||||
bool unhandled = true;
|
bool unhandled = true;
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < 9; i++) {
|
for (uintptr_t i = 0; i < 9; i++) {
|
||||||
if (ctrlOnly && scancode == (int) (ES_SCANCODE_1 + i) && container->tabBand->items.Length() > i) {
|
if (ctrlOnly && scancode == (int) (ES_SCANCODE_1 + i) && container->openTabs.Length() > i) {
|
||||||
WindowTabActivate((WindowTab *) container->tabBand->items[i]);
|
WindowTabActivate(container->openTabs[i]);
|
||||||
unhandled = false;
|
unhandled = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -736,9 +787,10 @@ int ContainerWindowMessage(EsElement *element, EsMessage *message) {
|
||||||
int WindowTabMessage(EsElement *element, EsMessage *message) {
|
int WindowTabMessage(EsElement *element, EsMessage *message) {
|
||||||
WindowTab *tab = (WindowTab *) element;
|
WindowTab *tab = (WindowTab *) element;
|
||||||
WindowTabBand *band = (WindowTabBand *) tab->parent;
|
WindowTabBand *band = (WindowTabBand *) tab->parent;
|
||||||
ApplicationInstance *instance = tab->applicationInstance;
|
|
||||||
|
|
||||||
if (message->type == ES_MSG_DESTROY) {
|
if (message->type == ES_MSG_DESTROY) {
|
||||||
|
band->container->openTabs.FindAndDelete(tab, false);
|
||||||
|
|
||||||
if (tab->notRespondingInstance) {
|
if (tab->notRespondingInstance) {
|
||||||
ApplicationInstanceClose(tab->notRespondingInstance);
|
ApplicationInstanceClose(tab->notRespondingInstance);
|
||||||
tab->notRespondingInstance = nullptr;
|
tab->notRespondingInstance = nullptr;
|
||||||
|
@ -762,13 +814,13 @@ int WindowTabMessage(EsElement *element, EsMessage *message) {
|
||||||
insets.t, closeButtonWidth, tab->height - insets.t - insets.b);
|
insets.t, closeButtonWidth, tab->height - insets.t - insets.b);
|
||||||
} else if (message->type == ES_MSG_PAINT) {
|
} else if (message->type == ES_MSG_PAINT) {
|
||||||
EsDrawContent(message->painter, element, ES_RECT_2S(message->painter->width, message->painter->height),
|
EsDrawContent(message->painter, element, ES_RECT_2S(message->painter->width, message->painter->height),
|
||||||
instance->title, instance->titleBytes, instance->iconID);
|
tab->title, tab->titleBytes, tab->iconID);
|
||||||
} else if (message->type == ES_MSG_ANIMATE) {
|
} else if (message->type == ES_MSG_ANIMATE) {
|
||||||
message->animate.complete = ReorderItemAnimate(tab, message->animate.deltaMs, "windowTabEntranceDuration");
|
message->animate.complete = ReorderItemAnimate(tab, message->animate.deltaMs, "windowTabEntranceDuration");
|
||||||
} else if (message->type == ES_MSG_MOUSE_LEFT_DRAG) {
|
} else if (message->type == ES_MSG_MOUSE_LEFT_DRAG) {
|
||||||
EsElementSetDisabled(band->GetChild(0), true);
|
EsElementSetDisabled(band->GetChild(0), true);
|
||||||
|
|
||||||
if (band->items.Length() == 1) {
|
if (band->container->openTabs.Length() == 1) {
|
||||||
// Get the window we're hovering the tab over.
|
// Get the window we're hovering the tab over.
|
||||||
EsObjectID hoverWindowID;
|
EsObjectID hoverWindowID;
|
||||||
EsPoint mousePositionOnScreen = EsMouseGetPosition();
|
EsPoint mousePositionOnScreen = EsMouseGetPosition();
|
||||||
|
@ -845,9 +897,9 @@ int WindowTabMessage(EsElement *element, EsMessage *message) {
|
||||||
} else if (message->type == ES_MSG_MOUSE_LEFT_UP) {
|
} else if (message->type == ES_MSG_MOUSE_LEFT_UP) {
|
||||||
ReorderItemDragComplete(tab);
|
ReorderItemDragComplete(tab);
|
||||||
EsElementSetDisabled(band->GetChild(0), false);
|
EsElementSetDisabled(band->GetChild(0), false);
|
||||||
} else if (message->type == ES_MSG_MOUSE_RIGHT_CLICK) {
|
} else if (message->type == ES_MSG_MOUSE_RIGHT_CLICK && tab->applicationInstance) {
|
||||||
EsMenu *menu = EsMenuCreate(tab, ES_FLAGS_DEFAULT);
|
EsMenu *menu = EsMenuCreate(tab, ES_FLAGS_DEFAULT);
|
||||||
uint64_t disableIfOnlyTab = tab->container->tabBand->items.Length() == 1 ? ES_ELEMENT_DISABLED : ES_FLAGS_DEFAULT;
|
uint64_t disableIfOnlyTab = tab->container->openTabs.Length() == 1 ? ES_ELEMENT_DISABLED : ES_FLAGS_DEFAULT;
|
||||||
|
|
||||||
EsMenuAddItem(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(DesktopCloseTab), [] (EsMenu *, EsGeneric context) {
|
EsMenuAddItem(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(DesktopCloseTab), [] (EsMenu *, EsGeneric context) {
|
||||||
WindowTabClose((WindowTab *) context.p);
|
WindowTabClose((WindowTab *) context.p);
|
||||||
|
@ -883,6 +935,7 @@ int WindowTabMessage(EsElement *element, EsMessage *message) {
|
||||||
EsMenuAddItem(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(DesktopInspectUI), [] (EsMenu *, EsGeneric context) {
|
EsMenuAddItem(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(DesktopInspectUI), [] (EsMenu *, EsGeneric context) {
|
||||||
WindowTab *tab = (WindowTab *) context.p;
|
WindowTab *tab = (WindowTab *) context.p;
|
||||||
ApplicationInstance *instance = tab->applicationInstance;
|
ApplicationInstance *instance = tab->applicationInstance;
|
||||||
|
if (!instance) return;
|
||||||
EsMessage m = { ES_MSG_TAB_INSPECT_UI };
|
EsMessage m = { ES_MSG_TAB_INSPECT_UI };
|
||||||
m.tabOperation.id = instance->embeddedWindowID;
|
m.tabOperation.id = instance->embeddedWindowID;
|
||||||
EsMessagePostRemote(instance->process->handle, &m);
|
EsMessagePostRemote(instance->process->handle, &m);
|
||||||
|
@ -912,6 +965,7 @@ WindowTab *WindowTabCreate(ContainerWindow *container) {
|
||||||
tab->container = container;
|
tab->container = container;
|
||||||
tab->Initialise(container->tabBand, ES_CELL_H_SHRINK | ES_CELL_V_BOTTOM, WindowTabMessage, nullptr);
|
tab->Initialise(container->tabBand, ES_CELL_H_SHRINK | ES_CELL_V_BOTTOM, WindowTabMessage, nullptr);
|
||||||
tab->cName = "window tab";
|
tab->cName = "window tab";
|
||||||
|
container->openTabs.Add(tab);
|
||||||
|
|
||||||
tab->closeButton = EsButtonCreate(tab, ES_FLAGS_DEFAULT, ES_STYLE_WINDOW_TAB_CLOSE_BUTTON);
|
tab->closeButton = EsButtonCreate(tab, ES_FLAGS_DEFAULT, ES_STYLE_WINDOW_TAB_CLOSE_BUTTON);
|
||||||
tab->closeButton->userData = tab;
|
tab->closeButton->userData = tab;
|
||||||
|
@ -927,8 +981,8 @@ int WindowTabBandMessage(EsElement *element, EsMessage *message) {
|
||||||
WindowTabBand *band = (WindowTabBand *) element;
|
WindowTabBand *band = (WindowTabBand *) element;
|
||||||
|
|
||||||
if (message->type == ES_MSG_LAYOUT) {
|
if (message->type == ES_MSG_LAYOUT) {
|
||||||
for (uint16_t i = 0; i < band->items.Length(); i++) {
|
for (uint16_t i = 0; i < band->container->openTabs.Length(); i++) {
|
||||||
WindowTab *tab = (WindowTab *) band->items[i];
|
WindowTab *tab = band->container->openTabs[i];
|
||||||
tab->SetStyle(tab == tab->container->active ? ES_STYLE_WINDOW_TAB_ACTIVE : ES_STYLE_WINDOW_TAB_INACTIVE);
|
tab->SetStyle(tab == tab->container->active ? ES_STYLE_WINDOW_TAB_ACTIVE : ES_STYLE_WINDOW_TAB_INACTIVE);
|
||||||
|
|
||||||
if (tab == tab->container->active) {
|
if (tab == tab->container->active) {
|
||||||
|
@ -951,16 +1005,15 @@ int WindowTabBandMessage(EsElement *element, EsMessage *message) {
|
||||||
}
|
}
|
||||||
} else if (message->type == ES_MSG_MOUSE_RIGHT_CLICK) {
|
} else if (message->type == ES_MSG_MOUSE_RIGHT_CLICK) {
|
||||||
EsMenu *menu = EsMenuCreate(band, ES_MENU_AT_CURSOR);
|
EsMenu *menu = EsMenuCreate(band, ES_MENU_AT_CURSOR);
|
||||||
|
const char *string = band->container->openTabs.Length() > 1 ? interfaceString_DesktopCloseAllTabs : interfaceString_DesktopCloseWindow;
|
||||||
|
|
||||||
EsMenuAddItem(menu, ES_FLAGS_DEFAULT,
|
EsMenuAddItem(menu, ES_FLAGS_DEFAULT, string, -1, [] (EsMenu *, EsGeneric context) {
|
||||||
band->items.Length() > 1 ? interfaceString_DesktopCloseAllTabs : interfaceString_DesktopCloseWindow, -1,
|
ContainerWindow *container = (ContainerWindow *) context.p;
|
||||||
[] (EsMenu *, EsGeneric context) {
|
|
||||||
WindowTabBand *band = (WindowTabBand *) context.p;
|
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < band->items.Length(); i++) {
|
for (uintptr_t i = 0; i < container->openTabs.Length(); i++) {
|
||||||
WindowTabClose((WindowTab *) band->items[i]);
|
WindowTabClose(container->openTabs[i]);
|
||||||
}
|
}
|
||||||
}, band);
|
}, band->container);
|
||||||
|
|
||||||
EsMenuAddSeparator(menu);
|
EsMenuAddSeparator(menu);
|
||||||
|
|
||||||
|
@ -1006,6 +1059,22 @@ int WindowTabBandMessage(EsElement *element, EsMessage *message) {
|
||||||
}, band->window);
|
}, band->window);
|
||||||
|
|
||||||
EsMenuShow(menu);
|
EsMenuShow(menu);
|
||||||
|
} else if (message->type == ES_MSG_REORDER_ITEM_MOVED) {
|
||||||
|
WindowTab *tab = (WindowTab *) message->child;
|
||||||
|
|
||||||
|
if (band->container->openTabs.FindAndDelete(tab, false)) {
|
||||||
|
uintptr_t openTabsBeforeTab = 0;
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < band->items.Length(); i++) {
|
||||||
|
if (band->items[i] == tab) {
|
||||||
|
break;
|
||||||
|
} else if (!band->items[i]->exiting) {
|
||||||
|
openTabsBeforeTab++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
band->container->openTabs.Insert(tab, openTabsBeforeTab);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return ReorderListMessage(band, message);
|
return ReorderListMessage(band, message);
|
||||||
}
|
}
|
||||||
|
@ -1081,12 +1150,15 @@ ContainerWindow *ContainerWindowCreate() {
|
||||||
int TaskBarButtonMessage(EsElement *element, EsMessage *message) {
|
int TaskBarButtonMessage(EsElement *element, EsMessage *message) {
|
||||||
TaskBarButton *button = (TaskBarButton *) element;
|
TaskBarButton *button = (TaskBarButton *) element;
|
||||||
|
|
||||||
if (message->type == ES_MSG_PAINT) {
|
if (message->type == ES_MSG_PAINT && button->containerWindow) {
|
||||||
ContainerWindow *containerWindow = button->containerWindow;
|
ContainerWindow *containerWindow = button->containerWindow;
|
||||||
ApplicationInstance *instance = containerWindow->active->applicationInstance;
|
ApplicationInstance *instance = containerWindow->active->applicationInstance;
|
||||||
EsDrawContent(message->painter, element, ES_RECT_2S(message->painter->width, message->painter->height),
|
|
||||||
instance->title, instance->titleBytes, instance->iconID);
|
if (instance) {
|
||||||
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK) {
|
EsDrawContent(message->painter, element, ES_RECT_2S(message->painter->width, message->painter->height),
|
||||||
|
instance->title, instance->titleBytes, instance->iconID);
|
||||||
|
}
|
||||||
|
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK && button->containerWindow) {
|
||||||
if (button->customStyleState & THEME_STATE_SELECTED) {
|
if (button->customStyleState & THEME_STATE_SELECTED) {
|
||||||
EsSyscall(ES_SYSCALL_WINDOW_MOVE, button->containerWindow->window->handle, 0, 0, ES_WINDOW_MOVE_HIDDEN);
|
EsSyscall(ES_SYSCALL_WINDOW_MOVE, button->containerWindow->window->handle, 0, 0, ES_WINDOW_MOVE_HIDDEN);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1458,6 +1530,10 @@ void InstanceBlankTabCreate(EsMessage *message) {
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
ApplicationInstance *ApplicationInstanceFindByWindowID(EsObjectID windowID, bool remove) {
|
ApplicationInstance *ApplicationInstanceFindByWindowID(EsObjectID windowID, bool remove) {
|
||||||
|
if (!windowID) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
|
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
|
||||||
ApplicationInstance *instance = desktop.allApplicationInstances[i];
|
ApplicationInstance *instance = desktop.allApplicationInstances[i];
|
||||||
|
|
||||||
|
@ -1983,7 +2059,7 @@ void OpenDocumentOpenReference(EsObjectID id) {
|
||||||
document->referenceCount++;
|
document->referenceCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenDocumentWithApplication(EsApplicationStartupRequest *startupRequest) {
|
void OpenDocumentWithApplication(EsApplicationStartupRequest *startupRequest, ContainerWindow *container) {
|
||||||
bool foundDocument = false;
|
bool foundDocument = false;
|
||||||
|
|
||||||
_EsApplicationStartupInformation startupInformation = {};
|
_EsApplicationStartupInformation startupInformation = {};
|
||||||
|
@ -2029,7 +2105,7 @@ void OpenDocumentWithApplication(EsApplicationStartupRequest *startupRequest) {
|
||||||
OpenDocumentListUpdated();
|
OpenDocumentListUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationInstanceCreate(startupInformation.id, &startupInformation, nullptr);
|
ApplicationInstanceCreate(startupInformation.id, &startupInformation, container);
|
||||||
OpenDocumentCloseReference(startupInformation.documentID);
|
OpenDocumentCloseReference(startupInformation.documentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2635,7 +2711,16 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) {
|
||||||
EsApplicationStartupRequest request = {};
|
EsApplicationStartupRequest request = {};
|
||||||
EsBufferReadInto(&b, &request, sizeof(EsApplicationStartupRequest));
|
EsBufferReadInto(&b, &request, sizeof(EsApplicationStartupRequest));
|
||||||
request.filePath = (const char *) EsBufferRead(&b, request.filePathBytes);
|
request.filePath = (const char *) EsBufferRead(&b, request.filePathBytes);
|
||||||
if (!b.error) OpenDocumentWithApplication(&request);
|
|
||||||
|
if (!b.error) {
|
||||||
|
ContainerWindow *container = nullptr /* new container */;
|
||||||
|
|
||||||
|
if ((request.flags & ES_APPLICATION_STARTUP_IN_SAME_CONTAINER) && instance && instance->tab) {
|
||||||
|
container = instance->tab->container;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenDocumentWithApplication(&request, container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (buffer[0] == DESKTOP_MSG_CREATE_CLIPBOARD_FILE && pipe) {
|
} else if (buffer[0] == DESKTOP_MSG_CREATE_CLIPBOARD_FILE && pipe) {
|
||||||
EsHandle processHandle = EsProcessOpen(message->desktop.processID);
|
EsHandle processHandle = EsProcessOpen(message->desktop.processID);
|
||||||
|
@ -2851,6 +2936,10 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance->tab) {
|
if (instance->tab) {
|
||||||
|
EsMemoryCopy(instance->tab->title, instance->title, instance->titleBytes);
|
||||||
|
instance->tab->titleBytes = instance->titleBytes;
|
||||||
|
instance->tab->iconID = instance->iconID;
|
||||||
|
|
||||||
instance->tab->Repaint(true);
|
instance->tab->Repaint(true);
|
||||||
|
|
||||||
if (instance->tab == instance->tab->container->active && instance->tab->container->taskBarButton) {
|
if (instance->tab == instance->tab->container->active && instance->tab->container->taskBarButton) {
|
||||||
|
|
|
@ -7470,15 +7470,16 @@ void UIProcessWindowManagerMessage(EsWindow *window, EsMessage *message, Process
|
||||||
UIMaybeRefreshStyleAll(window);
|
UIMaybeRefreshStyleAll(window);
|
||||||
}
|
}
|
||||||
} else if (message->type == ES_MSG_WINDOW_ACTIVATED) {
|
} else if (message->type == ES_MSG_WINDOW_ACTIVATED) {
|
||||||
|
gui.leftModifiers = message->windowActivated.leftModifiers;
|
||||||
|
gui.rightModifiers = message->windowActivated.rightModifiers;
|
||||||
|
|
||||||
if (!window->activated) {
|
if (!window->activated) {
|
||||||
AccessKeyModeExit();
|
AccessKeyModeExit();
|
||||||
|
|
||||||
gui.leftModifiers = gui.rightModifiers = 0;
|
|
||||||
gui.clickChainStartMs = 0;
|
gui.clickChainStartMs = 0;
|
||||||
|
|
||||||
window->activated = true;
|
window->activated = true;
|
||||||
EsMessage m = { ES_MSG_WINDOW_ACTIVATED };
|
|
||||||
EsMessageSend(window, &m);
|
EsMessageSend(window, message);
|
||||||
|
|
||||||
if (!window->focused && window->inactiveFocus) {
|
if (!window->focused && window->inactiveFocus) {
|
||||||
EsElementFocus(window->inactiveFocus, false);
|
EsElementFocus(window->inactiveFocus, false);
|
||||||
|
|
|
@ -1257,9 +1257,9 @@ struct EsListView : EsElement {
|
||||||
focusedItemIndex = item->index;
|
focusedItemIndex = item->index;
|
||||||
element->customStyleState |= THEME_STATE_FOCUSED_ITEM;
|
element->customStyleState |= THEME_STATE_FOCUSED_ITEM;
|
||||||
|
|
||||||
Select(item->group, item->index, EsKeyboardIsShiftHeld(), EsKeyboardIsCtrlHeld(), false);
|
if (message->mouseDown.clickChainCount == 1 || (~element->customStyleState & THEME_STATE_SELECTED)) {
|
||||||
|
Select(item->group, item->index, EsKeyboardIsShiftHeld(), EsKeyboardIsCtrlHeld(), false);
|
||||||
if (message->mouseDown.clickChainCount == 2 && !EsKeyboardIsShiftHeld() && !EsKeyboardIsCtrlHeld()) {
|
} else if (message->mouseDown.clickChainCount == 2) {
|
||||||
EsMessage m = { ES_MSG_LIST_VIEW_CHOOSE_ITEM };
|
EsMessage m = { ES_MSG_LIST_VIEW_CHOOSE_ITEM };
|
||||||
m.chooseItem.group = item->group;
|
m.chooseItem.group = item->group;
|
||||||
m.chooseItem.index = item->index;
|
m.chooseItem.index = item->index;
|
||||||
|
@ -1512,7 +1512,7 @@ struct EsListView : EsElement {
|
||||||
} else if (isSpace && ctrl && !shift && hasFocusedItem) {
|
} else if (isSpace && ctrl && !shift && hasFocusedItem) {
|
||||||
Select(focusedItemGroup, focusedItemIndex, false, true, false);
|
Select(focusedItemGroup, focusedItemIndex, false, true, false);
|
||||||
return true;
|
return true;
|
||||||
} else if (isEnter && hasFocusedItem && !shift && !ctrl && !alt) {
|
} else if (isEnter && hasFocusedItem) {
|
||||||
if (searchBufferBytes) {
|
if (searchBufferBytes) {
|
||||||
searchBufferLastKeyTime = 0;
|
searchBufferLastKeyTime = 0;
|
||||||
searchBufferBytes = 0;
|
searchBufferBytes = 0;
|
||||||
|
|
|
@ -700,6 +700,7 @@ define ES_ELEMENT_FOCUS_FROM_KEYBOARD (1 << 1)
|
||||||
|
|
||||||
define ES_APPLICATION_STARTUP_MANUAL_PATH (1 << 0)
|
define ES_APPLICATION_STARTUP_MANUAL_PATH (1 << 0)
|
||||||
define ES_APPLICATION_STARTUP_BACKGROUND_SERVICE (1 << 1)
|
define ES_APPLICATION_STARTUP_BACKGROUND_SERVICE (1 << 1)
|
||||||
|
define ES_APPLICATION_STARTUP_IN_SAME_CONTAINER (1 << 2)
|
||||||
|
|
||||||
define ES_LIST_VIEW_INLINE_TEXTBOX_COPY_EXISTING_TEXT (1 << 0)
|
define ES_LIST_VIEW_INLINE_TEXTBOX_COPY_EXISTING_TEXT (1 << 0)
|
||||||
define ES_LIST_VIEW_INLINE_TEXTBOX_REJECT_EDIT_IF_FOCUS_LOST (1 << 1)
|
define ES_LIST_VIEW_INLINE_TEXTBOX_REJECT_EDIT_IF_FOCUS_LOST (1 << 1)
|
||||||
|
@ -962,7 +963,6 @@ enum EsMessageType {
|
||||||
ES_MSG_RADIO_GROUP_UPDATED = 0x3002 // Sent to all siblings of a radiobox when it is checked, so they can uncheck themselves.
|
ES_MSG_RADIO_GROUP_UPDATED = 0x3002 // Sent to all siblings of a radiobox when it is checked, so they can uncheck themselves.
|
||||||
ES_MSG_COLOR_CHANGED = 0x3003 // Color well's color has changed. See message->colorChanged.
|
ES_MSG_COLOR_CHANGED = 0x3003 // Color well's color has changed. See message->colorChanged.
|
||||||
ES_MSG_LIST_DISPLAY_GET_MARKER = 0x3004 // Get the string for a marker in an EsListDisplay. See message->getContent.
|
ES_MSG_LIST_DISPLAY_GET_MARKER = 0x3004 // Get the string for a marker in an EsListDisplay. See message->getContent.
|
||||||
ES_MSG_REORDER_ITEM_TEST = 0x3005
|
|
||||||
ES_MSG_SLIDER_MOVED = 0x3006 // The slider has been moved.
|
ES_MSG_SLIDER_MOVED = 0x3006 // The slider has been moved.
|
||||||
|
|
||||||
// Desktop messages:
|
// Desktop messages:
|
||||||
|
@ -1032,6 +1032,10 @@ enum EsMessageType {
|
||||||
ES_MSG_LIST_VIEW_GET_SUMMARY = 0x5314
|
ES_MSG_LIST_VIEW_GET_SUMMARY = 0x5314
|
||||||
ES_MSG_LIST_VIEW_GET_COLUMN_SORT = 0x5315
|
ES_MSG_LIST_VIEW_GET_COLUMN_SORT = 0x5315
|
||||||
|
|
||||||
|
// Reorder list messages:
|
||||||
|
ES_MSG_REORDER_ITEM_TEST = 0x5400
|
||||||
|
ES_MSG_REORDER_ITEM_MOVED = 0x5401
|
||||||
|
|
||||||
// Application messages:
|
// Application messages:
|
||||||
ES_MSG_APPLICATION_EXIT = 0x7001
|
ES_MSG_APPLICATION_EXIT = 0x7001
|
||||||
ES_MSG_INSTANCE_CREATE = 0x7002
|
ES_MSG_INSTANCE_CREATE = 0x7002
|
||||||
|
@ -1558,6 +1562,10 @@ struct EsMessageKeyboard {
|
||||||
bool repeat, numpad, numlock, single;
|
bool repeat, numpad, numlock, single;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EsMessageWindowActivated {
|
||||||
|
uint8_t leftModifiers, rightModifiers;
|
||||||
|
};
|
||||||
|
|
||||||
struct EsMessageScrollWheel {
|
struct EsMessageScrollWheel {
|
||||||
int32_t dx, dy;
|
int32_t dx, dy;
|
||||||
};
|
};
|
||||||
|
@ -1813,6 +1821,7 @@ struct EsMessage {
|
||||||
EsMessageItemToString itemToString;
|
EsMessageItemToString itemToString;
|
||||||
EsMessageFocus focus;
|
EsMessageFocus focus;
|
||||||
EsMessageScrollWheel scrollWheel;
|
EsMessageScrollWheel scrollWheel;
|
||||||
|
EsMessageWindowActivated windowActivated;
|
||||||
const EsStyle *childStyleVariant;
|
const EsStyle *childStyleVariant;
|
||||||
EsRectangle *accessKeyHintBounds;
|
EsRectangle *accessKeyHintBounds;
|
||||||
EsPainter *painter;
|
EsPainter *painter;
|
||||||
|
@ -1954,7 +1963,7 @@ function_pointer void EsWorkCallback(EsGeneric context);
|
||||||
|
|
||||||
// System.
|
// System.
|
||||||
|
|
||||||
function void EsApplicationStart(const EsApplicationStartupRequest *request);
|
function void EsApplicationStart(ES_INSTANCE_TYPE *instance, const EsApplicationStartupRequest *request);
|
||||||
function void EsApplicationRunTemporary(ES_INSTANCE_TYPE *instance, STRING path);
|
function void EsApplicationRunTemporary(ES_INSTANCE_TYPE *instance, STRING path);
|
||||||
function EsHandle EsTakeSystemSnapshot(int type, size_t *bufferSize);
|
function EsHandle EsTakeSystemSnapshot(int type, size_t *bufferSize);
|
||||||
function EsInstance *_EsInstanceCreate(size_t bytes, EsMessage *message, STRING name = BLANK_STRING);
|
function EsInstance *_EsInstanceCreate(size_t bytes, EsMessage *message, STRING name = BLANK_STRING);
|
||||||
|
|
|
@ -191,7 +191,7 @@ bool SettingsPutValue(const char *cConfigurationSection, const char *cConfigurat
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsLoadDefaults() {
|
void SettingsLoadDefaults() {
|
||||||
SettingsPutValue("general", "click_chain_timeout_ms", EsLiteral("500"), nullptr, nullptr, true, false);
|
SettingsPutValue("general", "click_chain_timeout_ms", EsLiteral("300"), nullptr, nullptr, true, false);
|
||||||
SettingsPutValue("general", "show_cursor_shadow", EsLiteral("1"), nullptr, nullptr, true, false);
|
SettingsPutValue("general", "show_cursor_shadow", EsLiteral("1"), nullptr, nullptr, true, false);
|
||||||
SettingsPutValue("general", "scroll_lines_per_notch", EsLiteral("3"), nullptr, nullptr, true, false);
|
SettingsPutValue("general", "scroll_lines_per_notch", EsLiteral("3"), nullptr, nullptr, true, false);
|
||||||
SettingsPutValue("general", "ui_scale", EsLiteral("100"), nullptr, nullptr, true, false);
|
SettingsPutValue("general", "ui_scale", EsLiteral("100"), nullptr, nullptr, true, false);
|
||||||
|
|
|
@ -112,10 +112,8 @@ struct WindowManager {
|
||||||
|
|
||||||
// Keyboard:
|
// Keyboard:
|
||||||
|
|
||||||
bool shift, alt, ctrl, flag;
|
|
||||||
bool shift2, alt2, ctrl2, flag2;
|
|
||||||
bool numlock;
|
bool numlock;
|
||||||
uint8_t modifiers;
|
uint8_t leftModifiers, rightModifiers;
|
||||||
uint16_t keysHeld, maximumKeysHeld /* cleared when all released */;
|
uint16_t keysHeld, maximumKeysHeld /* cleared when all released */;
|
||||||
uint8_t keysHeldBitSet[512 / 8];
|
uint8_t keysHeldBitSet[512 / 8];
|
||||||
|
|
||||||
|
@ -341,39 +339,33 @@ void WindowManager::PressKey(uint32_t scancode) {
|
||||||
|
|
||||||
// TODO Caps lock.
|
// TODO Caps lock.
|
||||||
|
|
||||||
if (scancode == ES_SCANCODE_LEFT_CTRL) ctrl = true;
|
if (scancode == ES_SCANCODE_LEFT_CTRL) leftModifiers |= ES_MODIFIER_CTRL;
|
||||||
if (scancode == (ES_SCANCODE_LEFT_CTRL | K_SCANCODE_KEY_RELEASED)) ctrl = false;
|
if (scancode == (ES_SCANCODE_LEFT_CTRL | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_CTRL;
|
||||||
if (scancode == ES_SCANCODE_LEFT_SHIFT) shift = true;
|
if (scancode == ES_SCANCODE_LEFT_SHIFT) leftModifiers |= ES_MODIFIER_SHIFT;
|
||||||
if (scancode == (ES_SCANCODE_LEFT_SHIFT | K_SCANCODE_KEY_RELEASED)) shift = false;
|
if (scancode == (ES_SCANCODE_LEFT_SHIFT | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_SHIFT;
|
||||||
if (scancode == ES_SCANCODE_LEFT_ALT) alt = true;
|
if (scancode == ES_SCANCODE_LEFT_ALT) leftModifiers |= ES_MODIFIER_ALT;
|
||||||
if (scancode == (ES_SCANCODE_LEFT_ALT | K_SCANCODE_KEY_RELEASED)) alt = false;
|
if (scancode == (ES_SCANCODE_LEFT_ALT | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_ALT;
|
||||||
if (scancode == ES_SCANCODE_LEFT_FLAG) flag = true;
|
if (scancode == ES_SCANCODE_LEFT_FLAG) leftModifiers |= ES_MODIFIER_FLAG;
|
||||||
if (scancode == (ES_SCANCODE_LEFT_FLAG | K_SCANCODE_KEY_RELEASED)) flag = false;
|
if (scancode == (ES_SCANCODE_LEFT_FLAG | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_FLAG;
|
||||||
|
|
||||||
if (scancode == ES_SCANCODE_RIGHT_CTRL) ctrl2 = true;
|
if (scancode == ES_SCANCODE_RIGHT_CTRL) leftModifiers |= ES_MODIFIER_CTRL;
|
||||||
if (scancode == (ES_SCANCODE_RIGHT_CTRL | K_SCANCODE_KEY_RELEASED)) ctrl2 = false;
|
if (scancode == (ES_SCANCODE_RIGHT_CTRL | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_CTRL;
|
||||||
if (scancode == ES_SCANCODE_RIGHT_SHIFT) shift2 = true;
|
if (scancode == ES_SCANCODE_RIGHT_SHIFT) leftModifiers |= ES_MODIFIER_SHIFT;
|
||||||
if (scancode == (ES_SCANCODE_RIGHT_SHIFT | K_SCANCODE_KEY_RELEASED)) shift2 = false;
|
if (scancode == (ES_SCANCODE_RIGHT_SHIFT | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_SHIFT;
|
||||||
if (scancode == ES_SCANCODE_RIGHT_ALT) alt2 = true;
|
if (scancode == ES_SCANCODE_RIGHT_ALT) leftModifiers |= ES_MODIFIER_ALT_GR;
|
||||||
if (scancode == (ES_SCANCODE_RIGHT_ALT | K_SCANCODE_KEY_RELEASED)) alt2 = false;
|
if (scancode == (ES_SCANCODE_RIGHT_ALT | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_ALT_GR;
|
||||||
if (scancode == ES_SCANCODE_RIGHT_FLAG) flag2 = true;
|
if (scancode == ES_SCANCODE_RIGHT_FLAG) leftModifiers |= ES_MODIFIER_FLAG;
|
||||||
if (scancode == (ES_SCANCODE_RIGHT_FLAG | K_SCANCODE_KEY_RELEASED)) flag2 = false;
|
if (scancode == (ES_SCANCODE_RIGHT_FLAG | K_SCANCODE_KEY_RELEASED)) leftModifiers &= ~ES_MODIFIER_FLAG;
|
||||||
|
|
||||||
if (scancode == ES_SCANCODE_NUM_LOCK) {
|
if (scancode == ES_SCANCODE_NUM_LOCK) {
|
||||||
numlock = !numlock;
|
numlock = !numlock;
|
||||||
HIDeviceUpdateIndicators();
|
HIDeviceUpdateIndicators();
|
||||||
}
|
}
|
||||||
|
|
||||||
modifiers = (alt ? ES_MODIFIER_ALT : 0)
|
|
||||||
| (alt2 ? ES_MODIFIER_ALT_GR : 0)
|
|
||||||
| ((ctrl | ctrl2) ? ES_MODIFIER_CTRL : 0)
|
|
||||||
| ((shift | shift2) ? ES_MODIFIER_SHIFT : 0)
|
|
||||||
| ((flag | flag2) ? ES_MODIFIER_FLAG : 0);
|
|
||||||
|
|
||||||
EsMessage message;
|
EsMessage message;
|
||||||
EsMemoryZero(&message, sizeof(EsMessage));
|
EsMemoryZero(&message, sizeof(EsMessage));
|
||||||
message.type = (scancode & K_SCANCODE_KEY_RELEASED) ? ES_MSG_KEY_UP : ES_MSG_KEY_DOWN;
|
message.type = (scancode & K_SCANCODE_KEY_RELEASED) ? ES_MSG_KEY_UP : ES_MSG_KEY_DOWN;
|
||||||
message.keyboard.modifiers = modifiers;
|
message.keyboard.modifiers = leftModifiers | rightModifiers;
|
||||||
message.keyboard.scancode = scancode & ~K_SCANCODE_KEY_RELEASED;
|
message.keyboard.scancode = scancode & ~K_SCANCODE_KEY_RELEASED;
|
||||||
message.keyboard.numlock = numlock;
|
message.keyboard.numlock = numlock;
|
||||||
|
|
||||||
|
@ -397,9 +389,9 @@ void WindowManager::PressKey(uint32_t scancode) {
|
||||||
maximumKeysHeld = (!keysHeld || keysHeld > maximumKeysHeld) ? keysHeld : maximumKeysHeld;
|
maximumKeysHeld = (!keysHeld || keysHeld > maximumKeysHeld) ? keysHeld : maximumKeysHeld;
|
||||||
|
|
||||||
KernelLog(LOG_VERBOSE, "WM", "press key", "WindowManager::PressKey - Received key press %x. Modifiers are %X. Keys held: %d/%d%z.\n",
|
KernelLog(LOG_VERBOSE, "WM", "press key", "WindowManager::PressKey - Received key press %x. Modifiers are %X. Keys held: %d/%d%z.\n",
|
||||||
scancode, modifiers, keysHeld, maximumKeysHeld, message.keyboard.single ? " (single)" : "");
|
scancode, leftModifiers | rightModifiers, keysHeld, maximumKeysHeld, message.keyboard.single ? " (single)" : "");
|
||||||
|
|
||||||
if (((modifiers & ES_MODIFIER_CTRL) && (modifiers & ES_MODIFIER_FLAG)) || !activeWindow) {
|
if ((((leftModifiers | rightModifiers) & ES_MODIFIER_CTRL) && ((leftModifiers | rightModifiers) & ES_MODIFIER_FLAG)) || !activeWindow) {
|
||||||
_EsMessageWithObject messageWithObject = { nullptr, message };
|
_EsMessageWithObject messageWithObject = { nullptr, message };
|
||||||
DesktopSendMessage(&messageWithObject);
|
DesktopSendMessage(&messageWithObject);
|
||||||
} else {
|
} else {
|
||||||
|
@ -524,6 +516,8 @@ bool WindowManager::ActivateWindow(Window *window) {
|
||||||
|
|
||||||
// Activate the new window.
|
// Activate the new window.
|
||||||
message.type = ES_MSG_WINDOW_ACTIVATED;
|
message.type = ES_MSG_WINDOW_ACTIVATED;
|
||||||
|
message.windowActivated.leftModifiers = leftModifiers;
|
||||||
|
message.windowActivated.rightModifiers = rightModifiers;
|
||||||
SendMessageToWindow(window, &message);
|
SendMessageToWindow(window, &message);
|
||||||
} else {
|
} else {
|
||||||
// No window is active.
|
// No window is active.
|
||||||
|
@ -642,7 +636,7 @@ void WindowManager::MoveCursor(int64_t xMovement, int64_t yMovement) {
|
||||||
xMovement *= CURSOR_SPEED(cursorProperties);
|
xMovement *= CURSOR_SPEED(cursorProperties);
|
||||||
yMovement *= CURSOR_SPEED(cursorProperties);
|
yMovement *= CURSOR_SPEED(cursorProperties);
|
||||||
|
|
||||||
if (alt && (cursorProperties & CURSOR_USE_ALT_SLOW)) {
|
if ((leftModifiers & ES_MODIFIER_ALT) && (cursorProperties & CURSOR_USE_ALT_SLOW)) {
|
||||||
// Apply cursor slowdown.
|
// Apply cursor slowdown.
|
||||||
xMovement /= 5, yMovement /= 5;
|
xMovement /= 5, yMovement /= 5;
|
||||||
}
|
}
|
||||||
|
@ -1239,6 +1233,12 @@ void Window::SetEmbed(EmbeddedWindow *newEmbed) {
|
||||||
EsMessage message;
|
EsMessage message;
|
||||||
EsMemoryZero(&message, sizeof(message));
|
EsMemoryZero(&message, sizeof(message));
|
||||||
message.type = windowManager.activeWindow == this ? ES_MSG_WINDOW_ACTIVATED : ES_MSG_WINDOW_DEACTIVATED;
|
message.type = windowManager.activeWindow == this ? ES_MSG_WINDOW_ACTIVATED : ES_MSG_WINDOW_DEACTIVATED;
|
||||||
|
|
||||||
|
if (message.type == ES_MSG_WINDOW_ACTIVATED) {
|
||||||
|
message.windowActivated.leftModifiers = windowManager.leftModifiers;
|
||||||
|
message.windowActivated.rightModifiers = windowManager.rightModifiers;
|
||||||
|
}
|
||||||
|
|
||||||
embed->owner->messageQueue.SendMessage(embed->apiWindow, &message);
|
embed->owner->messageQueue.SendMessage(embed->apiWindow, &message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,16 +55,18 @@ struct Array {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void FindAndDelete(T item, bool failIfNotFound) {
|
inline bool FindAndDelete(T item, bool failIfNotFound) {
|
||||||
intptr_t index = Find(item, failIfNotFound);
|
intptr_t index = Find(item, failIfNotFound);
|
||||||
if (index == -1) return;
|
if (index == -1) return false;
|
||||||
Delete(index);
|
Delete(index);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void FindAndDeleteSwap(T item, bool failIfNotFound) {
|
inline bool FindAndDeleteSwap(T item, bool failIfNotFound) {
|
||||||
intptr_t index = Find(item, failIfNotFound);
|
intptr_t index = Find(item, failIfNotFound);
|
||||||
if (index == -1) return;
|
if (index == -1) return false;
|
||||||
DeleteSwap(index);
|
DeleteSwap(index);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AddFast(T item) {
|
inline void AddFast(T item) {
|
||||||
|
|
Loading…
Reference in New Issue