Coverage for src/plotly_gtk/widgets/updatemenus.py: 16%
67 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-08 21:22 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-08 21:22 +0000
1import gi
3gi.require_version("Gdk", "4.0")
4gi.require_version("Gtk", "4.0")
5from typing import TYPE_CHECKING
7import numpy as np
8from gi.repository import Gdk, Gtk # noqa: E402
10from plotly_gtk.utils import update_dict
11from plotly_gtk.widgets.base import Base
13if TYPE_CHECKING:
14 from plotly_gtk.chart import PlotlyGtk
17class UpdateMenu(Base):
18 def __init__(self, plot: "PlotlyGtk", _updatemenu: dict):
19 super().__init__()
20 default = dict(
21 active=0,
22 bgcolor="transparent",
23 bordercolor="#BEC8D9",
24 borderwidth=1,
25 direction="down",
26 font=plot.layout["font"],
27 showactive=True,
28 type="dropdown",
29 x=-0.05,
30 xanchor="right",
31 y=1,
32 yanchor="top",
33 )
34 updatemenu = update_dict(default, _updatemenu)
35 self.spec = updatemenu
37 if updatemenu["direction"] in ["up", "down"]:
38 self.set_orientation(Gtk.Orientation.VERTICAL)
40 buttons = updatemenu["buttons"]
42 font = updatemenu["font"]
43 custom_css = Gtk.CssProvider()
44 custom_css.load_from_string(
45 f"""
46 .plotly-button button {
47 background-color: {updatemenu["bgcolor"]};
48 border: {updatemenu["borderwidth"]}px solid {updatemenu["bordercolor"]};
49 box-shadow: none;
50 }
51 .plotly-button label {
52 color: {updatemenu["font"]["color"]};
53 font-family: {font["family"]};
54 font-size: {font["size"]}px;
55 font-style: {font["style"]};
56 font-variant: {font["variant"]};
57 font-weight: {font["weight"]};
58 }
59 """
60 )
61 Gtk.StyleContext().add_provider_for_display(
62 Gdk.Display().get_default(),
63 custom_css,
64 Gtk.STYLE_PROVIDER_PRIORITY_USER,
65 )
67 self.add_css_class("plotly-button")
69 def on_button_selected(button):
70 args = button.button["args"]
71 if button.button["method"] == "update":
72 for arg in args:
73 plot.layout.update(arg)
74 for k, v in arg.items():
75 if isinstance(v, list | np.ndarray) and len(v) == len(
76 plot.data
77 ):
78 for trace, val in zip(plot.data, v):
79 trace[k] = val
80 _updatemenu["active"] = buttons.index(button.button)
81 plot.update(dict(data=plot.data, layout=plot.layout))
83 if updatemenu["type"] == "dropdown":
84 _buttons = []
86 def top_button_clicked(button):
87 if button == top_button:
88 top_button.open = not top_button.open
89 for _button in _buttons:
90 _button.set_visible(button == top_button and top_button.open)
92 top_button = Gtk.Button(label=buttons[updatemenu["active"]]["label"])
93 top_button.get_child().set_halign(Gtk.Align.START)
94 top_button.open = False
95 top_button.connect("clicked", top_button_clicked)
96 self.append(top_button)
98 width = 0
100 for button in buttons:
101 _button = Gtk.Button(label=button["label"], visible=True)
102 _buttons.append(_button)
103 _button.get_child().set_halign(Gtk.Align.START)
104 _button.button = button
105 _button.connect("clicked", on_button_selected)
106 _button.connect("clicked", top_button_clicked)
107 width = max(
108 width,
109 _button.measure(Gtk.Orientation.HORIZONTAL, -1)[0],
110 )
111 _button.set_visible(False)
112 self.append(_button)
113 top_button.set_size_request(width, -1)
115 elif updatemenu["type"] == "buttons":
116 for button in buttons:
117 _button = Gtk.Button(label=button["label"])
118 _button.get_child().set_halign(Gtk.Align.START)
119 _button.button = button
120 _button.connect("clicked", on_button_selected)
121 self.append(_button)
122 else:
123 raise ValueError(f"Unknown updatemenu.type: {updatemenu["type"]}")