nicer window resize limits

This commit is contained in:
nakst 2021-09-08 12:23:30 +01:00
parent 81cc802542
commit 424d65d8c4
5 changed files with 90 additions and 32 deletions

View File

@ -104,23 +104,34 @@ bool InstanceLoadFolder(Instance *instance, String path /* takes ownership */, i
EsCommandSetEnabled(&instance->commandRefresh, true); EsCommandSetEnabled(&instance->commandRefresh, true);
// Load the view settings for the folder. // Load the view settings for the folder.
// If the folder does not have any settings, inherit from closest ancestor with settings.
bool foundViewSettings = false; bool foundViewSettings = false;
size_t lastMatchBytes = 0;
ptrdiff_t updateLRU = -1;
if (folder->path.bytes < sizeof(folderViewSettings[0].path)) { if (folder->path.bytes < sizeof(folderViewSettings[0].path)) {
for (uintptr_t i = 0; i < folderViewSettings.Length(); i++) { for (uintptr_t i = 0; i < folderViewSettings.Length(); i++) {
if (folderViewSettings[i].pathBytes == folder->path.bytes String path = StringFromLiteralWithSize(folderViewSettings[i].path, folderViewSettings[i].pathBytes);
&& 0 == EsMemoryCompare(folderViewSettings[i].path, STRING(folder->path))) { bool matchFull = StringEquals(path, folder->path);
bool matchPartial = matchFull || PathHasPrefix(folder->path, path);
if (matchFull || (matchPartial && lastMatchBytes < path.bytes)) {
foundViewSettings = true; foundViewSettings = true;
FolderViewSettingsEntry entry = folderViewSettings[i]; instance->viewSettings = folderViewSettings[i].settings;
instance->viewSettings = entry.settings; updateLRU = i;
folderViewSettings.Delete(i); if (matchFull) break;
folderViewSettings.Add(entry); // Update the LRU order. else lastMatchBytes = path.bytes; // Keep looking for a closer ancestor.
break;
} }
} }
} }
if (updateLRU != -1) {
FolderViewSettingsEntry entry = folderViewSettings[updateLRU];
folderViewSettings.Delete(updateLRU);
folderViewSettings.Add(entry);
}
if (!foundViewSettings) { if (!foundViewSettings) {
if (folder->itemHandler->getDefaultViewSettings) { if (folder->itemHandler->getDefaultViewSettings) {
folder->itemHandler->getDefaultViewSettings(folder, &instance->viewSettings); folder->itemHandler->getDefaultViewSettings(folder, &instance->viewSettings);

View File

@ -420,6 +420,7 @@ void HeapDuplicate(void **pointer, size_t *outBytes, const void *data, size_t by
struct EsWindow : EsElement { struct EsWindow : EsElement {
EsHandle handle; EsHandle handle;
EsWindowStyle windowStyle;
uint32_t windowWidth, windowHeight; uint32_t windowWidth, windowHeight;
bool willUpdate, toolbarFillMode, destroyInstanceAfterClose, hasDialog, doNotPaint; bool willUpdate, toolbarFillMode, destroyInstanceAfterClose, hasDialog, doNotPaint;
@ -427,10 +428,11 @@ struct EsWindow : EsElement {
bool hovering, activated; bool hovering, activated;
bool visualizeRepaints, visualizeLayoutBounds, visualizePaintSteps; // Inspector properties. bool visualizeRepaints, visualizeLayoutBounds, visualizePaintSteps; // Inspector properties.
EsPoint mousePosition;
EsElement *mainPanel, *toolbar; EsElement *mainPanel, *toolbar;
EsPanel *toolbarSwitcher; EsPanel *toolbarSwitcher;
EsElement *dialogOverlay, *dialogPanel;
EsPoint mousePosition;
EsElement *hovered, EsElement *hovered,
*pressed, *pressed,
@ -449,9 +451,9 @@ struct EsWindow : EsElement {
Array<EsElement *> checkVisible; Array<EsElement *> checkVisible;
bool processCheckVisible; bool processCheckVisible;
EsElement *dialogOverlay, *dialogPanel; EsRectangle beforeMaximiseBounds, targetBounds, animateFromBounds;
EsWindowStyle windowStyle; bool animateToTargetBoundsAfterResize;
EsRectangle beforeMaximiseBounds; double animateToTargetBoundsTimeMs;
EsRectangle updateRegion; EsRectangle updateRegion;
EsRectangle updateRegionInProgress; // For visualizePaintSteps. EsRectangle updateRegionInProgress; // For visualizePaintSteps.
@ -561,20 +563,14 @@ void WindowChangeBounds(int direction, int newX, int newY, int *originalX, int *
EsRectangle screen; EsRectangle screen;
EsSyscall(ES_SYSCALL_SCREEN_WORK_AREA_GET, 0, (uintptr_t) &screen, 0, 0); EsSyscall(ES_SYSCALL_SCREEN_WORK_AREA_GET, 0, (uintptr_t) &screen, 0, 0);
int newWidth = bounds.r - bounds.l;
int newHeight = bounds.b - bounds.t;
int windowSnapRange = GetConstantNumber("windowSnapRange"); int windowSnapRange = GetConstantNumber("windowSnapRange");
int windowMinimumWidth = GetConstantNumber("windowMinimumWidth"); int windowMinimumWidth = GetConstantNumber("windowMinimumWidth");
int windowMinimumHeight = GetConstantNumber("windowMinimumHeight"); int windowMinimumHeight = GetConstantNumber("windowMinimumHeight");
int windowRestoreDragYPosition = GetConstantNumber("windowRestoreDragYPosition"); int windowRestoreDragYPosition = GetConstantNumber("windowRestoreDragYPosition");
window->isMaximised = false; window->isMaximised = false;
window->animateToTargetBoundsAfterResize = false;
if (newWidth < windowMinimumWidth && direction & RESIZE_LEFT) bounds.l = bounds.r - windowMinimumWidth; window->animateToTargetBoundsTimeMs = -1;
if (newWidth < windowMinimumWidth && direction & RESIZE_RIGHT) bounds.r = bounds.l + windowMinimumWidth;
if (newHeight < windowMinimumHeight && direction & RESIZE_TOP) bounds.t = bounds.b - windowMinimumHeight;
if (newHeight < windowMinimumHeight && direction & RESIZE_BOTTOM) bounds.b = bounds.t + windowMinimumHeight;
if (direction == RESIZE_MOVE) { if (direction == RESIZE_MOVE) {
if (newY < screen.t + windowSnapRange && canSnap) { if (newY < screen.t + windowSnapRange && canSnap) {
@ -605,6 +601,17 @@ void WindowChangeBounds(int direction, int newX, int newY, int *originalX, int *
bounds.b = bounds.t + oldHeight; bounds.b = bounds.t + oldHeight;
} }
} else { } else {
EsRectangle targetBounds = bounds;
#define WINDOW_CLAMP_SIZE(_size, _direction, _side, _target) \
if (_size(bounds) < windowMinimum ## _size && (direction & _direction)) targetBounds._side = _target, bounds._side = RubberBand(bounds._side, _target)
WINDOW_CLAMP_SIZE(Width, RESIZE_LEFT, l, bounds.r - windowMinimumWidth);
WINDOW_CLAMP_SIZE(Width, RESIZE_RIGHT, r, bounds.l + windowMinimumWidth);
WINDOW_CLAMP_SIZE(Height, RESIZE_TOP, t, bounds.b - windowMinimumHeight);
WINDOW_CLAMP_SIZE(Height, RESIZE_BOTTOM, b, bounds.t + windowMinimumHeight);
window->animateToTargetBoundsAfterResize = !EsRectangleEquals(targetBounds, bounds);
window->animateFromBounds = bounds;
window->targetBounds = targetBounds;
window->resetPositionOnNextMove = window->restoreOnNextMove = false; window->resetPositionOnNextMove = window->restoreOnNextMove = false;
} }
@ -658,7 +665,25 @@ int ProcessWindowBorderMessage(EsWindow *window, EsMessage *message, EsRectangle
window->resetPositionOnNextMove = true; window->resetPositionOnNextMove = true;
} }
if (window->animateToTargetBoundsAfterResize) {
window->animateToTargetBoundsTimeMs = 0;
window->StartAnimating();
}
gui.resizing = false; gui.resizing = false;
} else if (message->type == ES_MSG_ANIMATE && window->animateToTargetBoundsAfterResize) {
double progress = window->animateToTargetBoundsTimeMs / 100.0;
window->animateToTargetBoundsTimeMs += message->animate.deltaMs;
if (progress > 1 || progress < 0) {
message->animate.complete = true;
window->animateToTargetBoundsAfterResize = false;
} else {
progress = SmoothAnimationTimeSharp(progress);
EsRectangle bounds = EsRectangleLinearInterpolate(window->animateFromBounds, window->targetBounds, progress);
EsSyscall(ES_SYSCALL_WINDOW_MOVE, window->handle, (uintptr_t) &bounds, 0, ES_WINDOW_MOVE_DYNAMIC);
message->animate.complete = false;
}
} else { } else {
return 0; return 0;
} }

View File

@ -2041,6 +2041,7 @@ function EsRectangle EsRectangleCenter(EsRectangle parent, EsRectangle child);
function EsRectangle EsRectangleCut(EsRectangle a, int32_t amount, char side); function EsRectangle EsRectangleCut(EsRectangle a, int32_t amount, char side);
function EsRectangle EsRectangleFit(EsRectangle parent, EsRectangle child, bool allowScalingUp); // Preserves aspect ratio. function EsRectangle EsRectangleFit(EsRectangle parent, EsRectangle child, bool allowScalingUp); // Preserves aspect ratio.
function EsRectangle EsRectangleIntersection(EsRectangle a, EsRectangle b); function EsRectangle EsRectangleIntersection(EsRectangle a, EsRectangle b);
function EsRectangle EsRectangleLinearInterpolate(EsRectangle a, EsRectangle b, float progress);
function EsRectangle EsRectangleSplit(EsRectangle *a, int32_t amount, char side, int32_t gap = 0); // Same as EsRectangleCut, but the source rectangle is modified. function EsRectangle EsRectangleSplit(EsRectangle *a, int32_t amount, char side, int32_t gap = 0); // Same as EsRectangleCut, but the source rectangle is modified.
function EsRectangle EsRectangleSubtract(EsRectangle a, EsRectangle b); function EsRectangle EsRectangleSubtract(EsRectangle a, EsRectangle b);
function EsRectangle EsRectangleTranslate(EsRectangle a, EsRectangle b); function EsRectangle EsRectangleTranslate(EsRectangle a, EsRectangle b);
@ -2199,6 +2200,8 @@ function bool EsCRTisnanf(float f);
function int EsCRTisspace(int c); function int EsCRTisspace(int c);
function int EsCRTisupper(int c); function int EsCRTisupper(int c);
function int EsCRTisxdigit(int c); function int EsCRTisxdigit(int c);
function double EsCRTlog2(double x);
function float EsCRTlog2f(float x);
function void *EsCRTmalloc(size_t size); function void *EsCRTmalloc(size_t size);
function void *EsCRTmemchr(const void *_s, int _c, size_t n); function void *EsCRTmemchr(const void *_s, int _c, size_t n);
function int EsCRTmemcmp(const void *s1, const void *s2, size_t n); function int EsCRTmemcmp(const void *s1, const void *s2, size_t n);

View File

@ -64,6 +64,22 @@ inline int MinimumInteger(int a, int b) {
return a < b ? a : b; return a < b ? a : b;
} }
inline float AbsoluteFloat(float f) {
return f > 0 ? f : -f;
}
inline float SignFloat(float f) {
return f < 0 ? -1 : f > 0 ? 1 : 0;
}
inline int AbsoluteInteger(int a) {
return a > 0 ? a : -a;
}
inline int64_t AbsoluteInteger64(int64_t a) {
return a > 0 ? a : -a;
}
///////////////////////////////// /////////////////////////////////
// Interpolation. // Interpolation.
///////////////////////////////// /////////////////////////////////
@ -79,6 +95,18 @@ float LinearInterpolate(float from, float to, float progress) {
return from + progress * (to - from); return from + progress * (to - from);
} }
EsRectangle EsRectangleLinearInterpolate(EsRectangle from, EsRectangle to, float progress) {
return ES_RECT_4(LinearInterpolate(from.l, to.l, progress), LinearInterpolate(from.r, to.r, progress),
LinearInterpolate(from.t, to.t, progress), LinearInterpolate(from.b, to.b, progress));
}
float RubberBand(float original, float target) {
float sign = SignFloat(original - target);
float distance = AbsoluteFloat(original - target);
float amount = EsCRTlog2f(distance);
return target + sign * amount * 2.0f;
}
#ifndef KERNEL #ifndef KERNEL
float GammaInterpolate(float from, float to, float progress) { float GammaInterpolate(float from, float to, float progress) {
from = from * from; from = from * from;
@ -184,18 +212,6 @@ float EsCRTfloorf(float x) {
return convert.f; return convert.f;
} }
inline float AbsoluteFloat(float f) {
return f > 0 ? f : -f;
}
inline int AbsoluteInteger(int a) {
return a > 0 ? a : -a;
}
inline int64_t AbsoluteInteger64(int64_t a) {
return a > 0 ? a : -a;
}
double EsCRTfloor(double x) { double EsCRTfloor(double x) {
if (x == 0) return x; if (x == 0) return x;

View File

@ -155,6 +155,7 @@ EsStringAllocateAndFormat=153
EsStringAllocateAndFormatV=154 EsStringAllocateAndFormatV=154
EsStringCompare=155 EsStringCompare=155
EsStringCompareRaw=156 EsStringCompareRaw=156
EsCRTlog2=157
EsStringFormat=158 EsStringFormat=158
EsStringFormatTemporary=159 EsStringFormatTemporary=159
EsStringFormatV=160 EsStringFormatV=160
@ -198,6 +199,7 @@ EsCRTqsort=197
EsCRTrealloc=198 EsCRTrealloc=198
EsCRTsinf=199 EsCRTsinf=199
EsElementGetScaleFactor=200 EsElementGetScaleFactor=200
EsCRTlog2f=201
EsCRTsqrt=202 EsCRTsqrt=202
EsCRTsqrtf=203 EsCRTsqrtf=203
EsSplitterCreate=204 EsSplitterCreate=204
@ -436,3 +438,4 @@ EsUserTaskSetProgress=436
EsUserTaskIsRunning=437 EsUserTaskIsRunning=437
EsTextboxSetFont=438 EsTextboxSetFont=438
EsTextboxSetTextSize=439 EsTextboxSetTextSize=439
EsRectangleLinearInterpolate=440