Skip to content

Commit

Permalink
Merge pull request #245 from nxt-dev/dev
Browse files Browse the repository at this point in the history
Release editor-v3.12.0
  • Loading branch information
ImLucasBrown authored Apr 9, 2022
2 parents ea419c2 + ab1f73c commit 2a52afd
Show file tree
Hide file tree
Showing 19 changed files with 660 additions and 259 deletions.
19 changes: 3 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,10 @@ branches:
python:
- "3.7"

services:
- xvfb

env:
- QT_CI_PACKAGES=qt.qt5.5132.gcc_64,qt.qt5.5132.qtwebengine PATH="$TRAVIS_BUILD_DIR/Qt/5.13.2/gcc_64/bin:${PATH}"

before_install:
- |
if [ "$TRAVIS_BRANCH" = "dev" ] && [ "$TRAVIS_EVENT_TYPE" = "push" ]; then
echo "Push to dev, not running tests until PR"
echo "Push to dev, not running until push to release"
exit 0
else
echo "Doing the build"
Expand All @@ -24,20 +18,13 @@ before_install:
install:
- cd ..
- git clone https://github.com/nxt-dev/nxt.git
- pip install ./nxt_editor
- pip install importlib-metadata==3.4
- pip install twine
- sudo apt-get install -y libxkbcommon-x11-0
- sudo apt-get install -y libgl1-mesa-dev
- pip install ./nxt_editor

script:
- |
if [ "$TRAVIS_BRANCH" = "release" ] && [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
python -m nxt.cli test
exit $?
fi
- |
if [ "$TRAVIS_BRANCH" = "release" ] && [ "$TRAVIS_EVENT_TYPE" = "push" ]; then
pip install twine
python -m nxt.cli exec nxt_editor/build/packaging.nxt -s /make_and_upload
exit $?
fi
33 changes: 24 additions & 9 deletions nxt_editor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class StringSignaler(QtCore.QObject):
def make_resources(qrc_path=None, result_path=None):
import PySide2
pyside_dir = os.path.dirname(PySide2.__file__)
full_rcc_path = os.path.join(pyside_dir, 'pyside2-rcc')
full_pyside2rcc_path = os.path.join(pyside_dir, 'pyside2-rcc')
full_rcc_path = os.path.join(pyside_dir, 'rcc')
this_dir = os.path.dirname(os.path.realpath(__file__))
if not qrc_path:
qrc_path = os.path.join(this_dir, 'resources/resources.qrc')
Expand All @@ -59,17 +60,26 @@ def make_resources(qrc_path=None, result_path=None):
return

try:
subprocess.check_call([full_rcc_path] + args)
subprocess.check_call([full_pyside2rcc_path] + args)
except:
pass
else:
return
try:
subprocess.check_call([full_rcc_path, '-g', 'python', qrc_path,
'-o', result_path], cwd=pyside_dir)
except:
pass
else:
return

try:
subprocess.check_call(['rcc', '-g', 'python', qrc_path, result_path])
subprocess.check_call(['rcc', '-g', 'python', qrc_path,
'-o', result_path], cwd=pyside_dir)
except:
raise Exception("Cannot find pyside2 rcc to generate UI resources."
" Reinstalling pyside2 may fix the problem.")
raise Exception("Failed to generate UI resources using pyside2 rcc!"
" Reinstalling pyside2 may fix the problem. If you "
"know how to use rcc please build from: \"{}\" and "
"output to \"{}\"".format(qrc_path, result_path))
else:
return

Expand All @@ -82,11 +92,16 @@ def make_resources(qrc_path=None, result_path=None):


def _new_qapp():
app = QtWidgets.QApplication
app = QtWidgets.QApplication.instance()
create_new = False
if not app:
app = QtWidgets.QApplication
app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
create_new = True
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
app.setEffectEnabled(QtCore.Qt.UI_AnimateCombo, False)
app = app(sys.argv)
if create_new:
app = app(sys.argv)
style_file = QtCore.QFile(':styles/styles/dark/dark.qss')
style_file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text)
stream = QtCore.QTextStream(style_file)
Expand Down
65 changes: 61 additions & 4 deletions nxt_editor/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,26 @@ def handle_model_change(self):


class BoolUserPrefAction(NxtAction):
"""NxtAction that saves state between sessions via preference key."""
def __init__(self, text, pref_key, default=False, parent=None):
"""NxtAction that saves state between sessions via preference key
Note that default checked state is set during initialization, before
signals have been hooked up. Meaning any later-connected function is not
automatically called to "kick start" the application state. Either
build that into the start of the UI, or call your action once manually
to kick start.
:param text: Action description.
:type text: str
:param pref_key: Preference key to save at
:type pref_key: str
:param default: Deafult value, loads default state from user pref, only
falling back to this default when no save exists, defaults to False
:type default: bool, optional
:param parent: Action parent, defaults to None
:type parent: QObject, optional
"""
super(BoolUserPrefAction, self).__init__(text, parent)
self.setCheckable(True)
self.pref_key = pref_key
Expand Down Expand Up @@ -1167,13 +1186,13 @@ def toggle_grid():
state = self.grid_action.isChecked()
self.main_window.view.toggle_grid(state)

