Skip to content

Commit

Permalink
Added dialog window object and improve nvpmodel page
Browse files Browse the repository at this point in the history
  • Loading branch information
rbonghi committed Dec 17, 2024
1 parent 11de977 commit bdfdfb2
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 33 deletions.
46 changes: 17 additions & 29 deletions jtop/gui/jtopgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
# In according with: https://gist.github.com/alanjcastonguay/25e4db0edd3534ab732d6ff615ca9fc1
ABC = abc.ABCMeta('ABC', (object,), {})
# Gui refresh rate
GUI_REFRESH = 1000 // 20
GUI_REFRESH = 20 # 1000 // 20
# Copyright small
COPYRIGHT_SMALL_RE = re.compile(r""".*__cr__ = ["'](.*?)['"]""", re.S)

Expand All @@ -44,6 +44,7 @@ def __init__(self, name, stdscr, jetson):
self.name = name
self.stdscr = stdscr
self.jetson = jetson
self.dialog_window = None

def setcontroller(self, controller):
self.controller = controller
Expand All @@ -57,6 +58,9 @@ def size_page(self):
first = 1
return height, width, first

def register_dialog_window(self, dialog_window_object):
self.dialog_window = dialog_window_object

@abc.abstractmethod
@check_curses
def draw(self, key, mouse):
Expand Down Expand Up @@ -125,42 +129,28 @@ def run(self, loop, seconds):
old = datetime.now()
# Here is the loop of our program, we keep clearing and redrawing in this loop
while not self.events() and self.jetson.ok(spin=True):
# Get page selected
page = self.pages[self.n_page]
# Check if dialog window is open and disable mouse event on main pages
record_mouse = self.mouse
if page.dialog_window and page.dialog_window.enable_dialog_window:
self.mouse = ()
# Draw pages
self.draw()
self.draw(page)
self.mouse = record_mouse
# Draw dialog window if it exists
if page.dialog_window:
page.dialog_window.show(self.stdscr, self.key, self.mouse)
# Increase page automatically if loop enabled
if loop and datetime.now() - old >= timedelta(seconds=seconds):
self.increase(loop=True)
old = datetime.now()

def dialog_window(self):
height, width = self.stdscr.getmaxyx()

dialog_height, dialog_width = 10, 46
dialog_y, dialog_x = (height - dialog_height) // 2, (width - dialog_width) // 2
dialog_win = curses.newwin(dialog_height, dialog_width, dialog_y, dialog_x)
# Add a border around the window
dialog_win.border()

# Add text to the dialog window
dialog_win.addstr(1, 2, "System reboot is required to apply changes", curses.A_BOLD)
dialog_win.addstr(3, 1, "1. Option 1")
dialog_win.addstr(4, 1, "2. Option 2")
dialog_win.addstr(5, 1, "3. Option 3")
dialog_win.addstr(7, 1, "Press 'q' to exit")

# Refresh the window to show the changes

dialog_win.refresh()

dialog_win.timeout(GUI_REFRESH * 2)

def draw(self):
def draw(self, page):
# First, clear the screen
self.stdscr.erase()
# Write head of the jtop
self.header()
# Get page selected
page = self.pages[self.n_page]
# Draw the page
page.draw(self.key, self.mouse)
# Draw menu
Expand All @@ -169,8 +159,6 @@ def draw(self):
self.stdscr.refresh()
# Set a timeout and read keystroke
self.stdscr.timeout(GUI_REFRESH)

self.dialog_window()

def increase(self, loop=False):
# check reset
Expand Down
71 changes: 71 additions & 0 deletions jtop/gui/lib/dialog_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- coding: UTF-8 -*-
# This file is part of the jetson_stats package (https://github.com/rbonghi/jetson_stats or http://rnext.it).
# Copyright (c) 2019-2023 Raffaello Bonghi.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import curses
from .smallbutton import SmallButton, ButtonList
# Gui refresh rate
GUI_REFRESH = 1000 // 20


class DialogWindow(object):
def __init__(self, title, text, on_click, buttons, width=44, height=6):
self.dialog_width = width
self.dialog_height = height
self.title = title
self.text = text
self.on_click = on_click
self.buttons = buttons
self.enable_dialog_window = False
self._dialog_win = None
self.info = {}

def enable(self, title="", info={}):
if title:
self.title = title
self.info = info
self.enable_dialog_window = True

def disable(self):
self.enable_dialog_window = False

def show(self, stdscr, key, mouse):
if self.enable_dialog_window:
self._draw(stdscr, key, mouse)

