Path: blob/main/src/vs/editor/contrib/find/browser/findOptionsWidget.ts
5251 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 type { IHoverLifecycleOptions } from '../../../../base/browser/ui/hover/hover.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 hoverLifecycleOptions: IHoverLifecycleOptions = { groupId: 'find-options-widget' };5657this.caseSensitive = this._register(new CaseSensitiveToggle({58appendTitle: this._keybindingLabelFor(FIND_IDS.ToggleCaseSensitiveCommand),59isChecked: this._state.matchCase,60hoverLifecycleOptions,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,73hoverLifecycleOptions,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,86hoverLifecycleOptions,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 {122return this._keybindingService.appendKeybinding('', actionId);123}124125public override dispose(): void {126this._editor.removeOverlayWidget(this);127super.dispose();128}129130// ----- IOverlayWidget API131132public getId(): string {133return FindOptionsWidget.ID;134}135136public getDomNode(): HTMLElement {137return this._domNode;138}139140public getPosition(): IOverlayWidgetPosition {141return {142preference: OverlayWidgetPositionPreference.TOP_RIGHT_CORNER143};144}145146public highlightFindOptions(): void {147this._revealTemporarily();148}149150private _hideSoon = this._register(new RunOnceScheduler(() => this._hide(), 2000));151152private _revealTemporarily(): void {153this._show();154this._hideSoon.schedule();155}156157private _onMouseLeave(): void {158this._hideSoon.schedule();159}160161private _onMouseOver(): void {162this._hideSoon.cancel();163}164165private _isVisible: boolean = false;166167private _show(): void {168if (this._isVisible) {169return;170}171this._isVisible = true;172this._domNode.style.display = 'block';173}174175private _hide(): void {176if (!this._isVisible) {177return;178}179this._isVisible = false;180this._domNode.style.display = 'none';181}182}183184185