...
 
Commits (1)
...@@ -36,6 +36,14 @@ along with gwe. If not, see <http://www.gnu.org/licenses/>. ...@@ -36,6 +36,14 @@ along with gwe. If not, see <http://www.gnu.org/licenses/>.
<column type="gchararray"/> <column type="gchararray"/>
</columns> </columns>
</object> </object>
<object class="GtkListStore" id="gpu_liststore">
<columns>
<!-- column-name id -->
<column type="gint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkMenu" id="main_menu"> <object class="GtkMenu" id="main_menu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
...@@ -126,18 +134,23 @@ along with gwe. If not, see <http://www.gnu.org/licenses/>. ...@@ -126,18 +134,23 @@ along with gwe. If not, see <http://www.gnu.org/licenses/>.
<property name="has_subtitle">False</property> <property name="has_subtitle">False</property>
<property name="show_close_button">True</property> <property name="show_close_button">True</property>
<child> <child>
<object class="GtkButton" id="historical_data_button"> <object class="GtkComboBox" id="gpu_combobox">
<property name="label" translatable="yes">Historical data</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="sensitive">False</property>
<property name="receives_default">True</property> <property name="can_focus">False</property>
<signal name="clicked" handler="on_historical_data_button_clicked" swapped="no"/> <property name="hexpand">False</property>
<style> <property name="model">gpu_liststore</property>
<class name="suggested-action"/> <property name="id_column">0</property>
</style> <signal name="changed" handler="on_gpu_selected" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="gpu_renderer"/>
<attributes>
<attribute name="markup">1</attribute>
</attributes>
</child>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
...@@ -157,7 +170,21 @@ along with gwe. If not, see <http://www.gnu.org/licenses/>. ...@@ -157,7 +170,21 @@ along with gwe. If not, see <http://www.gnu.org/licenses/>.
</object> </object>
<packing> <packing>
<property name="pack_type">end</property> <property name="pack_type">end</property>
<property name="position">1</property> </packing>
</child>
<child>
<object class="GtkButton" id="historical_data_button">
<property name="label" translatable="yes">Historical data</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_historical_data_button_clicked" swapped="no"/>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing> </packing>
</child> </child>
</object> </object>
......
...@@ -49,6 +49,9 @@ class MainViewInterface: ...@@ -49,6 +49,9 @@ class MainViewInterface:
def refresh_status(self, status: Optional[Status], gpu_index: int) -> None: def refresh_status(self, status: Optional[Status], gpu_index: int) -> None:
raise NotImplementedError() raise NotImplementedError()
def refresh_gpu_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None:
raise NotImplementedError()
def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None: def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None:
raise NotImplementedError() raise NotImplementedError()
...@@ -127,7 +130,7 @@ class MainPresenter: ...@@ -127,7 +130,7 @@ class MainPresenter:
self._gpu_index: int = 0 self._gpu_index: int = 0
def on_start(self) -> None: def on_start(self) -> None:
self._refresh_fan_profile_ui(True) self._refresh_fan_profile_selector(True)
self._register_db_listeners() self._register_db_listeners()
self._start_refresh() self._start_refresh()
self._check_new_version() self._check_new_version()
...@@ -155,7 +158,7 @@ class MainPresenter: ...@@ -155,7 +158,7 @@ class MainPresenter:
self._fan_profile_applied = self._fan_profile_selected self._fan_profile_applied = self._fan_profile_selected
if self._fan_profile_selected.type == FanProfileType.AUTO.value: if self._fan_profile_selected.type == FanProfileType.AUTO.value:
self._set_fan_speed(self._gpu_index, manual_control=False) self._set_fan_speed(self._gpu_index, manual_control=False)
self._refresh_fan_profile_ui(profile_id=self._fan_profile_selected.id) self._refresh_fan_profile_selector(profile_id=self._fan_profile_selected.id)
self._update_current_fan_profile(self._fan_profile_selected) self._update_current_fan_profile(self._fan_profile_selected)
def on_overclock_edit_button_clicked(self, *_: Any) -> None: def on_overclock_edit_button_clicked(self, *_: Any) -> None:
...@@ -170,7 +173,7 @@ class MainPresenter: ...@@ -170,7 +173,7 @@ class MainPresenter:
def on_overclock_apply_button_clicked(self, *_: Any) -> None: def on_overclock_apply_button_clicked(self, *_: Any) -> None:
if self._overclock_profile_selected: if self._overclock_profile_selected:
self._overclock_profile_applied = self._overclock_profile_selected self._overclock_profile_applied = self._overclock_profile_selected
self._refresh_overclock_profile_ui(profile_id=self._overclock_profile_selected.id) self._refresh_overclock_profile_selector(profile_id=self._overclock_profile_selected.id)
assert self._latest_status is not None assert self._latest_status is not None
self._composite_disposable.add(self._set_overclock_interactor.execute( self._composite_disposable.add(self._set_overclock_interactor.execute(
self._gpu_index, self._gpu_index,
...@@ -192,6 +195,15 @@ class MainPresenter: ...@@ -192,6 +195,15 @@ class MainPresenter:
def on_menu_about_clicked(self, *_: Any) -> None: def on_menu_about_clicked(self, *_: Any) -> None:
self.main_view.show_about_dialog() self.main_view.show_about_dialog()
def on_gpu_selected(self, widget: Any, *_: Any) -> None:
active = widget.get_active()
if active >= 0:
index = widget.get_model()[active][0]
if self._gpu_index != index:
self._gpu_index = index
self._refresh_gpu_selector(self._latest_status)
self._on_status_updated(self._latest_status)
def on_fan_profile_selected(self, widget: Any, *_: Any) -> None: def on_fan_profile_selected(self, widget: Any, *_: Any) -> None:
active = widget.get_active() active = widget.get_active()
if active >= 0: if active >= 0:
...@@ -228,20 +240,20 @@ class MainPresenter: ...@@ -228,20 +240,20 @@ class MainPresenter:
def _on_fan_profile_list_changed(self, db_change: DbChange) -> None: def _on_fan_profile_list_changed(self, db_change: DbChange) -> None:
profile = db_change.entry profile = db_change.entry
if db_change.type == DbChange.DELETE: if db_change.type == DbChange.DELETE:
self._refresh_fan_profile_ui() self._refresh_fan_profile_selector()
self._fan_profile_selected = None self._fan_profile_selected = None
self._fan_profile_applied = None self._fan_profile_applied = None
elif db_change.type == DbChange.INSERT or db_change.type == DbChange.UPDATE: elif db_change.type == DbChange.INSERT or db_change.type == DbChange.UPDATE:
self._refresh_fan_profile_ui(profile_id=profile.id) self._refresh_fan_profile_selector(profile_id=profile.id)
def _on_overclock_profile_list_changed(self, db_change: DbChange) -> None: def _on_overclock_profile_list_changed(self, db_change: DbChange) -> None:
profile = db_change.entry profile = db_change.entry
if db_change.type == DbChange.DELETE: if db_change.type == DbChange.DELETE:
self._refresh_overclock_profile_ui() self._refresh_overclock_profile_selector()
self._overclock_profile_selected = None self._overclock_profile_selected = None
self._overclock_profile_applied = None self._overclock_profile_applied = None
elif db_change.type == DbChange.INSERT or db_change.type == DbChange.UPDATE: elif db_change.type == DbChange.INSERT or db_change.type == DbChange.UPDATE:
self._refresh_overclock_profile_ui(profile_id=profile.id) self._refresh_overclock_profile_selector(profile_id=profile.id)
def _start_refresh(self) -> None: def _start_refresh(self) -> None:
LOG.debug("start refresh") LOG.debug("start refresh")
...@@ -262,7 +274,8 @@ class MainPresenter: ...@@ -262,7 +274,8 @@ class MainPresenter:
was_latest_status_none = self._latest_status is None was_latest_status_none = self._latest_status is None
self._latest_status = status self._latest_status = status
if was_latest_status_none: if was_latest_status_none:
self._refresh_overclock_profile_ui(True) self._refresh_gpu_selector(status)
self._refresh_overclock_profile_selector(True)
self._update_fan(status) self._update_fan(status)
self.main_view.refresh_status(status, self._gpu_index) self.main_view.refresh_status(status, self._gpu_index)
self._historical_data_presenter.add_status(status, self._gpu_index) self._historical_data_presenter.add_status(status, self._gpu_index)
...@@ -275,7 +288,7 @@ class MainPresenter: ...@@ -275,7 +288,7 @@ class MainPresenter:
if self._fan_profile_selected is None and not fan.manual_control: if self._fan_profile_selected is None and not fan.manual_control:
fan_profile = FanProfile.get(FanProfile.type == FanProfileType.AUTO.value) fan_profile = FanProfile.get(FanProfile.type == FanProfileType.AUTO.value)
self._fan_profile_applied = fan_profile self._fan_profile_applied = fan_profile
self._refresh_fan_profile_ui(profile_id=fan_profile.id) self._refresh_fan_profile_selector(profile_id=fan_profile.id)
elif self._fan_profile_applied and self._fan_profile_applied.type != FanProfileType.AUTO.value: elif self._fan_profile_applied and self._fan_profile_applied.type != FanProfileType.AUTO.value:
gpu_status = status.gpu_status_list[self._gpu_index] gpu_status = status.gpu_status_list[self._gpu_index]
if not self._fan_profile_applied.steps: if not self._fan_profile_applied.steps:
...@@ -301,7 +314,16 @@ class MainPresenter: ...@@ -301,7 +314,16 @@ class MainPresenter:
duty = float(p_2[1]) duty = float(p_2[1])
return duty return duty
def _refresh_fan_profile_ui(self, init: bool = False, profile_id: Optional[int] = None) -> None: def _refresh_gpu_selector(self, status: Status) -> None:
data: List[Tuple[int, str]] = []
for index, gpu_status in enumerate(status.gpu_status_list):
name = gpu_status.info.name
if self._gpu_index == index:
name = f"<b>{name}</b>"
data.append((index, name))
self.main_view.refresh_gpu_combobox(data, self._gpu_index)
def _refresh_fan_profile_selector(self, init: bool = False, profile_id: Optional[int] = None) -> None:
current: Optional[CurrentFanProfile] = None current: Optional[CurrentFanProfile] = None
if init and self._settings_interactor.get_bool('settings_load_last_profile'): if init and self._settings_interactor.get_bool('settings_load_last_profile'):
current = CurrentFanProfile.get_or_none() current = CurrentFanProfile.get_or_none()
...@@ -355,7 +377,7 @@ class MainPresenter: ...@@ -355,7 +377,7 @@ class MainPresenter:
current.save() current.save()
self.main_view.set_statusbar_text(f'{profile.name} fan profile selected') self.main_view.set_statusbar_text(f'{profile.name} fan profile selected')
def _refresh_overclock_profile_ui(self, init: bool = False, profile_id: Optional[int] = None) -> None: def _refresh_overclock_profile_selector(self, init: bool = False, profile_id: Optional[int] = None) -> None:
current: Optional[CurrentOverclockProfile] = None current: Optional[CurrentOverclockProfile] = None
assert self._latest_status is not None assert self._latest_status is not None
if init and self._settings_interactor.get_bool('settings_load_last_profile') \ if init and self._settings_interactor.get_bool('settings_load_last_profile') \
......
...@@ -60,43 +60,44 @@ class HistoricalDataView(HistoricalDataViewInterface): ...@@ -60,43 +60,44 @@ class HistoricalDataView(HistoricalDataViewInterface):
self._graph_views: Dict[GraphType, Tuple[Gtk.Label, Gtk.Label, Gtk.Label]] = {} self._graph_views: Dict[GraphType, Tuple[Gtk.Label, Gtk.Label, Gtk.Label]] = {}
self._graph_models: Dict[GraphType, Dazzle.GraphModel] = {} self._graph_models: Dict[GraphType, Dazzle.GraphModel] = {}
for graph_type in GraphType: for graph_type in GraphType:
self._graph_container: Gtk.Frame = self._builder.get_object(f'graph_container_{graph_type.value}') graph_container: Gtk.Frame = self._builder.get_object(f'graph_container_{graph_type.value}')
self._graph_views[graph_type] = (self._builder.get_object(f'graph_min_value_{graph_type.value}'), self._graph_views[graph_type] = (self._builder.get_object(f'graph_min_value_{graph_type.value}'),
self._builder.get_object(f'graph_max_value_{graph_type.value}'), self._builder.get_object(f'graph_max_value_{graph_type.value}'),
self._builder.get_object(f'graph_max_axis_{graph_type.value}')) self._builder.get_object(f'graph_max_axis_{graph_type.value}'))
graph_views = Dazzle.GraphView() graph_views = Dazzle.GraphView()
graph_model = Dazzle.GraphModel()
graph_renderer = GraphStackedRenderer()
graph_views.set_hexpand(True) graph_views.set_hexpand(True)
graph_views.props.height_request = 80 graph_views.props.height_request = 80
graph_renderer.set_line_width(1.5)
stroke_color = Gdk.RGBA() stroke_color = Gdk.RGBA()
stroke_color.parse(GRAPH_COLOR_HEX) stroke_color.parse(GRAPH_COLOR_HEX)
stacked_color = Gdk.RGBA() stacked_color = Gdk.RGBA()
stacked_color.parse(GRAPH_COLOR_HEX) stacked_color.parse(GRAPH_COLOR_HEX)
stacked_color.alpha = 0.5 stacked_color.alpha = 0.5
graph_renderer = GraphStackedRenderer()
graph_renderer.set_line_width(1.5)
graph_renderer.set_stroke_color_rgba(stroke_color) graph_renderer.set_stroke_color_rgba(stroke_color)
graph_renderer.set_stacked_color_rgba(stacked_color) graph_renderer.set_stacked_color_rgba(stacked_color)
graph_model.set_timespan(MONITORING_INTERVAL * 1000 * 1000)
graph_model.set_max_samples(MONITORING_INTERVAL / self._presenter.get_refresh_interval() + 1)
graph_model.props.value_max = 100.0
graph_model.props.value_min = 0.0
column_ram = Dazzle.GraphColumn().new("Col0", TYPE_DOUBLE)
graph_model.add_column(column_ram)
graph_views.set_model(graph_model)
graph_views.add_renderer(graph_renderer) graph_views.add_renderer(graph_renderer)
self._add_new_graph_model_to_graph_view(graph_type, graph_views)
self._graph_container.add(graph_views) graph_container.add(graph_views)
graph_model_iter = graph_model.push(GLib.get_monotonic_time()) def _add_new_graph_model_to_graph_view(self, graph_type: GraphType, graph_views: Dazzle.GraphView) -> None:
graph_model.iter_set(graph_model_iter, 0, 0.0) graph_model = Dazzle.GraphModel()
graph_model.set_timespan(MONITORING_INTERVAL * 1000 * 1000)
self._graph_models[graph_type] = graph_model graph_model.set_max_samples(MONITORING_INTERVAL / self._presenter.get_refresh_interval() + 1)
graph_model.props.value_max = 100.0
graph_model.props.value_min = 0.0
column_ram = Dazzle.GraphColumn().new("Col0", TYPE_DOUBLE)
graph_model.add_column(column_ram)
graph_views.set_model(graph_model)
graph_model_iter = graph_model.push(GLib.get_monotonic_time())
graph_model.iter_set(graph_model_iter, 0, 0.0)
self._graph_models[graph_type] = graph_model
def reset_graphs(self) -> None: def reset_graphs(self) -> None:
self._init_graphs() for graph_type in GraphType:
graph_container: Gtk.Frame = self._builder.get_object(f'graph_container_{graph_type.value}')
graph_views = graph_container.get_children()[0]
self._add_new_graph_model_to_graph_view(graph_type, graph_views)
def refresh_graphs(self, data_dict: Dict[GraphType, Tuple[int, float, str, float, float]]) -> None: def refresh_graphs(self, data_dict: Dict[GraphType, Tuple[int, float, str, float, float]]) -> None:
time1 = time.time() time1 = time.time()
......
...@@ -149,8 +149,10 @@ class MainView(MainViewInterface): ...@@ -149,8 +149,10 @@ class MainView(MainViewInterface):
self._fan_apply_button: Gtk.Button = self._builder.get_object('fan_apply_button') self._fan_apply_button: Gtk.Button = self._builder.get_object('fan_apply_button')
self._overclock_apply_button: Gtk.Button = self._builder.get_object('overclock_apply_button') self._overclock_apply_button: Gtk.Button = self._builder.get_object('overclock_apply_button')
self._power_limit_apply_button: Gtk.Button = self._builder.get_object('power_limit_apply_button') self._power_limit_apply_button: Gtk.Button = self._builder.get_object('power_limit_apply_button')
self._gpu_liststore: Gtk.ListStore = self._builder.get_object('gpu_liststore')
self._fan_liststore: Gtk.ListStore = self._builder.get_object('fan_profile_liststore') self._fan_liststore: Gtk.ListStore = self._builder.get_object('fan_profile_liststore')
self._overclock_liststore: Gtk.ListStore = self._builder.get_object('overclock_profile_liststore') self._overclock_liststore: Gtk.ListStore = self._builder.get_object('overclock_profile_liststore')
self._gpu_combobox: Gtk.ComboBox = self._builder.get_object('gpu_combobox')
self._fan_combobox: Gtk.ComboBox = self._builder.get_object('fan_profile_combobox') self._fan_combobox: Gtk.ComboBox = self._builder.get_object('fan_profile_combobox')
self._overclock_combobox: Gtk.ComboBox = self._builder.get_object('overclock_profile_combobox') self._overclock_combobox: Gtk.ComboBox = self._builder.get_object('overclock_profile_combobox')
fan_scrolled_window: Gtk.ScrolledWindow = self._builder.get_object('fan_scrolled_window') fan_scrolled_window: Gtk.ScrolledWindow = self._builder.get_object('fan_scrolled_window')
...@@ -349,6 +351,16 @@ class MainView(MainViewInterface): ...@@ -349,6 +351,16 @@ class MainView(MainViewInterface):
else: else:
self._plot_chart(get_fan_profile_data(profile)) self._plot_chart(get_fan_profile_data(profile))
def refresh_gpu_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None:
self._gpu_liststore.clear()
self._first_refresh = True
for item in data:
self._gpu_liststore.append([item[0], item[1]])
self._gpu_combobox.set_model(self._gpu_liststore)
self._gpu_combobox.set_sensitive(len(self._gpu_liststore) > 1)
if active is not None:
self._gpu_combobox.set_active(active)
def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None: def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None:
self._fan_liststore.clear() self._fan_liststore.clear()
for item in data: for item in data:
......