UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

184 lines 5.83 kB
import { View } from "../../core/view"; import { min, max } from "../../core/util/array"; import { entries } from "../../core/util/object"; import { isString } from "../../core/util/types"; import { Comparator } from "../../core/util/eq"; import { Model } from "../../model"; import { MenuItem, Menu } from "../ui/menus"; import { IconLike } from "../common/kinds"; export class ToolView extends View { static __name__ = "ToolView"; connect_signals() { super.connect_signals(); this.connect(this.model.properties.active.change, () => { if (this.model.active) { this.activate(); } else { this.deactivate(); } }); } get overlays() { return []; } // activate is triggered by toolbar ui actions activate() { } // deactivate is triggered by toolbar ui actions deactivate() { } } export class Tool extends Model { static __name__ = "Tool"; constructor(attrs) { super(attrs); } static { this.prototype._known_aliases = new Map(); this.define(({ Bool, Or, Str, Nullable }) => ({ icon: [Nullable(IconLike), null], description: [Nullable(Str), null], visible: [Bool, true], group: [Or(Str, Bool), true], })); this.internal(({ Bool }) => ({ active: [Bool, false], disabled: [Bool, false], })); } tool_name; tool_icon; // CSS class (no dot) // GestureTool {{{ event_type; get event_role() { const { event_type } = this; return isString(event_type) ? event_type : "multi"; } get event_types() { const { event_type } = this; return event_type == null ? [] : (isString(event_type) ? [event_type] : event_type); } // }}} button_view; menu_item() { const item = new MenuItem({ icon: this.computed_icon, label: this.tool_name, tooltip: this.tooltip != this.tool_name ? this.tooltip : undefined, checked: () => this.active, disabled: () => this.disabled, action: () => this.active = !this.active, }); const submenu = this.menu; if (submenu != null) { item.menu = new Menu({ items: submenu }); } return item; } get tooltip() { return this.description ?? this.tool_name; } get computed_icon() { const { icon, tool_icon } = this; return icon ?? (tool_icon != null ? `.${tool_icon}` : undefined); } get menu() { return null; } supports_auto() { return false; } // utility function to get limits along both dimensions, given // optional dimensional constraints _get_dim_limits([sx0, sy0], [sx1, sy1], frame, dims) { const hr = frame.bbox.h_range; let sxlim; if (dims == "width" || dims == "both") { sxlim = [min([sx0, sx1]), max([sx0, sx1])]; sxlim = [max([sxlim[0], hr.start]), min([sxlim[1], hr.end])]; } else { sxlim = [hr.start, hr.end]; } const vr = frame.bbox.v_range; let sylim; if (dims == "height" || dims == "both") { sylim = [min([sy0, sy1]), max([sy0, sy1])]; sylim = [max([sylim[0], vr.start]), min([sylim[1], vr.end])]; } else { sylim = [vr.start, vr.end]; } return [sxlim, sylim]; } _compute_overlay_limits(sxlim, sylim, dims, line_width) { if (dims == "width") { sylim[0] -= line_width; // top sylim[1] += line_width; // bottom } else if (dims == "height") { sxlim[0] -= line_width; // left sxlim[1] += line_width; // right } return [sxlim, sylim]; } // utility function to return a tool name, modified // by the active dimensions. Used by tools that have dimensions _get_dim_tooltip(dims) { const { description, tool_name } = this; if (description != null) { return description; } else if (dims == "both") { return tool_name; } else if (dims == "auto") { return `${tool_name} (either x, y or both dimensions)`; } else { return `${tool_name} (${dims == "width" ? "x" : "y"}-axis)`; } } /** @prototype */ _known_aliases; static register_alias(name, fn) { const tool = fn(); const attrs = tool.dirty_attributes; const cmp = new Comparator(); const query = (obj) => { if (!(obj instanceof tool.constructor)) { return false; } for (const [attr, value] of entries(attrs)) { if (!cmp.eq(value, obj.property(attr).get_value())) { return false; } } return true; }; this.prototype._known_aliases.set(name, { fn, query }); } /** * Is the given tool member of the given tool family. */ static is_alias_of(tool, name) { const spec = this.prototype._known_aliases.get(name); return spec?.query(tool.underlying) ?? false; } static from_string(name) { const spec = this.prototype._known_aliases.get(name); if (spec != null) { return spec.fn(); } else { const names = [...this.prototype._known_aliases.keys()]; throw new Error(`unexpected tool name '${name}', possible tools are ${names.join(", ")}`); } } /** * Unifying API with ProxyTool. */ get underlying() { return this; } } //# sourceMappingURL=tool.js.map