Skip to content

Commit

Permalink
overlay: Better typing for tables. Better lane visibility widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomaz-Vieira committed Sep 5, 2023
1 parent 437a466 commit 523435d
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 119 deletions.
1 change: 1 addition & 0 deletions overlay/src/gui/css_classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export enum CssClasses{
ItkContainerForWebilastikControls = "ItkContainerForWebilastikControls",
ItkLaneWidget = "ItkLaneWidget",
ItkLaneLayerWidget = "ItkLaneLayerWidget",
ItkLaneLayerName = "ItkLaneLayerName",
ItkButtonDepressed = "ItkButtonDepressed",
ItkAppletContents = "ItkAppletContents",
ItkSessionManagementAdvancedOptions = "ItkSessionManagementAdvancedOptions",
Expand Down
16 changes: 8 additions & 8 deletions overlay/src/gui/widgets/feature_selector.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FeatureClassName, IlpFeatureExtractor } from "../../client/ilastik"
import { CssClasses } from "../css_classes"
import { Button, CheckboxWidget } from "./input_widget"
import { ContainerWidget, Div, Paragraph, Table, TableData, TableHeader, TableRow } from "./widget"
import { ContainerWidget, Div, Paragraph, Table, Td, Th, Tr } from "./widget"

type FeatureSelectionCheckbox = CheckboxWidget<IlpFeatureExtractor>