self.grid_action = NxtAction(text='Toggle Grid',
parent=self)
self.grid_action = BoolUserPrefAction('Toggle Grid',
user_dir.USER_PREF.SHOW_GRID,
default=True,
parent=self)
self.grid_action.setShortcut('Ctrl+;')
self.grid_action.setToolTip('Show / Hide the Grid')
self.grid_action.setWhatsThis('Shows or hides the grid for all tabs.')
self.grid_action.setCheckable(True)
self.grid_action.setChecked(True)
self.grid_action.triggered.connect(toggle_grid)
grid_icon = QtGui.QIcon()
grid_icn_on = QtGui.QPixmap(':icons/icons/grid_pressed.png')
Expand Down Expand Up @@ -1585,6 +1604,44 @@ def toggle_breakpoints():
self.run_build_action.setWhatsThis('Runs build specified by the '
'current value of build view.')

self.toggle_skip_action = NxtAction(text='Toggle Skippoint',
parent=self)
self.toggle_skip_action.setWhatsThis('Toggle skippoint on the selected'
'node(s)')
self.toggle_skip_action.setAutoRepeat(False)
self.toggle_skip_action.setShortcut('X')

def toggle_skip():
node_paths = self.toggle_skip_action.data()
self.toggle_skip_action.setData(None)
if not node_paths:
node_paths = self.main_window.model.get_selected_nodes()
if not node_paths:
logger.info("No nodes to toggle skip on.")
return
layer = self.main_window.model.top_layer.real_path
self.main_window.model.toggle_skippoints(node_paths, layer)
self.toggle_skip_action.triggered.connect(toggle_skip)

self.set_descendent_skips = NxtAction('Toggle Skip with Descendants',
parent=self)
self.set_descendent_skips.setWhatsThis('Toggles skip of the selected '
'node(s), applying the '
'skip state to all descendents')
self.set_descendent_skips.setAutoRepeat(False)
self.set_descendent_skips.setShortcut('Shift+X')

def toggle_descendant_skips():
node_paths = self.set_descendent_skips.data()
self.set_descendent_skips.setData(None)
if not node_paths:
node_paths = self.main_window.model.get_selected_nodes()
if not node_paths:
logger.info("No nodes to toggle skip on.")
return
self.main_window.model.toggle_descendant_skips(node_paths)
self.set_descendent_skips.triggered.connect(toggle_descendant_skips)

def stop():
self.main_window.model.stop_build()
self.stop_exec_action = NxtAction(text='Stop Execution', parent=self)
Expand Down
5 changes: 5 additions & 0 deletions nxt_editor/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
'dict': QColor('#984dab'),
}

GRAPH_BG_COLOR = QColor(35, 35, 35)
START_COLOR = QColor("#1bd40b")
SKIP_COLOR = QColor("#f0880a")
BREAK_COLOR = QColor(255, 0, 0)

