提交 c236bf49 编写于 作者: J Joao Moreno

wip: splitview tweaking

上级 a260c08a
......@@ -96,7 +96,7 @@ export abstract class Panel implements IView {
constructor(options: IPanelOptions = {}) {
this._expanded = typeof options.expanded === 'undefined' ? true : !!options.expanded;
this.ariaHeaderLabel = options.ariaHeaderLabel || '';
this._minimumBodySize = typeof options.minimumBodySize === 'number' ? options.minimumBodySize : 44;
this._minimumBodySize = typeof options.minimumBodySize === 'number' ? options.minimumBodySize : 120;
this._maximumBodySize = typeof options.maximumBodySize === 'number' ? options.maximumBodySize : Number.POSITIVE_INFINITY;
this.header = $('.panel-header');
}
......
......@@ -39,6 +39,7 @@ interface IViewItem {
explicitSize: number;
container: HTMLElement;
disposable: IDisposable;
layout(): void;
}
interface ISashItem {
......@@ -52,16 +53,6 @@ interface ISashDragState {
sizes: number[];
}
function layoutViewItem(item: IViewItem, orientation: Orientation): void {
if (orientation === Orientation.VERTICAL) {
item.container.style.height = `${item.size}px`;
} else {
item.container.style.width = `${item.size}px`;
}
item.view.layout(item.size, orientation);
}
export class SplitView implements IDisposable {
private orientation: Orientation;
......@@ -98,8 +89,23 @@ export class SplitView implements IDisposable {
const containerDisposable = toDisposable(() => this.el.removeChild(container));
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
const layoutContainer = this.orientation === Orientation.VERTICAL
? size => item.container.style.height = `${item.size}px`
: size => item.container.style.width = `${item.size}px`;
let previousSize: number | undefined = undefined;
const layout = () => {
if (item.size === previousSize) {
return;
}
layoutContainer(item.size);
item.view.layout(item.size, this.orientation);
previousSize = item.size;
};
const explicitSize = size;
const item: IViewItem = { view, container, explicitSize, size, disposable };
const item: IViewItem = { view, container, explicitSize, size, layout, disposable };
this.viewItems.splice(index, 0, item);
// Add sash
......@@ -193,8 +199,14 @@ export class SplitView implements IDisposable {
}
private onViewChange(item: IViewItem): void {
item.size = clamp(item.size, item.view.minimumSize, item.view.maximumSize);
this.relayout();
const index = this.viewItems.indexOf(item);
if (index < 0 || index >= this.viewItems.length - 1) {
return;
}
const size = clamp(item.size, item.view.minimumSize, item.view.maximumSize);
this.resize(index, size - item.size);
}
resizeView(index: number, size: number): void {
......@@ -219,6 +231,12 @@ export class SplitView implements IDisposable {
const down = downIndexes.map(i => this.viewItems[i]);
const downSizes = downIndexes.map(i => sizes[i]);
delta = clamp(
delta,
-upIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.minimumSize), 0),
downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.minimumSize), 0)
);
for (let i = 0, deltaUp = delta; deltaUp !== 0 && i < up.length; i++) {
const item = up[i];
const size = clamp(upSizes[i] + deltaUp, item.view.minimumSize, item.view.maximumSize);
......@@ -242,7 +260,7 @@ export class SplitView implements IDisposable {
}
private layoutViews(): void {
this.viewItems.forEach(item => layoutViewItem(item, this.orientation));
this.viewItems.forEach(item => item.layout());
this.sashItems.forEach(item => item.sash.layout());
// Update sashes enablement
......
......@@ -145,4 +145,8 @@
.scm-viewlet .scm-editor.scroll > .monaco-inputbox > .wrapper > textarea.input {
overflow-y: scroll;
}
.scm-viewlet .split-view-view {
background: green;
}
\ No newline at end of file
......@@ -12,7 +12,7 @@ import { chain } from 'vs/base/common/event';
import { basename } from 'vs/base/common/paths';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose, combinedDisposable, empty as EmptyDisposable } from 'vs/base/common/lifecycle';
import { Builder } from 'vs/base/browser/builder';
import { Builder, Dimension } from 'vs/base/browser/builder';
import { PanelViewlet, ViewletPanel } from 'vs/workbench/browser/parts/views/views2';
import { append, $, toggleClass, trackFocus } from 'vs/base/browser/dom';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
......@@ -68,11 +68,12 @@ class SCMMenuItemActionItem extends MenuItemActionItem {
}
}
interface IViewModel {
export interface IViewModel {
readonly height: number | undefined;
addRepositoryPanel(panel: RepositoryPanel, size: number, index?: number): void;
removeRepositoryPanel(panel: RepositoryPanel): void;
moveRepositoryPanel(from: RepositoryPanel, to: RepositoryPanel): void;
isRepositoryVisible(repository: ISCMRepository): boolean;
toggleRepositoryVisibility(repository: ISCMRepository, visible: boolean);
}
......@@ -236,9 +237,9 @@ class MainPanel extends ViewletPanel {
this.list.splice(this.list.length, 0, [repository]);
this.updateBodySize();
if (this.repositories.length === 1) {
this.list.setSelection([0]);
}
// if (this.repositories.length === 1) {
this.list.setSelection(this.repositories.map((_, i) => i));
// }
}
private onDidRemoveRepository(repository: ISCMRepository): void {
......@@ -254,16 +255,27 @@ class MainPanel extends ViewletPanel {
}
private onSelectionChange(e: IListEvent<ISCMRepository>): void {
console.log(e.elements);
// Remove unselected panels
this.repositoryPanels
.filter(p => e.elements.every(r => p.repository !== r))
.forEach(panel => this.viewModel.removeRepositoryPanel(panel));
const toRemove = this.repositoryPanels.filter(p => e.elements.every(r => p.repository !== r));
const toAdd = e.elements.filter(r => this.repositoryPanels.every(p => p.repository !== r));
// Collect panels still selected
const repositoryPanels = this.repositoryPanels
.filter(p => e.elements.some(r => p.repository === r));
console.log(toAdd, toRemove);
// Collect new selected panels
const newRepositoryPanels = e.elements
.filter(r => this.repositoryPanels.every(p => p.repository !== r))
.map(r => this.instantiationService.createInstance(RepositoryPanel, r));
// Add new selected panels
const height = typeof this.viewModel.height === 'number' ? this.viewModel.height : 1000;
const size = (height - this.minimumSize) / e.elements.length;
console.log(this.viewModel.height, height, this.minimumBodySize, e.elements.length, size);
newRepositoryPanels.forEach(panel => this.viewModel.addRepositoryPanel(panel, size));
// this.viewModel.addRepositoryPanel();
// this.repositoryPanels
this.repositoryPanels = [...repositoryPanels, ...newRepositoryPanels];
}
private updateBodySize(): void {
......@@ -483,8 +495,11 @@ export class RepositoryPanel extends ViewletPanel {
@IInstantiationService protected instantiationService: IInstantiationService
) {
super(repository.provider.label, {}, keybindingService, contextMenuService);
this.menus = instantiationService.createInstance(SCMMenus, repository.provider);
}
render(container: HTMLElement): void {
super.render(container);
this.menus.onDidChangeTitle(this.updateActions, this, this.disposables);
}
......@@ -703,15 +718,15 @@ class InstallAdditionalSCMProvidersAction extends Action {
}
}
export class SCMViewlet extends PanelViewlet {
export class SCMViewlet extends PanelViewlet implements IViewModel {
private menus: SCMMenus;
private mainPanel: MainPanel;
// private repositoryToViewDescriptor = new Map<string, ProviderViewDescriptor>();
private disposables: IDisposable[] = [];
private _height: number | undefined = undefined;
get height(): number | undefined { return this._height; }
constructor(
@ITelemetryService telemetryService: ITelemetryService,
@ISCMService protected scmService: ISCMService,
......@@ -835,7 +850,12 @@ export class SCMViewlet extends PanelViewlet {
return new SCMMenuItemActionItem(action, this.keybindingService, this.messageService);
}
addRepositoryPanel(panel: RepositoryPanel, size: number, index?: number): void {
layout(dimension: Dimension): void {
super.layout(dimension);
this._height = dimension.height;
}
addRepositoryPanel(panel: RepositoryPanel, size: number, index: number = this.length): void {
this.addPanel(panel, size, index + 1);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册