Skip to content

Commit

Permalink
Update checkbox API usage
Browse files Browse the repository at this point in the history
  • Loading branch information
alexr00 committed May 17, 2023
1 parent f0bd766 commit 0425661
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 59 deletions.
17 changes: 15 additions & 2 deletions src/@types/vscode.proposed.treeItemCheckbox.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ declare module 'vscode' {

export class TreeItem2 extends TreeItem {
/**
* [TreeItemCheckboxState](#TreeItemCheckboxState) of the tree item.
* {@link TreeItemCheckboxState TreeItemCheckboxState} of the tree item.
* {@link TreeDataProvider.onDidChangeTreeData onDidChangeTreeData} should be fired when {@link TreeItem2.checkboxState checkboxState} changes.
*/
checkboxState?: TreeItemCheckboxState | { readonly state: TreeItemCheckboxState; readonly tooltip?: string };
checkboxState?: TreeItemCheckboxState | { readonly state: TreeItemCheckboxState; readonly tooltip?: string; readonly accessibilityInformation?: AccessibilityInformation };
}

/**
Expand Down Expand Up @@ -42,4 +43,16 @@ declare module 'vscode' {
*/
readonly items: ReadonlyArray<[T, TreeItemCheckboxState]>;
}

/**
* Options for creating a {@link TreeView}
*/
export interface TreeViewOptions<T> {
/**
* By default, when the children of a tree item have already been fetched, child checkboxes are automatically managed based on the checked state of the parent tree item.
* If the tree item is collapsed by default (meaning that the children haven't yet been fetched) then child checkboxes will not be updated.
* To override this behavior and manage child and parent checkbox state in the extension, set this to `true`.
*/
manuallyManageCheckboxSelection?: boolean;
}
}
41 changes: 4 additions & 37 deletions src/view/treeNodes/directoryTreeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class DirectoryTreeNode extends TreeNode implements vscode.TreeItem2 {
public collapsibleState: vscode.TreeItemCollapsibleState;
public children: (RemoteFileChangeNode | InMemFileChangeNode | GitFileChangeNode | DirectoryTreeNode)[] = [];
private pathToChild: Map<string, DirectoryTreeNode> = new Map();
public checkboxState?: { state: vscode.TreeItemCheckboxState, tooltip: string };
public checkboxState?: { state: vscode.TreeItemCheckboxState, tooltip: string, accessibilityInformation: vscode.AccessibilityInformation };

constructor(public parent: TreeNodeParent, public label: string) {
super();
Expand Down Expand Up @@ -117,56 +117,23 @@ export class DirectoryTreeNode extends TreeNode implements vscode.TreeItem2 {
node.addPathRecc(tail, file);
}

updateCheckbox(newState: vscode.TreeItemCheckboxState) {
this.children.forEach(child => child.updateCheckbox(newState));

if (this.parent instanceof TreeNode && !this.parent.updateParentCheckbox()) {
this.refresh(this);
}
}

public allChildrenViewed(): boolean {
for (const child of this.children) {
if (child instanceof DirectoryTreeNode) {
if (!child.allChildrenViewed()) {
return false;
}
}
else if (child.checkboxState.state !== vscode.TreeItemCheckboxState.Checked) {
} else if (child.checkboxState.state !== vscode.TreeItemCheckboxState.Checked) {
return false;
}
}
return true;
}

public updateParentCheckbox(): boolean {
// Returns true if the node has been refreshed and false otherwise
const allChildrenViewed = this.allChildrenViewed();
if (
(allChildrenViewed && this.checkboxState?.state === vscode.TreeItemCheckboxState.Checked) ||
(!allChildrenViewed && this.checkboxState?.state === vscode.TreeItemCheckboxState.Unchecked)
) {
return false;
}

this.setCheckboxState(allChildrenViewed);
if (this.parent instanceof DirectoryTreeNode && this.parent.checkboxState !== undefined && this.checkboxState !== this.parent.checkboxState) {
if (!this.parent.updateParentCheckbox()) {
this.refresh(this);
return true;
}
}
else {
this.refresh(this);
return true;
}
return false;
}

private setCheckboxState(isChecked: boolean) {
this.checkboxState = isChecked ?
{ state: vscode.TreeItemCheckboxState.Checked, tooltip: 'unmark all files viewed' } :
{ state: vscode.TreeItemCheckboxState.Unchecked, tooltip: 'mark all files viewed' };
{ state: vscode.TreeItemCheckboxState.Checked, tooltip: vscode.l10n.t('Mark all files unviewed'), accessibilityInformation: { label: vscode.l10n.t('Mark all files in folder {0} as unviewed', this.label) } } :
{ state: vscode.TreeItemCheckboxState.Unchecked, tooltip: vscode.l10n.t('Mark all files viewed'), accessibilityInformation: { label: vscode.l10n.t('Mark all files in folder {0} as viewed', this.label) } };
}

getTreeItem(): vscode.TreeItem {
Expand Down
26 changes: 7 additions & 19 deletions src/view/treeNodes/fileChangeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class FileChangeNode extends TreeNode implements vscode.TreeItem2 {
public command: vscode.Command;
public opts: vscode.TextDocumentShowOptions;

public checkboxState: { state: vscode.TreeItemCheckboxState; tooltip?: string };
public checkboxState: { state: vscode.TreeItemCheckboxState; tooltip?: string; accessibilityInformation: vscode.AccessibilityInformation };

public childrenDisposables: vscode.Disposable[] = [];

Expand Down Expand Up @@ -139,9 +139,6 @@ export class FileChangeNode extends TreeNode implements vscode.TreeItem2 {
const matchingChange = e.changed.find(viewStateChange => viewStateChange.fileName === this.changeModel.fileName);
if (matchingChange) {
this.updateViewed(matchingChange.viewed);
if (this.parent instanceof TreeNode && !this.parent.updateParentCheckbox()) {
this.refresh(this);
}
}
}),
);
Expand All @@ -167,8 +164,8 @@ export class FileChangeNode extends TreeNode implements vscode.TreeItem2 {
this.contextValue = `${Schemes.FileChange}:${GitChangeType[this.changeModel.status]}:${viewed === ViewedState.VIEWED ? 'viewed' : 'unviewed'
}`;
this.checkboxState = viewed === ViewedState.VIEWED ?
{ state: vscode.TreeItemCheckboxState.Checked, tooltip: 'unmark file as viewed' } :
{ state: vscode.TreeItemCheckboxState.Unchecked, tooltip: 'mark file as viewed' };
{ state: vscode.TreeItemCheckboxState.Checked, tooltip: vscode.l10n.t('Mark file as viewed'), accessibilityInformation: { label: vscode.l10n.t('Mark file {0} as viewed', this.label ?? '') } } :
{ state: vscode.TreeItemCheckboxState.Unchecked, tooltip: vscode.l10n.t('Mark file as unviewed'), accessibilityInformation: { label: vscode.l10n.t('Mark file {0} as unviewed', this.label ?? '') } };
}

public async markFileAsViewed() {
Expand All @@ -185,20 +182,11 @@ export class FileChangeNode extends TreeNode implements vscode.TreeItem2 {
const viewed = newState === vscode.TreeItemCheckboxState.Checked ? ViewedState.VIEWED : ViewedState.UNVIEWED;
this.updateViewed(viewed);

async function markFile(node: FileChangeNode) {
if (newState === vscode.TreeItemCheckboxState.Checked) {
await node.markFileAsViewed();
}
else {
await node.unmarkFileAsViewed();
}
if (newState === vscode.TreeItemCheckboxState.Checked) {
this.markFileAsViewed();
} else {
this.unmarkFileAsViewed();
}

markFile(this).then(_ => {
if (this.parent instanceof TreeNode && !this.parent.updateParentCheckbox()) {
this.refresh(this);
}
});
}

updateShowOptions() {
Expand Down
1 change: 0 additions & 1 deletion src/view/treeNodes/treeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ export abstract class TreeNode implements vscode.Disposable {

updateCheckbox(_newState: vscode.TreeItemCheckboxState): void { }

public updateParentCheckbox(): boolean { return false; }

dispose(): void {
if (this.childrenDisposables) {
Expand Down

0 comments on commit 0425661

Please sign in to comment.