LAYER_COLORS = [
QColor('#991C24'), # dark red
QColor('#C91781'), # fuschia
Expand Down
39 changes: 39 additions & 0 deletions nxt_editor/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,45 @@ def redo(self):
self.setText("Set {} exec input to {}".format(self.node_path, val))


class SetNodesAreSkipPoints(QUndoCommand):

"""Set nodes as skip points"""

def __init__(self, node_paths, to_skip, layer_path, model):
super(SetNodesAreSkipPoints, self).__init__()
self.node_paths = node_paths
self.to_skip = to_skip
self.model = model
self.layer_path = layer_path

@processing
def redo(self):
if self.to_skip:
func = self.model._add_skippoint
else:
func = self.model._remove_skippoint
for node_path in self.node_paths:
func(node_path, self.layer_path)
self.model.nodes_changed.emit(tuple(self.node_paths))
if len(self.node_paths) == 1:
path_str = self.node_paths[0]
else:
path_str = "Multiple nodes"
if self.to_skip:
self.setText("Add skippoint to {}".format(path_str))
else:
self.setText("Remove skippoint from {}".format(path_str))

@processing
def undo(self):
if not self.to_skip:
func = self.model._add_skippoint
else:
func = self.model._remove_skippoint
for node_path in self.node_paths:
func(node_path, self.layer_path)


class SetNodeBreakPoint(QUndoCommand):

"""Set node as a break point"""
Expand Down
55 changes: 40 additions & 15 deletions nxt_editor/dockwidgets/build_view.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Builtin
import logging
import time
from turtle import color

# External
from Qt import QtWidgets, QtGui, QtCore
Expand All @@ -10,6 +11,7 @@
from nxt import nxt_path
from nxt_editor.dockwidgets.layer_manager import LetterCheckboxDelegeate
import nxt_editor
from nxt_editor import colors

logger = logging.getLogger(nxt_editor.LOGGER_NAME)

Expand Down Expand Up @@ -320,7 +322,11 @@ def __init__(self):
self.break_delegate = LetterCheckboxDelegeate('B')
self.setItemDelegateForColumn(BuildModel.BREAK_COLUMN,
self.break_delegate)
self.skip_delegate = LetterCheckboxDelegeate('S')
self.setItemDelegateForColumn(BuildModel.SKIP_COLUMN,
self.skip_delegate)
self.clicked.connect(self.on_row_clicked)
# TODO context menu and shift-click for +descendents.

def on_row_clicked(self, clicked_idx):
"""When a row in the table is clicked, select and frame.
Expand Down Expand Up @@ -349,7 +355,7 @@ def setModel(self, model):

def on_build_idx_changed(self, build_idx):
if self.model().stage_model.can_build_run():
model_index = self.model().index(build_idx + 1, 0)
model_index = self.model().index(build_idx, 0)
else:
model_index = self.model().index(0, 0)
self.scrollTo(model_index, self.ScrollHint.PositionAtCenter)
Expand All @@ -359,19 +365,21 @@ class BuildModel(QtCore.QAbstractTableModel):
"""A model of a series of nodes that reflects execution information
including break status, start status, and which node is next to be run.
"""
BREAK_COLUMN = 0
START_COLUMN = 1
PATH_COLUMN = 2
NEXT_RUN_COLUMN = 3
SKIP_COLUMN = 0
BREAK_COLUMN = 1
START_COLUMN = 2
PATH_COLUMN = 3
NEXT_RUN_COLUMN = 4

def __init__(self, stage_model):
super(BuildModel, self).__init__()
"""self._nodes is the execute order this build model with reflect
answers about.
"""
self.headers = ['Break', 'Start', 'Path', 'Next']
self.headers = ['Skip', 'Break', 'Start', 'Path', 'Next']
self.stage_model = stage_model
self._nodes = []
self.stage_model.skips_changed.connect(self.on_skips_changed)
self.stage_model.breaks_changed.connect(self.on_breaks_changed)
self.stage_model.build_idx_changed.connect(self.on_build_idx_changed)

Expand All @@ -389,6 +397,11 @@ def nodes(self, val):
self._nodes = val
self.endResetModel()

def on_skips_changed(self, new_skips):
last_row = len(self.nodes) - 1
self.dataChanged.emit(self.index(0, self.SKIP_COLUMN),
self.index(last_row, self.SKIP_COLUMN))

def on_breaks_changed(self, new_breaks):
last_row = len(self.nodes) - 1
self.dataChanged.emit(self.index(0, self.BREAK_COLUMN),
Expand All @@ -412,7 +425,7 @@ def rowCount(self, index):
return len(self.nodes)

def columnCount(self, index):
return 4
return len(self.headers)

def data(self, index, role=None):
row = index.row()
Expand All @@ -423,23 +436,28 @@ def data(self, index, role=None):
return idx_path
next_run = False
if self.stage_model.is_build_setup():
next_run = row == self.stage_model.last_built_idx + 1
next_run = row == self.stage_model.last_built_idx
elif row == 0:
next_run = True
is_start = self.stage_model.get_is_node_start(idx_path)
is_break = self.stage_model.get_is_node_breakpoint(idx_path)
is_skip = self.stage_model.is_node_skippoint(idx_path)
if role == QtCore.Qt.CheckStateRole:
if column == self.START_COLUMN:
return QtCore.Qt.Checked if is_start else QtCore.Qt.Unchecked
if column == self.BREAK_COLUMN:
return QtCore.Qt.Checked if is_break else QtCore.Qt.Unchecked
if column == self.SKIP_COLUMN:
return QtCore.Qt.Checked if is_skip else QtCore.Qt.Unchecked
if column == self.NEXT_RUN_COLUMN:
return QtCore.Qt.Checked if next_run else QtCore.Qt.Unchecked
if role == QtCore.Qt.BackgroundRole:
if column == self.BREAK_COLUMN and is_break:
return QtGui.QBrush(QtCore.Qt.red)
return colors.BREAK_COLOR
if column == self.SKIP_COLUMN and is_skip:
return colors.SKIP_COLOR
if column == self.START_COLUMN and is_start:
return QtGui.QBrush(QtCore.Qt.green)
return colors.START_COLOR
if column == self.PATH_COLUMN and next_run:
return QtGui.QBrush(QtCore.Qt.red)
if role == QtCore.Qt.ForegroundRole:
Expand All @@ -448,11 +466,18 @@ def data(self, index, role=None):

def setData(self, index, value, role=QtCore.Qt.EditRole):
column = index.column()
if column != self.BREAK_COLUMN:
return False
if role != QtCore.Qt.CheckStateRole:
return False
path = self.nodes[index.row()]
current_break = self.stage_model.get_is_node_breakpoint(path)
self.stage_model.set_breakpoints([path], not current_break)
return True
if column == self.BREAK_COLUMN:
current_break = self.stage_model.get_is_node_breakpoint(path)
self.stage_model.set_breakpoints([path], not current_break)
return True
if column == self.SKIP_COLUMN:
modifiers = QtWidgets.QApplication.keyboardModifiers()
if modifiers == QtCore.Qt.ShiftModifier:
self.stage_model.toggle_descendant_skips([path])
else:
self.stage_model.toggle_skippoints([path])
return True
return False
Loading

0 comments on commit 2a52afd

Please sign in to comment.