2017-10-10 22:32:46 +00:00
|
|
|
/// <reference path="UIBuilder.ts" />
|
|
|
|
|
2017-09-24 22:23:22 +00:00
|
|
|
module TK.SpaceTac.UI {
|
2017-04-19 21:34:11 +00:00
|
|
|
|
2018-02-08 15:16:03 +00:00
|
|
|
export type TooltipFiller = string | ((filler: TooltipBuilder) => string) | ((filler: TooltipBuilder) => boolean);
|
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
export class TooltipContainer extends UIContainer {
|
2017-04-19 21:34:11 +00:00
|
|
|
view: BaseView
|
2018-05-15 14:57:45 +00:00
|
|
|
background: UIBackground
|
|
|
|
content: UIContainer
|
2018-01-31 18:19:50 +00:00
|
|
|
item?: IBounded
|
2017-05-15 23:20:35 +00:00
|
|
|
border = 10
|
|
|
|
margin = 6
|
|
|
|
viewport: IBounded | null = null
|
2017-04-19 21:34:11 +00:00
|
|
|
|
|
|
|
constructor(view: BaseView) {
|
2018-05-15 14:57:45 +00:00
|
|
|
super(view);
|
2017-04-19 21:34:11 +00:00
|
|
|
|
|
|
|
this.view = view;
|
|
|
|
this.visible = false;
|
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
this.background = new UIBackground(view, this);
|
2017-04-19 21:34:11 +00:00
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
this.content = new UIContainer(view);
|
2017-04-19 21:34:11 +00:00
|
|
|
this.add(this.content);
|
2017-05-14 23:00:36 +00:00
|
|
|
|
|
|
|
this.view.tooltip_layer.add(this);
|
2017-04-19 21:34:11 +00:00
|
|
|
}
|
|
|
|
|
2017-05-15 23:20:35 +00:00
|
|
|
show(item: IBounded) {
|
|
|
|
this.item = item;
|
2017-04-19 21:34:11 +00:00
|
|
|
this.visible = true;
|
2017-05-15 23:20:35 +00:00
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
|
|
|
|
tryPosition(viewport: IBounded, tooltip: IBounded): [number, number, number] {
|
|
|
|
let [x, y] = UITools.positionInside(tooltip, viewport);
|
|
|
|
let distance = Math.max(Math.abs(x - tooltip.x), Math.abs(y - tooltip.y));
|
|
|
|
if (this.view.isMouseInside({ x: x, y: y, width: tooltip.width, height: tooltip.height })) {
|
|
|
|
distance += 1000;
|
|
|
|
}
|
|
|
|
return [x, y, distance];
|
|
|
|
}
|
|
|
|
|
|
|
|
getBestPosition(item: IBounded, width: number, height: number): [number, number] {
|
|
|
|
let viewport = this.viewport || { x: 0, y: 0, width: this.view.getWidth(), height: this.view.getHeight() };
|
|
|
|
let candidates = [
|
|
|
|
this.tryPosition(viewport, { x: item.x + item.width / 2 - width / 2, y: item.y + item.height + this.margin, width: width, height: height }),
|
|
|
|
this.tryPosition(viewport, { x: item.x + item.width + this.margin, y: item.y + item.height / 2 - height / 2, width: width, height: height }),
|
|
|
|
this.tryPosition(viewport, { x: item.x + item.width / 2 - width / 2, y: item.y - height - this.margin, width: width, height: height }),
|
|
|
|
this.tryPosition(viewport, { x: item.x - width - this.margin, y: item.y + item.height / 2 - height / 2, width: width, height: height }),
|
|
|
|
]
|
|
|
|
candidates[0][2] -= 1; // preference to down tooltip on equality
|
|
|
|
let [x, y, distance] = candidates.sort((a, b) => cmp(a[2], b[2]))[0];
|
|
|
|
return [x, y];
|
2017-04-19 21:34:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
update() {
|
2018-01-31 18:19:50 +00:00
|
|
|
if (this.visible && this.item) {
|
2017-05-22 20:41:34 +00:00
|
|
|
let [width, height] = UITools.drawBackground(this.content, this.background, this.border);
|
2017-04-19 21:34:11 +00:00
|
|
|
|
2017-05-15 23:20:35 +00:00
|
|
|
let [x, y] = this.getBestPosition(this.item, width, height);
|
|
|
|
x += this.border;
|
|
|
|
y += this.border;
|
2017-04-19 21:34:11 +00:00
|
|
|
if (x != this.x || y != this.y) {
|
2018-05-15 14:57:45 +00:00
|
|
|
this.setPosition(x, y);
|
2017-04-19 21:34:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hide() {
|
|
|
|
this.content.removeAll();
|
2017-05-15 23:20:35 +00:00
|
|
|
this.background.clear();
|
2017-04-19 21:34:11 +00:00
|
|
|
this.visible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-14 23:00:36 +00:00
|
|
|
/**
|
|
|
|
* Functions used to fill a tooltip content
|
|
|
|
*/
|
2017-12-11 00:31:16 +00:00
|
|
|
export class TooltipBuilder extends UIBuilder {
|
2018-05-15 14:57:45 +00:00
|
|
|
private content: TooltipContainer;
|
2017-05-14 23:00:36 +00:00
|
|
|
|
|
|
|
constructor(container: TooltipContainer) {
|
2017-10-10 22:32:46 +00:00
|
|
|
let style = new UITextStyle();
|
|
|
|
style.center = false;
|
|
|
|
style.vcenter = false;
|
2017-12-11 00:31:16 +00:00
|
|
|
style.shadow = true;
|
2017-10-10 22:32:46 +00:00
|
|
|
super(container.view, container.content, style);
|
2017-05-14 23:00:36 +00:00
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
this.content = container;
|
2017-05-28 20:37:07 +00:00
|
|
|
}
|
|
|
|
|
2017-05-15 23:20:35 +00:00
|
|
|
/**
|
|
|
|
* Configure the positioning and base style of the tooltip
|
|
|
|
*/
|
|
|
|
configure(border = 10, margin = 6, viewport: IBounded | null = null): void {
|
2018-05-15 14:57:45 +00:00
|
|
|
this.content.border = border;
|
|
|
|
this.content.margin = margin;
|
2017-05-15 23:20:35 +00:00
|
|
|
if (viewport) {
|
2018-05-15 14:57:45 +00:00
|
|
|
this.content.viewport = viewport;
|
2017-05-15 23:20:35 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-14 23:00:36 +00:00
|
|
|
}
|
|
|
|
|
2017-03-15 21:40:19 +00:00
|
|
|
/**
|
|
|
|
* Tooltip system, to display information on hover
|
|
|
|
*/
|
|
|
|
export class Tooltip {
|
2018-05-15 14:57:45 +00:00
|
|
|
readonly view: BaseView;
|
|
|
|
readonly container: TooltipContainer;
|
2017-03-15 21:40:19 +00:00
|
|
|
|
|
|
|
constructor(view: BaseView) {
|
|
|
|
this.view = view;
|
2017-04-19 21:34:11 +00:00
|
|
|
this.container = new TooltipContainer(view);
|
2017-03-15 21:40:19 +00:00
|
|
|
}
|
|
|
|
|
2017-05-14 23:00:36 +00:00
|
|
|
get ui(): MainUI {
|
|
|
|
return this.view.gameui;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-12-11 00:31:16 +00:00
|
|
|
* Get a tooltip builder
|
2017-05-14 23:00:36 +00:00
|
|
|
*/
|
2017-12-11 00:31:16 +00:00
|
|
|
getBuilder(): TooltipBuilder {
|
|
|
|
return new TooltipBuilder(this.container);
|
2017-05-14 23:00:36 +00:00
|
|
|
}
|
|
|
|
|
2017-03-15 21:40:19 +00:00
|
|
|
/**
|
|
|
|
* Bind to an UI component
|
|
|
|
*
|
|
|
|
* When the component is hovered, the function is called to allow filling the tooltip container
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
bind(obj: UIButton | UIImage, func: (filler: TooltipBuilder) => boolean): void {
|
2017-10-01 20:52:50 +00:00
|
|
|
this.view.inputs.setHoverClick(obj,
|
2017-03-15 21:40:19 +00:00
|
|
|
// enter
|
|
|
|
() => {
|
2017-04-11 17:01:05 +00:00
|
|
|
this.hide();
|
2017-12-11 00:31:16 +00:00
|
|
|
if (func(this.getBuilder())) {
|
2018-05-15 14:57:45 +00:00
|
|
|
this.container.show(UITools.getBounds(obj));
|
2017-03-15 21:40:19 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
// leave
|
2017-04-11 17:01:05 +00:00
|
|
|
() => this.hide(),
|
2017-03-15 21:40:19 +00:00
|
|
|
// click
|
2017-04-11 17:01:05 +00:00
|
|
|
() => this.hide()
|
2017-03-15 21:40:19 +00:00
|
|
|
);
|
2018-05-15 14:57:45 +00:00
|
|
|
obj.on("pointerdown", () => this.hide());
|
2017-03-15 21:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bind to an UI component to display a dynamic text
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
bindDynamicText(obj: UIButton | UIImage, text_getter: () => string): void {
|
2017-05-14 23:00:36 +00:00
|
|
|
this.bind(obj, filler => {
|
2017-05-14 21:08:36 +00:00
|
|
|
let content = text_getter();
|
|
|
|
if (content) {
|
2017-10-10 22:32:46 +00:00
|
|
|
filler.text(content, 0, 0, { color: "#cccccc", size: 20 });
|
2017-05-14 21:08:36 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2017-03-15 21:40:19 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bind to an UI component to display a simple text
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
bindStaticText(obj: UIButton | UIImage, text: string): void {
|
2017-03-15 21:40:19 +00:00
|
|
|
this.bindDynamicText(obj, () => text);
|
|
|
|
}
|
2017-04-11 17:01:05 +00:00
|
|
|
|
2018-02-08 15:16:03 +00:00
|
|
|
/**
|
|
|
|
* Show a tooltip for a component
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
show(obj: UIButton, content: TooltipFiller): void {
|
2018-02-08 15:16:03 +00:00
|
|
|
let builder = this.getBuilder();
|
|
|
|
let scontent = (typeof content == "string") ? content : content(builder);
|
|
|
|
if (typeof scontent == "string") {
|
|
|
|
builder.text(scontent, 0, 0, { color: "#cccccc", size: 20 });
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scontent) {
|
2018-05-15 14:57:45 +00:00
|
|
|
this.container.show(UITools.getBounds(obj));
|
2018-02-08 15:16:03 +00:00
|
|
|
} else {
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-11 17:01:05 +00:00
|
|
|
/**
|
|
|
|
* Hide the current tooltip
|
|
|
|
*/
|
|
|
|
hide(): void {
|
2017-04-19 21:34:11 +00:00
|
|
|
this.container.hide();
|
2017-04-11 17:01:05 +00:00
|
|
|
}
|
2017-03-15 21:40:19 +00:00
|
|
|
}
|
|
|
|
}
|