mirror of https://gitlab.com/nakst/essence
				
				
				
			nicer window resize limits
This commit is contained in:
		
							parent
							
								
									81cc802542
								
							
						
					
					
						commit
						424d65d8c4
					
				| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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); 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue