Skip to content

Commit

Permalink
Add "open image in a new tab" mode to save tool (bokeh#14031)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpap authored Aug 21, 2024
1 parent f5d54ea commit 2bfef99
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 6 deletions.
5 changes: 5 additions & 0 deletions bokehjs/src/less/icons.less
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
.tool-icon-mask(var(--bokeh-icon-copy));
}

.bk-tool-icon-open {
.tool-icon-mask(var(--bokeh-icon-open));
}

.bk-tool-icon-replace-mode {
.tool-icon(--bokeh-icon-replace-mode, "ReplaceMode");
}
Expand Down Expand Up @@ -232,6 +236,7 @@

--bokeh-icon-save: data-uri("icons/save.svg");
--bokeh-icon-copy: data-uri("icons/copy.svg");
--bokeh-icon-open: data-uri("icons/open.svg");

--bokeh-icon-tap-select: data-uri("icons/tap.svg");
--bokeh-icon-lasso-select: data-uri("icons/lasso-select.svg");
Expand Down
4 changes: 4 additions & 0 deletions bokehjs/src/less/icons/open.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 27 additions & 6 deletions bokehjs/src/lib/models/tools/actions/save_tool.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import {ActionTool, ActionToolView} from "./action_tool"
import type * as p from "core/properties"
import {tool_icon_save} from "styles/icons.css"
import * as icons from "styles/icons.css"
import type {MenuItem} from "core/util/menus"

export class SaveToolView extends ActionToolView {
declare model: SaveTool

protected async _export(): Promise<Blob> {
return this.parent.export().to_blob()
}

async copy(): Promise<void> {
const blob = await this.parent.export().to_blob()
const blob = await this._export()
const item = new ClipboardItem({[blob.type]: blob})
await navigator.clipboard.write([item])
}

async save(name: string): Promise<void> {
const blob = await this.parent.export().to_blob()
const blob = await this._export()
const link = document.createElement("a")
link.href = URL.createObjectURL(blob)
link.download = name // + ".png" | "svg" (inferred from MIME type)
link.target = "_blank"
link.dispatchEvent(new MouseEvent("click"))
}

doit(action: "save" | "copy" = "save"): void {
async open(): Promise<void> {
const blob = await this._export()
const url = URL.createObjectURL(blob)
open(url)
}

doit(action: "save" | "copy" | "open" = "save"): void {
switch (action) {
case "save": {
const filename = this.model.filename ?? prompt("Enter filename", "bokeh_plot")
Expand All @@ -34,6 +44,10 @@ export class SaveToolView extends ActionToolView {
void this.copy()
break
}
case "open": {
void this.open()
break
}
}
}
}
Expand Down Expand Up @@ -67,18 +81,25 @@ export class SaveTool extends ActionTool {
}

override tool_name = "Save"
override tool_icon = tool_icon_save
override tool_icon = icons.tool_icon_save

override get menu(): MenuItem[] | null {
return [
{
icon: "bk-tool-icon-copy",
icon: icons.tool_icon_copy,
tooltip: "Copy image to clipboard",
if: () => typeof ClipboardItem !== "undefined",
handler: () => {
this.do.emit("copy")
},
},
{
icon: icons.tool_icon_open,
tooltip: "Open image in a new tab",
handler: () => {
this.do.emit("open")
},
},
]
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/bokeh/source/docs/releases/3.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
Bokeh version ``3.6.0`` (??? 2024) is a minor milestone of Bokeh project.

* Improved streaming corner cases and added NumPy to ``bokeh info`` (:bokeh-pull:`14007`)
* Added support for "open in a new tab" mode to ``SaveTool`` (:bokeh-pull:`14031`)

0 comments on commit 2bfef99

Please sign in to comment.