Skip to content

Commit 144a6e8

Browse files
Merge pull request #242 from SenteraLLC/fix/slider-value
Fix/slider value
2 parents 674b9d9 + ccd0cd3 commit 144a6e8

11 files changed

Lines changed: 173 additions & 14 deletions

File tree

.github/tasks.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
11
## Tasks
2-
- [x] Read the discussion in issue [#159](https://github.com/SenteraLLC/ulabel/issues/159)
3-
- [x] Implement a vertex deletion keybind for polygon and polyline spatial types it should:
4-
- [x] Delete the vertex when pressed when hovering over it such that the edit suggestion is showing
5-
- [x] Delete the vertex when pressed when dragging/editing the vertex
6-
- [x] For polylines, if only one point remains in the polyline, it should delete the polyline
7-
- [x] For polygons, if fewer than 3 points remain in a polygon layer, the layer should be removed
8-
- [x] Add a test for the keybind in keybind-functionality.spec.js
9-
- [x] Update the api_spec and changelog
10-
2+
-

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented here.
44

55
## [unreleased]
66

7+
## [0.23.3] - Mar 18th, 2026
8+
- Add `get_keypoint_slider_value()` public API method to get the current keypoint slider value (0-1).
9+
- Add `get_distance_filter_value()` public API method to get the current distance filter slider values.
10+
711
## [0.23.2] - Mar 18th, 2026
812
- Fix bug where multiple spaces in a submit button name would cause the button hook to not fire.
913

api_spec.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,14 @@ Sets the zoom to focus on the provided annotation id, and switches to its subtas
559559
### `fly_to_annotation(annotation, subtask_key, max_zoom)`
560560
Sets the zoom to focus on the provided annotation, and switches to its subtask if provided. Returns `true` on success and `false` on failure (eg, annotation doesn't exist in subtask, is not a spatial annotation, or is deprecated).
561561
562+
### `get_keypoint_slider_value()`
563+
564+
*() => number | null* -- Returns the current keypoint slider value as a number between 0 and 1. Returns `null` if the KeypointSlider toolbox item is not active or the slider element is not found.
565+
566+
### `get_distance_filter_value()`
567+
568+
*() => object | null* -- Returns an object mapping class identifiers to their distance filter values (in pixels). The object always includes a `closest_row` key for the single-class slider. In multi-class mode, additional keys correspond to each class ID. Returns `null` if the FilterDistance toolbox item is not active or no sliders are found.
569+
562570
## Generic Callbacks
563571
564572
Callbacks can be provided by calling `.on(fn, callback)` on a `ULabel` object.

index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ export class ULabel {
338338
force_filter_all?: boolean,
339339
offset?: Offset,
340340
): void;
341+
public get_keypoint_slider_value(): number | null;
342+
public get_distance_filter_value(): DistanceFromPolylineClasses | null;
341343
public fly_to_next_annotation(increment: number, max_zoom?: number): boolean;
342344
public fly_to_annotation_id(annotation_id: string, subtask_key?: string, max_zoom?: number): boolean;
343345
public fly_to_annotation(annotation: ULabelAnnotation, subtask_key?: string, max_zoom?: number): boolean;

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ulabel",
33
"description": "An image annotation tool.",
4-
"version": "0.23.2",
4+
"version": "0.23.3",
55
"main": "dist/ulabel.min.js",
66
"module": "dist/ulabel.min.js",
77
"types": "index.d.ts",

src/annotation_operators.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {
1010
// Import ULabel from ../src/index - TypeScript will find ../src/index.d.ts for types
1111
import { ULabel } from "../src/index";
1212

13-
import { ULabelAnnotation } from "./annotation";
13+
import { ULabelAnnotation, DELETE_CLASS_ID } from "./annotation";
1414
import { ULabelSubtask } from "./subtask";
1515

1616
/**
@@ -582,6 +582,8 @@ export function findAllPolylineClassDefinitions(ulabel: ULabel) {
582582
if (subtask.allowed_modes.includes("polyline")) {
583583
// Loop through all the classes in the subtask
584584
subtask.class_defs.forEach((current_class_def) => {
585+
// Skip the reserved delete class
586+
if (current_class_def.id === DELETE_CLASS_ID) return;
585587
potential_class_defs.push(current_class_def);
586588
});
587589
}

src/index.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,32 @@ export class ULabel {
10201020
}
10211021
}
10221022

1023+
/**
1024+
* Get the current keypoint slider value.
1025+
*
1026+
* @returns {number|null} The current slider value as a number between 0 and 1,
1027+
* or null if the KeypointSlider toolbox item is not active or the slider is not found
1028+
*/
1029+
get_keypoint_slider_value() {
1030+
if (!this.config.toolbox_order.includes(AllowedToolboxItem.KeypointSlider)) return null;
1031+
const item = this.toolbox.items.find((item) => item.get_toolbox_item_type() === "KeypointSlider");
1032+
if (item === undefined) return null;
1033+
return item.get_current_value();
1034+
}
1035+
1036+
/**
1037+
* Get the current distance filter slider values.
1038+
*
1039+
* @returns {object|null} An object mapping class identifiers to their distance values,
1040+
* or null if the FilterDistance toolbox item is not active or no sliders are found
1041+
*/
1042+
get_distance_filter_value() {
1043+
if (!this.config.toolbox_order.includes(AllowedToolboxItem.FilterDistance)) return null;
1044+
const item = this.toolbox.items.find((item) => item.get_toolbox_item_type() === "FilterDistance");
1045+
if (item === undefined) return null;
1046+
return item.get_current_values();
1047+
}
1048+
10231049
// Show annotation mode
10241050
show_annotation_mode(el = null) {
10251051
if (el === null) {

src/toolbox.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,17 @@ export class KeypointSliderItem extends ToolboxItem {
19471947
`;
19481948
}
19491949

1950+
/**
1951+
* Get the current keypoint slider value by reading the DOM slider element.
1952+
*
1953+
* @returns The current slider value as a number between 0 and 1, or null if the slider is not found
1954+
*/
1955+
public get_current_value(): number | null {
1956+
const slider = document.querySelector<HTMLInputElement>(`#${this.slider_bar_id}`);
1957+
if (slider === null) return null;
1958+
return slider.valueAsNumber / 100;
1959+
}
1960+
19501961
public after_init() {
19511962
// This toolbox item doesn't need to do anything after initialization
19521963
}
@@ -2355,6 +2366,40 @@ export class FilterPointDistanceFromRow extends ToolboxItem {
23552366
// This toolbox item doesn't need to do anything after initialization
23562367
}
23572368

2369+
/**
2370+
* Get the current distance filter slider values by reading the DOM slider elements.
2371+
*
2372+
* @returns An object mapping class identifiers to their distance values, or null if no sliders are found
2373+
*/
2374+
public get_current_values(): DistanceFromPolylineClasses | null {
2375+
// Always read the single-class slider for closest_row
2376+
const single_container = document.getElementById("filter-single-class-mode");
2377+
if (single_container === null) return null;
2378+
2379+
const single_slider = single_container.querySelector<HTMLInputElement>(".filter-row-distance-slider");
2380+
if (single_slider === null) return null;
2381+
2382+
const filter_values: DistanceFromPolylineClasses = {
2383+
closest_row: { distance: single_slider.valueAsNumber },
2384+
};
2385+
2386+
// In multi-class mode, also read the per-class sliders
2387+
if (this.multi_class_mode) {
2388+
const multi_container = document.getElementById("filter-multi-class-mode");
2389+
if (multi_container !== null) {
2390+
const sliders = multi_container.querySelectorAll<HTMLInputElement>(".filter-row-distance-slider");
2391+
for (let idx = 0; idx < sliders.length; idx++) {
2392+
const slider_class_name = /[^-]*$/.exec(sliders[idx].id)[0];
2393+
filter_values[slider_class_name] = {
2394+
distance: sliders[idx].valueAsNumber,
2395+
};
2396+
}
2397+
}
2398+
}
2399+
2400+
return filter_values;
2401+
}
2402+
23582403
public get_toolbox_item_type() {
23592404
return "FilterDistance";
23602405
}

src/version.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const ULABEL_VERSION = "0.23.2";
1+
export const ULABEL_VERSION = "0.23.3";

0 commit comments

Comments
 (0)