diff --git a/src/Actions.ts b/src/Actions.ts index 0b9a495..41621c8 100644 --- a/src/Actions.ts +++ b/src/Actions.ts @@ -166,89 +166,13 @@ namespace Actions { columnWidthIncrease: () => { world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => { - const desktop = grid.desktop; - const visibleRange = desktop.getCurrentVisibleRange(); - if(!column.isVisible(visibleRange, true) || column.getWidth() >= column.getMaxWidth()) { - return; - } - - let leftVisibleColumn = grid.getLeftmostVisibleColumn(visibleRange, true); - let rightVisibleColumn = grid.getRightmostVisibleColumn(visibleRange, true); - if (leftVisibleColumn === null || rightVisibleColumn === null) { - console.assert(false); // should at least see self - return; - } - - const leftSpace = leftVisibleColumn.getLeft() - visibleRange.getLeft(); - const rightSpace = visibleRange.getRight() - rightVisibleColumn.getRight(); - - const newWidth = findNextStep( - [ - visibleRange.getWidth(), - column.getWidth() + config.manualResizeStep, - column.getWidth() + leftSpace + rightSpace, - column.getWidth() + leftSpace + rightSpace + leftVisibleColumn.getWidth() + grid.config.gapsInnerHorizontal, - column.getWidth() + leftSpace + rightSpace + rightVisibleColumn.getWidth() + grid.config.gapsInnerHorizontal, - ], - width => width - column.getWidth(), - ) - if (newWidth === undefined) { - return; - } - - column.setWidth(newWidth, true); - desktop.scrollCenterVisible(column); - desktop.onLayoutChanged(); - desktop.autoAdjustScroll(); + config.columnResizer.increaseWidth(column, config.manualResizeStep); }); }, columnWidthDecrease: () => { world.doIfTiledFocused(false, (clientManager, desktopManager, window, column, grid) => { - const desktop = grid.desktop; - const visibleRange = desktop.getCurrentVisibleRange(); - if(!column.isVisible(visibleRange, true) || column.getWidth() <= column.getMinWidth()) { - return; - } - - const leftVisibleColumn = grid.getLeftmostVisibleColumn(visibleRange, true); - const rightVisibleColumn = grid.getRightmostVisibleColumn(visibleRange, true); - if (leftVisibleColumn === null || rightVisibleColumn === null) { - console.assert(false); // should at least see self - return; - } - - let leftOffScreenColumn = grid.getPrevColumn(leftVisibleColumn); - if (leftOffScreenColumn === column) { - leftOffScreenColumn = null; - } - let rightOffScreenColumn = grid.getNextColumn(rightVisibleColumn); - if (rightOffScreenColumn === column) { - rightOffScreenColumn = null; - } - - const visibleColumnsWidth = rightVisibleColumn.getRight() - leftVisibleColumn.getLeft(); - const unusedWidth = visibleRange.getWidth() - visibleColumnsWidth; - const leftOffScreen = leftOffScreenColumn === null ? 0 : leftOffScreenColumn.getWidth() + grid.config.gapsInnerHorizontal - unusedWidth; - const rightOffScreen = rightOffScreenColumn === null ? 0 : rightOffScreenColumn.getWidth() + grid.config.gapsInnerHorizontal - unusedWidth; - - const newWidth = findNextStep( - [ - visibleRange.getWidth(), - column.getWidth() - config.manualResizeStep, - column.getWidth() - leftOffScreen, - column.getWidth() - rightOffScreen, - ], - width => column.getWidth() - width, - ) - if (newWidth === undefined) { - return; - } - - column.setWidth(newWidth, true); - desktop.scrollCenterVisible(column); - desktop.onLayoutChanged(); - desktop.autoAdjustScroll(); + config.columnResizer.decreaseWidth(column, config.manualResizeStep); }); }, @@ -399,21 +323,14 @@ namespace Actions { }); } - function findNextStep(steps: number[], evaluate: (step: number) => number) { - let bestScore = Infinity; - let bestStep = undefined; - for (const step of steps) { - const score = evaluate(step); - if (score > 0 && score < bestScore) { - bestScore = score; - bestStep = step; - } - } - return bestStep; - } - export type Config = { manualScrollStep: number, manualResizeStep: number, + columnResizer: ColumnResizer, }; + + export type ColumnResizer = { + increaseWidth(column: Column, step: number): void, + decreaseWidth(column: Column, step: number): void, + } } diff --git a/src/behavior/columnResizer/ContextualResizer.ts b/src/behavior/columnResizer/ContextualResizer.ts new file mode 100644 index 0000000..5134dae --- /dev/null +++ b/src/behavior/columnResizer/ContextualResizer.ts @@ -0,0 +1,96 @@ +class ContextualResizer { + public increaseWidth(column: Column, step: number) { + const grid = column.grid; + const desktop = grid.desktop; + const visibleRange = desktop.getCurrentVisibleRange(); + if(!column.isVisible(visibleRange, true) || column.getWidth() >= column.getMaxWidth()) { + return; + } + + let leftVisibleColumn = grid.getLeftmostVisibleColumn(visibleRange, true); + let rightVisibleColumn = grid.getRightmostVisibleColumn(visibleRange, true); + if (leftVisibleColumn === null || rightVisibleColumn === null) { + console.assert(false); // should at least see self + return; + } + + const leftSpace = leftVisibleColumn.getLeft() - visibleRange.getLeft(); + const rightSpace = visibleRange.getRight() - rightVisibleColumn.getRight(); + + const newWidth = ContextualResizer.findNextStep( + [ + visibleRange.getWidth(), + column.getWidth() + step, + column.getWidth() + leftSpace + rightSpace, + column.getWidth() + leftSpace + rightSpace + leftVisibleColumn.getWidth() + grid.config.gapsInnerHorizontal, + column.getWidth() + leftSpace + rightSpace + rightVisibleColumn.getWidth() + grid.config.gapsInnerHorizontal, + ], + width => width - column.getWidth(), + ) + if (newWidth === undefined) { + return; + } + + column.setWidth(newWidth, true); + desktop.scrollCenterVisible(column); + } + + public decreaseWidth(column: Column, step: number) { + const grid = column.grid; + const desktop = grid.desktop; + const visibleRange = desktop.getCurrentVisibleRange(); + if(!column.isVisible(visibleRange, true) || column.getWidth() <= column.getMinWidth()) { + return; + } + + const leftVisibleColumn = grid.getLeftmostVisibleColumn(visibleRange, true); + const rightVisibleColumn = grid.getRightmostVisibleColumn(visibleRange, true); + if (leftVisibleColumn === null || rightVisibleColumn === null) { + console.assert(false); // should at least see self + return; + } + + let leftOffScreenColumn = grid.getPrevColumn(leftVisibleColumn); + if (leftOffScreenColumn === column) { + leftOffScreenColumn = null; + } + let rightOffScreenColumn = grid.getNextColumn(rightVisibleColumn); + if (rightOffScreenColumn === column) { + rightOffScreenColumn = null; + } + + const visibleColumnsWidth = rightVisibleColumn.getRight() - leftVisibleColumn.getLeft(); + const unusedWidth = visibleRange.getWidth() - visibleColumnsWidth; + const leftOffScreen = leftOffScreenColumn === null ? 0 : leftOffScreenColumn.getWidth() + grid.config.gapsInnerHorizontal - unusedWidth; + const rightOffScreen = rightOffScreenColumn === null ? 0 : rightOffScreenColumn.getWidth() + grid.config.gapsInnerHorizontal - unusedWidth; + + const newWidth = ContextualResizer.findNextStep( + [ + visibleRange.getWidth(), + column.getWidth() - step, + column.getWidth() - leftOffScreen, + column.getWidth() - rightOffScreen, + ], + width => column.getWidth() - width, + ) + if (newWidth === undefined) { + return; + } + + column.setWidth(newWidth, true); + desktop.scrollCenterVisible(column); + } + + private static findNextStep(steps: number[], evaluate: (step: number) => number) { + let bestScore = Infinity; + let bestStep = undefined; + for (const step of steps) { + const score = evaluate(step); + if (score > 0 && score < bestScore) { + bestScore = score; + bestStep = step; + } + } + return bestStep; + } +} diff --git a/src/behavior/columnResizer/RawResizer.ts b/src/behavior/columnResizer/RawResizer.ts new file mode 100644 index 0000000..099b8b1 --- /dev/null +++ b/src/behavior/columnResizer/RawResizer.ts @@ -0,0 +1,9 @@ +class RawResizer { + public increaseWidth(column: Column, step: number) { + column.adjustWidth(step, true); + } + + public decreaseWidth(column: Column, step: number) { + column.adjustWidth(-step, true); + } +} diff --git a/src/keyBindings/loader.ts b/src/keyBindings/loader.ts index 5761a53..3e480c4 100644 --- a/src/keyBindings/loader.ts +++ b/src/keyBindings/loader.ts @@ -53,7 +53,12 @@ function registerNumKeyBindings(name: string, description: string, modifiers: st } function registerKeyBindings(world: World, config: Config) { - const actions = Actions.init(world, config); + const actions = Actions.init(world, { + manualScrollStep: config.manualScrollStep, + manualResizeStep: config.manualScrollStep, + columnResizer: config.scrollingCentered ? new RawResizer() : new ContextualResizer(), + }); + for (const binding of keyBindings) { registerKeyBinding(binding.name, binding.description, binding.defaultKeySequence, actions[binding.action]); }