Expand Down Expand Up @@ -54,7 +54,7 @@ export class FeatureSelector{
public readonly element: Div
private baseScales: Array<number>
private checkboxes: Map<FeatureClassName, Map<number, FeatureSelectionCheckbox>>
checkboxesContainer: Paragraph
checkboxesContainer: Table
public readonly buttonsContainer: Paragraph

public get value(): FeatureExtractorSet{
Expand All @@ -78,14 +78,14 @@ export class FeatureSelector{
val.getScales().forEach(s => scalesSet.add(s))
let scales = Array.from(scalesSet).sort((a, b) => a - b)

new TableRow({parentElement: this.checkboxesContainer, children: [
new TableHeader({innerText: 'Feature / sigma', parentElement: undefined}),
...scales.map(scale => new TableHeader({parentElement: undefined, innerText: scale.toFixed(1).toString()}))
new Tr({parentElement: this.checkboxesContainer, children: [
new Th({innerText: 'Feature / sigma', parentElement: undefined}),
...scales.map(scale => new Th({parentElement: undefined, innerText: scale.toFixed(1).toString()}))
]})

featureNames.forEach(feature_name => {
let tr = new TableRow({parentElement: this.checkboxesContainer, children: [
new TableData({parentElement: undefined, innerText: feature_name})
let tr = new Tr({parentElement: this.checkboxesContainer, children: [
new Td({parentElement: undefined, innerText: feature_name})
]})
const checkboxLine = new Map<number, FeatureSelectionCheckbox>()
this.checkboxes.set(feature_name, checkboxLine)
Expand All @@ -96,7 +96,7 @@ export class FeatureSelector{
axis_2d: "z", //FIXME
__class__: feature_name,
});
let td = new TableData({parentElement: tr});
let td = new Td({parentElement: tr});
let checked = val.contains(featureExtractor);
if(scale == 0.3 && feature_name != "Gaussian Smoothing" && !checked){
return
Expand Down
2 changes: 1 addition & 1 deletion overlay/src/gui/widgets/input_widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export abstract class InputWidget<IT extends InputType> extends Widget<"input">{
export class CheckboxWidget<T> extends InputWidget<"checkbox">{
public readonly valueWhenChecked: T;

constructor(params: Omit<InputWidgetParams, "onClick"> & {
constructor(params: InputWidgetParams & {
checked?: boolean,
valueWhenChecked: T,
}){
Expand Down
105 changes: 48 additions & 57 deletions overlay/src/gui/widgets/layer_widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,44 @@ import { INativeView, IViewerDriver } from "../../drivers/viewer_driver";
import { uuidv4 } from "../../util/misc";
import { Url } from "../../util/parsed_url";
import { CssClasses } from "../css_classes";
import { Button } from "./input_widget";
import { ToggleButton } from "./value_input_widget";
import { ContainerWidget, Div, Label, Paragraph, Span } from "./widget";
import { Button, CheckboxWidget } from "./input_widget";
import { ContainerWidget, Table, TBody, Td, Tr } from "./widget";

class LayerWidget{
public readonly nativeView: INativeView;

public readonly element: Div;
private readonly visibilityInput: ToggleButton;
public readonly element: Tr;
private readonly visibilityInput: CheckboxWidget<true>;
// private readonly opacitySlider: RangeInput;

public constructor(params: {
parentElement: ContainerWidget<any> | undefined,
parentElement: TBody | undefined,
nativeView: INativeView,
name: string,
}){
this.nativeView = params.nativeView

this.element = new Div({parentElement: params.parentElement, cssClasses: [CssClasses.ItkLaneLayerWidget]})

new Label({parentElement: this.element, innerText: params.name})
this.visibilityInput = new ToggleButton({
text: "👁️",
parentElement: this.element,
value: true,
onClick: () => {
this.nativeView.reconfigure({isVisible: this.visibilityInput.value})
}
})

// new ToggleVisibilityButton({
// parentElement: this.element,
// text: "⚙",
// subject: new Div({
// parentElement: this.element,
// children: [
// new Label({parentElement: undefined, innerText: "opacity: "}),
// this.opacitySlider = new RangeInput({parentElement: undefined, min: 0, max: 1, value: 0.5, step: 0.05, onChange: () => {
// this.nativeView.reconfigure({opacity: this.opacitySlider.value})
// }})
// ]
// })
// })
this.element = new Tr({parentElement: params.parentElement, children: [
new Td({parentElement: undefined, innerText: params.name, cssClasses: [CssClasses.ItkLaneLayerName]}),
new Td({parentElement: undefined, children: [
this.visibilityInput = new CheckboxWidget<true>({
parentElement: undefined,
valueWhenChecked: true,
checked: true,
onClick: () => {
this.nativeView.reconfigure({isVisible: this.visibilityInput.checked})
}
})
]})
]})
}

public enableVisibilityControls(enable: boolean){
this.visibilityInput.disabled = !enable
}

public get isVisible(): boolean{
return this.visibilityInput.value
return this.visibilityInput.checked
}

public destroy(){
Expand Down Expand Up @@ -92,7 +79,7 @@ export class RawDataLayerWidget extends LayerWidget{
]

constructor(params: {
parentElement: ContainerWidget<any> | undefined,
parentElement: TBody | undefined,
datasource: FsDataSource,
opacity: number,
nativeView: INativeView,
Expand All @@ -102,7 +89,7 @@ export class RawDataLayerWidget extends LayerWidget{
}

public static async create(params: {
parentElement: ContainerWidget<any> | undefined,
parentElement: TBody | undefined,
driver: IViewerDriver,
session: Session,
datasource: FsDataSource,
Expand Down Expand Up @@ -154,7 +141,7 @@ export class PredictionsLayerWidget extends LayerWidget{
public channelColors: Color[]

constructor(params: {
parentElement: ContainerWidget<any>,
parentElement: TBody,
rawData: FsDataSource,
classifierGeneration: number,
channelColors: Color[],
Expand All @@ -168,7 +155,7 @@ export class PredictionsLayerWidget extends LayerWidget{
}

public static async create(params: {
parentElement: ContainerWidget<any>,
parentElement: TBody,
driver: IViewerDriver,
session: Session,
rawData: FsDataSource,
Expand Down Expand Up @@ -245,10 +232,10 @@ export class PredictionsParams{
}

export class PixelClassificationLaneWidget{
private element: Div;
private element: TBody;
private rawDataWidget: RawDataLayerWidget;
private driver: IViewerDriver;
private readonly visibilityInput: ToggleButton;
private readonly visibilityInput: CheckboxWidget<true>;

private _predictionsWidget: PredictionsLayerWidget | undefined | PredictionsParams = undefined
private get predictionsWidget(): PredictionsLayerWidget | undefined{
Expand All @@ -259,30 +246,34 @@ export class PixelClassificationLaneWidget{
}

private constructor(params: {
parentElement: ContainerWidget<any>,
parentElement: Table,
name: string,
rawDataWidget: RawDataLayerWidget,
driver: IViewerDriver,
isVisible: boolean,
onDestroyed: (lane: PixelClassificationLaneWidget) => void,
onVisibilityChanged: (lane: PixelClassificationLaneWidget) => void,
}){
this.element = new Div({parentElement: params.parentElement, cssClasses: [CssClasses.ItkLaneWidget], children: [
new Paragraph({parentElement: undefined, children: [
new Span({parentElement: undefined, innerText: params.name, title: params.rawDataWidget.datasource.url.raw}),
this.visibilityInput = new ToggleButton({
parentElement: undefined,
text: "👁️",
value: params.isVisible,
onClick: () => {
this.setVisible(this.visibilityInput.value)
params.onVisibilityChanged(this)
}
}),
new Button({inputType: "button", text: "✖", parentElement: undefined, onClick: () => {
this.destroy()
params.onDestroyed(this)
}}),
this.element = new TBody({parentElement: params.parentElement, children: [
new Tr({parentElement: undefined, children: [
new Td({parentElement: undefined, innerText: params.name, title: params.rawDataWidget.datasource.url.raw}),
new Td({parentElement: undefined, children: [
this.visibilityInput = new CheckboxWidget<true>({
parentElement: undefined,
checked: params.isVisible,
valueWhenChecked: true,
onClick: () => {
this.setVisible(this.visibilityInput.checked)
params.onVisibilityChanged(this)
}
}),
]}),
new Td({parentElement: undefined, children: [
new Button({inputType: "button", text: "✖", parentElement: undefined, onClick: () => {
this.destroy()
params.onDestroyed(this)
}}),
]}),
]}),

]})
Expand Down Expand Up @@ -334,7 +325,7 @@ export class PixelClassificationLaneWidget{
}

public get isVisible(): boolean{
return this.visibilityInput.value
return this.visibilityInput.checked
}
public get rawData(): FsDataSource{
return this.rawDataWidget.datasource
Expand All @@ -348,7 +339,7 @@ export class PixelClassificationLaneWidget{
this.rawDataWidget.nativeView.reconfigure({isVisible: false})
this.predictionsWidget?.nativeView.reconfigure({isVisible: false})
}
this.visibilityInput.value = isVisible
this.visibilityInput.checked = isVisible
this.rawDataWidget.enableVisibilityControls(isVisible)
this.predictionsWidget?.enableVisibilityControls(isVisible)
}
Expand Down
8 changes: 4 additions & 4 deletions overlay/src/gui/widgets/list_widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DataProxyFilePicker } from "./data_proxy_file_picker";
import { Button } from "./input_widget";
import { LiveFsTree } from "./live_fs_tree";
import { PopupWidget } from "./popup";
import { ContainerWidget, Div, Paragraph, Span, Table, TableData, TableRow, TagName, Widget } from "./widget";
import { ContainerWidget, Div, Paragraph, Span, Table, Td, Tr, TagName, Widget } from "./widget";

export class ListWidget<T> extends Table{
private items = new Array<T>();
Expand Down Expand Up @@ -50,9 +50,9 @@ export class ListWidget<T> extends Table{
for(let i=0; i<this.items.length; i++){
const item = this.items[i];

new TableRow({parentElement: this, cssClasses: [CssClasses.ItkListWidgetRow], children: [
new TableData({parentElement: undefined, children: [this.itemRenderer(item)]}),
new TableData({parentElement: undefined, children: [
new Tr({parentElement: this, cssClasses: [CssClasses.ItkListWidgetRow], children: [
new Td({parentElement: undefined, children: [this.itemRenderer(item)]}),
new Td({parentElement: undefined, children: [
new Button({inputType: "button", parentElement: undefined, text: "✖", title: "Remove this item", onClick: () => {
this.items.splice(i, 1);
this.redraw()
Expand Down
30 changes: 15 additions & 15 deletions overlay/src/gui/widgets/predictions_export_widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { DatasinkConfigWidget, UnsupportedDziDataType } from './datasink_builder
import { DataType } from '../../util/precomputed_chunks';
import { FileLocationPatternInputWidget } from './file_location_input';
import { Button, ButtonWidget, Select } from './input_widget';
import { Anchor, Div, Label, Paragraph, Span, Table, TableData, TableHeader, TableRow } from './widget';
import { Anchor, Div, Label, Paragraph, Span, Table, Td, Th, Tr, THead } from './widget';
import { Path, Url } from '../../util/parsed_url';
import { BooleanInput } from './value_input_widget';
import { Shape5DInputNoChannel } from './shape5d_input';
Expand Down Expand Up @@ -73,15 +73,15 @@ class Job{
private makeProgressDisplay(params: {
viewer: Viewer,
session: Session,
}): TableData{
}): Td{
const jobDto = this.jobDto

if(jobDto.status instanceof JobIsPendingDto){
return new TableData({parentElement: undefined, innerText: "pending"})
return new Td({parentElement: undefined, innerText: "pending"})
}
if(jobDto.status instanceof JobCanceledDto){
const cancellationMessage = jobDto.status.message;
return new TableData({parentElement: undefined, children: [
return new Td({parentElement: undefined, children: [
new Label({parentElement: undefined, innerText: "cancelled"}),
new ButtonWidget({
parentElement: undefined, contents: "?", onClick: () => PopupWidget.OkPopup({
Expand All @@ -91,7 +91,7 @@ class Job{
]})
}
if(jobDto.status instanceof JobIsRunningDto){
return new TableData({
return new Td({
parentElement: undefined,
innerText: jobDto.num_args === undefined ?
"unknwown" :
Expand All @@ -102,11 +102,11 @@ class Job{
assertUnreachable(jobDto.status)
}
if(jobDto.status.error_message){
let td = new TableData({parentElement: undefined, innerText: "failed"})
let td = new Td({parentElement: undefined, innerText: "failed"})
td.element.title = jobDto.status.error_message
return td
}
let out = new TableData({parentElement: undefined})
let out = new Td({parentElement: undefined})

let dataProxyGuiUrl: Url | undefined = undefined;

Expand Down Expand Up @@ -145,12 +145,12 @@ class Job{

return out
}
public toTableRow(params: {
public toTr(params: {
viewer: Viewer,
session: Session,
}): {name: TableData, progress: TableData}{
}): {name: Td, progress: Td}{
return {
name: new TableData({parentElement: undefined, innerText: this.jobDto.name}),
name: new Td({parentElement: undefined, innerText: this.jobDto.name}),
progress: this.makeProgressDisplay(params),
}
}
Expand Down Expand Up @@ -450,18 +450,18 @@ export class PredictionsExportWidget extends Applet<PixelClassificationExportApp
}

const jobsTable = new Table({parentElement: this.jobsDisplay, cssClasses: [CssClasses.ItkTable], children: [
new TableRow({parentElement: undefined, children: [
new TableHeader({parentElement: undefined, innerText: "Name"}), //FIXME: mode? name?
new TableHeader({parentElement: undefined, innerText: "Progress"}),
new THead({parentElement: undefined, children: [
new Th({parentElement: undefined, innerText: "Name"}), //FIXME: mode? name?
new Th({parentElement: undefined, innerText: "Progress"}),
]}),
]})

new_state.jobs.forEach(job => {
const row = job.toTableRow({
const row = job.toTr({
session: this.session,
viewer: this.viewer
})
new TableRow({parentElement: jobsTable, children: [row.name, row.progress]})
new Tr({parentElement: jobsTable, children: [row.name, row.progress]})
})
}
}
Loading

0 comments on commit 523435d

Please sign in to comment.