Skip to content

Commit 5b78b08

Browse files
authored
Add watermark for input box (#4117) (#4124)
* Add watermark for input box * Add news entry * Fix hygiene after merge
1 parent 6d7c012 commit 5b78b08

File tree

8 files changed

+37
-4
lines changed

8 files changed

+37
-4
lines changed

news/1 Enhancements/4111.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Watermark for Python Interactive input prompt

package.nls.json

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
"DataScience.pythonVersionHeaderNoPyKernel": "Python version may not match, no ipykernel found:",
121121
"DataScience.pythonRestartHeader": "Restarted Kernel:",
122122
"DataScience.executingCodeFailure" : "Executing code failed : {0}",
123+
"DataScience.inputWatermark" : "Shift-enter to run",
123124
"Linter.InstalledButNotEnabled": "Linter {0} is installed but not enabled.",
124125
"Linter.replaceWithSelectedLinter": "Multiple linters are enabled in settings. Replace with '{0}'?",
125126
"DataScience.jupyterSelectURILaunchLocal": "Launch a local Jupyter server when needed",

src/client/common/utils/localize.ts

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export namespace DataScience {
118118
export const pythonInterruptFailedHeader = localize('DataScience.pythonInterruptFailedHeader', 'Keyboard interrupt crashed the kernel. Kernel restarted.');
119119
export const sysInfoURILabel = localize('DataScience.sysInfoURILabel', 'Jupyter Server URI: ');
120120
export const executingCodeFailure = localize('DataScience.executingCodeFailure', 'Executing code failed : {0}');
121+
export const inputWatermark = localize('DataScience.inputWatermark', 'Shift-enter to run');
121122
}
122123

123124
export namespace DebugConfigurationPrompts {

src/datascience-ui/history-react/MainPanel.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
3737
super(props);
3838

3939
// Default state should show a busy message
40-
this.state = { cellVMs: [], busy: true, undoStack: [], redoStack : [], historyStack: []};
40+
this.state = { cellVMs: [], busy: true, undoStack: [], redoStack : [], historyStack: [], submittedText: false};
4141

4242
// Add test state if necessary
4343
if (!this.props.skipDefault) {
@@ -213,6 +213,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
213213
submitNewCode={this.submitInput}
214214
baseTheme={this.props.baseTheme}
215215
codeTheme={this.props.codeTheme}
216+
showWatermark={!this.state.submittedText}
216217
gotoCode={() => this.gotoCellCode(index)}
217218
delete={() => this.deleteCell(index)}/>
218219
</ErrorBoundary>
@@ -637,7 +638,8 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
637638
undoStack : this.pushStack(this.state.undoStack, this.state.cellVMs),
638639
redoStack: this.state.redoStack,
639640
skipNextScroll: false,
640-
historyStack: newHistory
641+
historyStack: newHistory,
642+
submittedText: true
641643
});
642644

643645
// Send a message to execute this code if necessary.

src/datascience-ui/history-react/cell.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ interface ICellProps {
3434
autoFocus: boolean;
3535
maxTextSize?: number;
3636
history: string [];
37+
showWatermark: boolean;
3738
gotoCode(): void;
3839
delete(): void;
3940
submitNewCode(code: string): void;
@@ -204,6 +205,7 @@ export class Cell extends React.Component<ICellProps> {
204205
codeTheme={this.props.codeTheme}
205206
testMode={this.props.testMode ? true : false}
206207
readOnly={!this.props.cellVM.editable}
208+
showWatermark={this.props.showWatermark}
207209
onSubmit={this.props.submitNewCode}
208210
onChangeLineCount={this.onChangeLineCount}
209211
ref={this.updateCodeRef}

src/datascience-ui/history-react/code.css

+14
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,17 @@
3636
.code-area-editable {
3737
margin-bottom: 10px;
3838
}
39+
40+
.code-watermark {
41+
position: absolute;
42+
top: 0;
43+
left: 30px;
44+
z-index: 500;
45+
font-style: italic;
46+
color: var(--vscode-pickerGroup-border);
47+
}
48+
49+
.hide {
50+
visibility: hidden;
51+
}
52+

src/datascience-ui/history-react/code.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as RCM from 'react-codemirror';
1111

1212
import './code.css';
1313

14+
import { getLocString } from '../react-common/locReactSide';
1415
import { Cursor } from './cursor';
1516
import { InputHistory } from './inputHistory';
1617

@@ -22,6 +23,7 @@ export interface ICodeProps {
2223
readOnly: boolean;
2324
history: string[];
2425
cursorType: string;
26+
showWatermark: boolean;
2527
onSubmit(code: string): void;
2628
onChangeLineCount(lineCount: number) : void;
2729

@@ -33,6 +35,7 @@ interface ICodeState {
3335
cursorTop: number;
3436
cursorBottom: number;
3537
charUnderCursor: string;
38+
allowWatermark: boolean;
3639
}
3740

3841
export class Code extends React.Component<ICodeProps, ICodeState> {
@@ -43,7 +46,7 @@ export class Code extends React.Component<ICodeProps, ICodeState> {
4346

4447
constructor(prop: ICodeProps) {
4548
super(prop);
46-
this.state = {focused: false, cursorLeft: 0, cursorTop: 0, cursorBottom: 0, charUnderCursor: ''};
49+
this.state = {focused: false, cursorLeft: 0, cursorTop: 0, cursorBottom: 0, charUnderCursor: '', allowWatermark: true};
4750
this.history = new InputHistory(this.props.history);
4851
}
4952

@@ -57,6 +60,7 @@ export class Code extends React.Component<ICodeProps, ICodeState> {
5760
public render() {
5861
const readOnly = this.props.testMode || this.props.readOnly;
5962
const classes = readOnly ? 'code-area' : 'code-area code-area-editable';
63+
const waterMarkClass = this.props.showWatermark && this.state.allowWatermark && !readOnly ? 'code-watermark' : 'hide';
6064
return (
6165
<div className={classes}>
6266
<Cursor
@@ -92,6 +96,7 @@ export class Code extends React.Component<ICodeProps, ICodeState> {
9296
onFocusChange={this.onFocusChange}
9397
onCursorActivity={this.onCursorActivity}
9498
/>
99+
<div className={waterMarkClass}>{this.getWatermarkString()}</div>
95100
</div>
96101
);
97102
}
@@ -104,6 +109,10 @@ export class Code extends React.Component<ICodeProps, ICodeState> {
104109
}
105110
}
106111

112+
private getWatermarkString = () : string => {
113+
return getLocString('DataScience.inputWatermark', 'Shift-enter to run');
114+
}
115+
107116
private onCursorActivity = (codeMirror: CodeMirror.Editor) => {
108117
// Update left/top/char for cursor
109118
if (codeMirror) {
@@ -245,5 +254,6 @@ export class Code extends React.Component<ICodeProps, ICodeState> {
245254

246255
private onChange = (newValue: string, change: CodeMirror.EditorChange) => {
247256
this.history.onChange();
257+
this.setState({allowWatermark: false});
248258
}
249259
}

src/datascience-ui/history-react/mainPanelState.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface IMainPanelState {
1818
undoStack : ICellViewModel[][];
1919
redoStack : ICellViewModel[][];
2020
historyStack: string[];
21+
submittedText: boolean;
2122
}
2223

2324
// This function generates test state when running under a browser instead of inside of
@@ -28,7 +29,8 @@ export function generateTestState(inputBlockToggled : (id: string) => void, file
2829
skipNextScroll : false,
2930
undoStack : [],
3031
redoStack : [],
31-
historyStack: []
32+
historyStack: [],
33+
submittedText: false
3234
};
3335
}
3436

0 commit comments

Comments
 (0)