Support position property in editor component (#2314)

* Support position property in editor component
- This needs to be set directly on the editor component so cannot just use CSSStyles feature
- Given its importance to this scenario, it also warrants a dedicated property.

* Fix window resize when action bar clicked

* Renamed per Abbie's suggestion

* Changed name to clarify the comments
This commit is contained in:
Kevin Cunnane
2018-08-23 17:32:13 -07:00
committed by GitHub
parent 4ab5d84b94
commit 2bfc3a6c85
6 changed files with 51 additions and 18 deletions

View File

@@ -33,7 +33,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
private _editorInput: UntitledEditorInput; private _editorInput: UntitledEditorInput;
private _editorModel: ITextModel; private _editorModel: ITextModel;
private _renderedContent: string; private _renderedContent: string;
private _langaugeMode: string; private _languageMode: string;
constructor( constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@@ -76,10 +76,13 @@ export default class EditorComponent extends ComponentBase implements IComponent
public layout(): void { public layout(): void {
let width: number = this.convertSizeToNumber(this.width); let width: number = this.convertSizeToNumber(this.width);
let height: number = this.convertSizeToNumber(this.height); let height: number = this.convertSizeToNumber(this.height);
this._editor.layout(new DOM.Dimension( this._editor.layout(new DOM.Dimension(
width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement), width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement),
height && height > 0 ? height : DOM.getContentHeight(this._el.nativeElement))); height && height > 0 ? height : DOM.getContentHeight(this._el.nativeElement)));
let element = <HTMLElement> this._el.nativeElement;
element.style.position = this.position;
} }
/// Editor Functions /// Editor Functions
@@ -92,8 +95,8 @@ export default class EditorComponent extends ComponentBase implements IComponent
private updateLanguageMode() { private updateLanguageMode() {
if (this._editorModel && this._editor) { if (this._editorModel && this._editor) {
this._langaugeMode = this.languageMode; this._languageMode = this.languageMode;
this._modeService.getOrCreateMode(this._langaugeMode).then((modeValue) => { this._modeService.getOrCreateMode(this._languageMode).then((modeValue) => {
this._modelService.setMode(this._editorModel, modeValue); this._modelService.setMode(this._editorModel, modeValue);
}); });
} }
@@ -111,7 +114,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
if (this.content !== this._renderedContent) { if (this.content !== this._renderedContent) {
this.updateModel(); this.updateModel();
} }
if (this.languageMode !== this._langaugeMode) { if (this.languageMode !== this._languageMode) {
this.updateLanguageMode(); this.updateLanguageMode();
} }
} }
@@ -132,4 +135,12 @@ export default class EditorComponent extends ComponentBase implements IComponent
public set languageMode(newValue: string) { public set languageMode(newValue: string) {
this.setPropertyFromUI<sqlops.EditorProperties, string>((properties, languageMode) => { properties.languageMode = languageMode; }, newValue); this.setPropertyFromUI<sqlops.EditorProperties, string>((properties, languageMode) => { properties.languageMode = languageMode; }, newValue);
} }
public get position(): string {
return this.getPropertyOrDefault<sqlops.EditorProperties, string>((props) => props.position, '');
}
public set position(newValue: string) {
this.setPropertyFromUI<sqlops.EditorProperties, string>((properties, position) => { properties.languoffsetMarginageMode = position; }, newValue);
}
} }

View File

