Path: blob/main/src/vs/editor/contrib/find/browser/findOptionsWidget.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as dom from '../../../../base/browser/dom.js';6import './findOptionsWidget.css';7import { CaseSensitiveToggle, RegexToggle, WholeWordsToggle } from '../../../../base/browser/ui/findinput/findInputToggles.js';8import { Widget } from '../../../../base/browser/ui/widget.js';9import { RunOnceScheduler } from '../../../../base/common/async.js';10import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from '../../../browser/editorBrowser.js';11import { FIND_IDS } from './findModel.js';12import { FindReplaceState } from './findState.js';13import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';14import { asCssVariable, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground } from '../../../../platform/theme/common/colorRegistry.js';15import { createInstantHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegateFactory.js';1617export class FindOptionsWidget extends Widget implements IOverlayWidget {1819private static readonly ID = 'editor.contrib.findOptionsWidget';2021private readonly _editor: ICodeEditor;22private readonly _state: FindReplaceState;23private readonly _keybindingService: IKeybindingService;2425private readonly _domNode: HTMLElement;26private readonly regex: RegexToggle;27private readonly wholeWords: WholeWordsToggle;28private readonly caseSensitive: CaseSensitiveToggle;2930constructor(31editor: ICodeEditor,32state: FindReplaceState,33keybindingService: IKeybindingService34) {35super();3637this._editor = editor;38this._state = state;39this._keybindingService = keybindingService;4041this._domNode = document.createElement('div');42this._domNode.className = 'findOptionsWidget';43this._domNode.style.display = 'none';44this._domNode.style.top = '10px';45this._domNode.style.zIndex = '12';46this._domNode.setAttribute('role', 'presentation');47this._domNode.setAttribute('aria-hidden', 'true');4849const toggleStyles = {50inputActiveOptionBorder: asCssVariable(inputActiveOptionBorder),51inputActiveOptionForeground: asCssVariable(inputActiveOptionForeground),52inputActiveOptionBackground: asCssVariable(inputActiveOptionBackground),53};5455const hoverDelegate = this._register(createInstantHoverDelegate());5657this.caseSensitive = this._register(new CaseSensitiveToggle({58appendTitle: this._keybindingLabelFor(FIND_IDS.ToggleCaseSensitiveCommand),59isChecked: this._state.matchCase,60hoverDelegate,61...toggleStyles62}));63this._domNode.appendChild(this.caseSensitive.domNode);64this._register(this.caseSensitive.onChange(() => {65this._state.change({66matchCase: this.caseSensitive.checked67}, false);68}));6970this.wholeWords = this._register(new WholeWordsToggle({71appendTitle: this._keybindingLabelFor(FIND_IDS.ToggleWholeWordCommand),72isChecked: this._state.wholeWord,73hoverDelegate,74...toggleStyles75}));76this._domNode.appendChild(this.wholeWords.domNode);77this._register(this.wholeWords.onChange(() => {78this._state.change({79wholeWord: this.wholeWords.checked80}, false);81}));8283this.regex = this._register(new RegexToggle({84appendTitle: this._keybindingLabelFor(FIND_IDS.ToggleRegexCommand),85isChecked: this._state.isRegex,86hoverDelegate,87...toggleStyles88}));89this._domNode.appendChild(this.regex.domNode);90this._register(this.regex.onChange(() => {91this._state.change({92isRegex: this.regex.checked93}, false);94}));9596this._editor.addOverlayWidget(this);9798this._register(this._state.onFindReplaceStateChange((e) => {99let somethingChanged = false;100if (e.isRegex) {101this.regex.checked = this._state.isRegex;102somethingChanged = true;103}104if (e.wholeWord) {105this.wholeWords.checked = this._state.wholeWord;106somethingChanged = true;107}108if (e.matchCase) {109this.caseSensitive.checked = this._state.matchCase;110somethingChanged = true;111}112if (!this._state.isRevealed && somethingChanged) {113this._revealTemporarily();114}115}));116117this._register(dom.addDisposableListener(this._domNode, dom.EventType.MOUSE_LEAVE, (e) => this._onMouseLeave()));118this._register(dom.addDisposableListener(this._domNode, 'mouseover', (e) => this._onMouseOver()));119}120121private _keybindingLabelFor(actionId: string): string {122const kb = this._keybindingService.lookupKeybinding(actionId);123if (!kb) {124return '';125}126return ` (${kb.getLabel()})`;127}128129public override dispose(): void {130this._editor.removeOverlayWidget(this);131super.dispose();132}133134// ----- IOverlayWidget API135136public getId(): string {137return FindOptionsWidget.ID;138}139140public getDomNode(): HTMLElement {141return this._domNode;142}143144public getPosition(): IOverlayWidgetPosition {145return {146preference: OverlayWidgetPositionPreference.TOP_RIGHT_CORNER147};148}149150public highlightFindOptions(): void {151this._revealTemporarily();152}153154private _hideSoon = this._register(new RunOnceScheduler(() => this._hide(), 2000));155156private _revealTemporarily(): void {157this._show();158this._hideSoon.schedule();159}160161private _onMouseLeave(): void {162this._hideSoon.schedule();163}164165private _onMouseOver(): void {166this._hideSoon.cancel();167}168169private _isVisible: boolean = false;170171private _show(): void {172if (this._isVisible) {173return;174}175this._isVisible = true;176this._domNode.style.display = 'block';177}178179private _hide(): void {180if (!this._isVisible) {181return;182}183this._isVisible = false;184this._domNode.style.display = 'none';185}186}187188189