def _draw(self, stdscr, key, mouse):
# Refresh the window to show the changes
height, width = stdscr.getmaxyx()
dialog_y, dialog_x = (height - self.dialog_height) // 2, (width - self.dialog_width) // 2
self._dialog_win = curses.newwin(self.dialog_height, self.dialog_width, dialog_y, dialog_x)
# Create a list of buttons
self._buttons_profile = ButtonList(self._dialog_win, self._on_click, self.buttons, info=self.info, linear=True)
# Add a border around the window
self._dialog_win.border()
# Add the title and the text
self._dialog_win.addstr(1, 2, self.title, curses.A_BOLD)
self._dialog_win.addstr(2, 2, self.text)
# Add the buttons
align_mouse = (mouse[0] - dialog_x, mouse[1] - dialog_y) if mouse else ()
self._buttons_profile.update(4, 2, key, align_mouse, "")
# Refresh the window to show the changes
self._dialog_win.refresh()
self._dialog_win.timeout(GUI_REFRESH)

def _on_click(self, info, selected):
self.on_click(info, selected)
self.enable_dialog_window = False
# EOF
10 changes: 8 additions & 2 deletions jtop/gui/lib/smallbutton.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@ def update(self, y, x, label='', key=None, mouse=None, color=None):


class ButtonList:
def __init__(self, stdscr, on_click, buttons=[], info={}):
def __init__(self, stdscr, on_click, buttons=[], info={}, linear=False):
self.buttons = []
self.on_click = on_click
self.stdscr = stdscr
self.info = info
self._selected = ''
self.linear = linear
# Load all buttons
for button in buttons:
self.add_button(button)
Expand All @@ -133,8 +134,13 @@ def update(self, y, x, key, mouse, selected_button, colors=[]):
if not colors:
colors = [None] * len(self.buttons)
# Show all buttons
counter_space = 0
for i, (button, color) in enumerate(zip(self.buttons, colors)):
name = button.get_label()
button.set_selected(self._selected == name)
button.update(y + i, x, key=key, mouse=mouse, color=color)
if self.linear:
button.update(y, x + counter_space, key=key, mouse=mouse, color=color)
counter_space += len(name) + 3
else:
button.update(y + i, x, key=key, mouse=mouse, color=color)
# EOF
21 changes: 19 additions & 2 deletions jtop/gui/pcontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from .lib.colors import NColors
from .lib.chart import Chart
from .lib.smallbutton import SmallButton, ButtonList
from .lib.dialog_window import DialogWindow

FAN_STEP = 10
PROFILE_STR = "Profiles:"
Expand Down Expand Up @@ -139,6 +140,12 @@ def __init__(self, stdscr, jetson):
self._nvpmodel_profile = ButtonList(stdscr, self.action_nvpmodels, self.jetson.nvpmodel.models)
self._nvpmodel_increase = SmallButton(stdscr, self.action_nvp_increase, trigger_key='+')
self._nvpmodel_decrease = SmallButton(stdscr, self.action_nvp_decrease, trigger_key='-')
# Initialize dialog window
self._dialog_window = DialogWindow("NVP Model",
"Required a reboot to apply this change",
self.dialog_window_nvpmodel,
["Force and reboot", "Force", "Skip"])
self.register_dialog_window(self._dialog_window)

def action_fan_profile(self, info, selected):
# Set new fan profile
Expand Down Expand Up @@ -172,7 +179,17 @@ def action_jetson_clocks_boot(self, info, selected):

def action_nvpmodels(self, info, selected):
# Set new nvpmodel
self.jetson.nvpmodel = info['label']
model_index = self.jetson.nvpmodel.models.index(info['label'])
if not self.jetson.nvpmodel.status[model_index]:
self._dialog_window.enable("NVP model {model_name}".format(model_name=info['label']), info={'name': info['label']})
else:
self.jetson.nvpmodel = info['label']

def dialog_window_nvpmodel(self, info, selected):
if info['label'] == "Force and reboot":
self.jetson.nvpmodel.set_nvpmodel_name(info['name'], force=True, reboot=True)
elif info['label'] == "Force":
self.jetson.nvpmodel.set_nvpmodel_name(info['name'], force=True)

def action_nvp_increase(self, info, selected):
# NVPmodel controller
Expand All @@ -195,7 +212,7 @@ def update_chart(self, jetson, name):
return {
'value': [speed],
}

def control_jetson_clocks(self, pos_y, pos_x, key, mouse):
# Show jetson_clocks
try:
Expand Down

0 comments on commit bdfdfb2

Please sign in to comment.