@@ -28,12 +28,13 @@ import { generateUuid } from 'vs/base/common/uuid';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService'; import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { LayoutRequestParams } from 'sql/platform/dialog/dialogContainer.component';
const componentRegistry = <IComponentRegistry>Registry.as(Extensions.ComponentContribution); const componentRegistry = <IComponentRegistry>Registry.as(Extensions.ComponentContribution);
export interface ModelComponentParams extends IBootstrapParams { export interface ModelComponentParams extends IBootstrapParams {
onLayoutRequested: Event<string>; onLayoutRequested: Event<LayoutRequestParams>;
modelViewId: string; modelViewId: string;
} }
@@ -69,8 +70,8 @@ export class ModelComponentWrapper extends AngularDisposable implements OnInit {
super(); super();
if (_params && _params.onLayoutRequested) { if (_params && _params.onLayoutRequested) {
this._modelViewId = _params.modelViewId; this._modelViewId = _params.modelViewId;
_params.onLayoutRequested(modelViewId => { _params.onLayoutRequested(layoutParams => {
if (modelViewId === this._modelViewId) { if (layoutParams && (layoutParams.alwaysRefresh || layoutParams.modelViewId === this._modelViewId)) {
this.layout(); this.layout();
} }
}); });

View File

@@ -79,7 +79,8 @@ export class ModelViewEditor extends BaseEditor {
} }
private doUpdateContainer() { private doUpdateContainer() {
const modelViewContainer = this.input && (this.input as ModelViewInput).container; let modelViewInput = this.input as ModelViewInput;
const modelViewContainer = modelViewInput && modelViewInput.container;
if (modelViewContainer) { if (modelViewContainer) {
const frameRect = this._editorFrame.getBoundingClientRect(); const frameRect = this._editorFrame.getBoundingClientRect();
const containerRect = modelViewContainer.parentElement.getBoundingClientRect(); const containerRect = modelViewContainer.parentElement.getBoundingClientRect();
@@ -89,6 +90,9 @@ export class ModelViewEditor extends BaseEditor {
modelViewContainer.style.left = `${frameRect.left - containerRect.left}px`; modelViewContainer.style.left = `${frameRect.left - containerRect.left}px`;
modelViewContainer.style.width = `${frameRect.width}px`; modelViewContainer.style.width = `${frameRect.width}px`;
modelViewContainer.style.height = `${frameRect.height}px`; modelViewContainer.style.height = `${frameRect.height}px`;
if (modelViewInput.dialogPane) {
modelViewInput.dialogPane.layout(true);
}
} }
} }

View File

@@ -13,10 +13,14 @@ import { DialogPane } from 'sql/platform/dialog/dialogPane';
import { ComponentEventType } from 'sql/parts/modelComponents/interfaces'; import { ComponentEventType } from 'sql/parts/modelComponents/interfaces';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
export interface LayoutRequestParams {
modelViewId?: string;
alwaysRefresh?: boolean;
}
export interface DialogComponentParams extends IBootstrapParams { export interface DialogComponentParams extends IBootstrapParams {
modelViewId: string; modelViewId: string;
validityChangedCallback: (valid: boolean) => void; validityChangedCallback: (valid: boolean) => void;
onLayoutRequested: Event<string>; onLayoutRequested: Event<LayoutRequestParams>;
dialogPane: DialogPane; dialogPane: DialogPane;
} }
@@ -50,8 +54,8 @@ export class DialogContainer implements AfterViewInit {
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef, @Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
@Inject(IBootstrapParams) private _params: DialogComponentParams) { @Inject(IBootstrapParams) private _params: DialogComponentParams) {
this.modelViewId = this._params.modelViewId; this.modelViewId = this._params.modelViewId;
this._params.onLayoutRequested(e => { this._params.onLayoutRequested(layoutParams => {
if (this.modelViewId === e) { if (layoutParams && (layoutParams.alwaysRefresh || layoutParams.modelViewId === this.modelViewId)) {
this.layout(); this.layout();
} }
}); });

View File

@@ -14,7 +14,7 @@ import { DialogTab } from 'sql/platform/dialog/dialogTypes';
import { TabbedPanel, IPanelTab, IPanelView } from 'sql/base/browser/ui/panel/panel'; import { TabbedPanel, IPanelTab, IPanelView } from 'sql/base/browser/ui/panel/panel';
import { bootstrapAngular } from 'sql/services/bootstrap/bootstrapService'; import { bootstrapAngular } from 'sql/services/bootstrap/bootstrapService';
import { DialogModule } from 'sql/platform/dialog/dialog.module'; import { DialogModule } from 'sql/platform/dialog/dialog.module';
import { DialogComponentParams } from 'sql/platform/dialog/dialogContainer.component'; import { DialogComponentParams, LayoutRequestParams } from 'sql/platform/dialog/dialogContainer.component';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { Builder } from 'vs/base/browser/builder'; import { Builder } from 'vs/base/browser/builder';
@@ -32,7 +32,7 @@ export class DialogPane extends Disposable implements IThemable {
private _body: HTMLElement; private _body: HTMLElement;
private _selectedTabIndex: number = 0; //TODO: can be an option private _selectedTabIndex: number = 0; //TODO: can be an option
private _onTabChange = new Emitter<string>(); private _onLayoutChange = new Emitter<LayoutRequestParams>();
private _selectedTabContent: string; private _selectedTabContent: string;
public pageNumber?: number; public pageNumber?: number;
@@ -65,7 +65,7 @@ export class DialogPane extends Disposable implements IThemable {
this.initializeModelViewContainer(tabContainer, tab.content, tab); this.initializeModelViewContainer(tabContainer, tab.content, tab);
this._tabbedPanel.onTabChange(e => { this._tabbedPanel.onTabChange(e => {
tabContainer.style.height = (this.getTabDimension().height - this._tabbedPanel.headersize) + 'px'; tabContainer.style.height = (this.getTabDimension().height - this._tabbedPanel.headersize) + 'px';
this._onTabChange.fire(tab.content); this._onLayoutChange.fire({ modelViewId: tab.content });
}); });
this._tabbedPanel.pushTab({ this._tabbedPanel.pushTab({
title: tab.title, title: tab.title,
@@ -92,10 +92,16 @@ export class DialogPane extends Disposable implements IThemable {
return new DOM.Dimension(DOM.getContentWidth(this._body) - 5, DOM.getContentHeight(this._body) - 5); return new DOM.Dimension(DOM.getContentWidth(this._body) - 5, DOM.getContentHeight(this._body) - 5);
} }
public layout(): void { public layout(alwaysRefresh: boolean = false): void {
let layoutParams: LayoutRequestParams = {
alwaysRefresh: alwaysRefresh,
modelViewId: this._selectedTabContent
};
if (this._tabbedPanel) { if (this._tabbedPanel) {
this._tabbedPanel.layout(this.getTabDimension()); this._tabbedPanel.layout(this.getTabDimension());
this._onTabChange.fire(this._selectedTabContent); this._onLayoutChange.fire(layoutParams);
} else if (alwaysRefresh) {
this._onLayoutChange.fire(layoutParams);
} }
} }
@@ -115,7 +121,7 @@ export class DialogPane extends Disposable implements IThemable {
tab.notifyValidityChanged(valid); tab.notifyValidityChanged(valid);
} }
}, },
onLayoutRequested: this._onTabChange.event, onLayoutRequested: this._onLayoutChange.event,
dialogPane: this dialogPane: this
} as DialogComponentParams, } as DialogComponentParams,
undefined, undefined,

View File

@@ -484,7 +484,14 @@ declare module 'sqlops' {
/** /**
* The languge mode for this text editor. The language mode is SQL by default. * The languge mode for this text editor. The language mode is SQL by default.
*/ */
languageMode?: string languageMode?: string;
/**
* The position CSS property for the editor. Empty by default.
* If the editor is included inside a FlexContainer this must be
* set to 'absolute', with the parent FlexContainer having 'relative' position.
* Without this the editor will fail to correctly size itself
*/
position?: string;
} }
export interface ButtonProperties extends ComponentProperties, ComponentWithIcon { export interface ButtonProperties extends ComponentProperties, ComponentWithIcon {