bugfix: update sets after graph selection;

check for config on start
color cycles added;
This commit is contained in:
dominik 2022-04-16 20:41:26 +02:00
parent 4a18965580
commit dc906972e9
19 changed files with 749 additions and 201 deletions

View File

@ -4,6 +4,11 @@ import sys
import pathlib import pathlib
sys.path.append(str(pathlib.Path().cwd().parent)) sys.path.append(str(pathlib.Path().cwd().parent))
from nmreval.configs import check_for_config
# does a directory for config stuff exist? create it if not
check_for_config()
# pyqtgraph warns on Mac if QApplication is created when it is imported # pyqtgraph warns on Mac if QApplication is created when it is imported
# import pyqtgraph # import pyqtgraph

View File

@ -1,25 +1,44 @@
import configparser import configparser
import pathlib import pathlib
import pickle import pickle
import logging.handlers from shutil import copyfile
from importlib.resources import path as resource_path
__all__ = ['config_paths', 'read_configuration', 'write_configuration', 'allowed_values', 'write_state', 'read_state'] __all__ = ['config_paths', 'check_for_config', 'read_configuration', 'write_configuration', 'allowed_values', 'write_state', 'read_state']
def check_for_config(make=True):
try:
config_paths()
except FileNotFoundError as e:
if make:
conf_path = pathlib.Path('~/.auswerten').expanduser()
conf_path.mkdir(parents=True)
cwd = pathlib.Path(__file__).parent
copyfile(cwd / 'models' / 'usermodels.py', conf_path / 'usermodels.py')
with resource_path('resources', 'Default.agr') as fp:
copyfile(fp, conf_path / 'Default.agr')
else:
raise e
def config_paths() -> pathlib.Path: def config_paths() -> pathlib.Path:
# TODO adjust for different OS # TODO adjust for different OS
searchpaths = ['~/.local/share/auswerten', '~/.auswerten', '/usr/share/nmreval'] searchpaths = ['~/.config/nmreval', '~/.auswerten', '/usr/share/nmreval']
path = None conf_path = None
for p in searchpaths: for p in searchpaths:
path = pathlib.Path(p).expanduser() path = pathlib.Path(p).expanduser()
if path.exists(): if path.exists():
conf_path = path
break break
if path is None: if conf_path is None:
raise FileNotFoundError('No valid configuration path found') raise FileNotFoundError('No valid configuration path found')
return path return conf_path
def read_configuration() -> configparser.ConfigParser: def read_configuration() -> configparser.ConfigParser:

View File

@ -233,8 +233,8 @@ class Ui_BaseWindow(object):
self.actionShow_log.setObjectName("actionShow_log") self.actionShow_log.setObjectName("actionShow_log")
self.action_create_fit_function = QtWidgets.QAction(BaseWindow) self.action_create_fit_function = QtWidgets.QAction(BaseWindow)
self.action_create_fit_function.setObjectName("action_create_fit_function") self.action_create_fit_function.setObjectName("action_create_fit_function")
self.actionGrace_preferences = QtWidgets.QAction(BaseWindow) self.action_colorcycle = QtWidgets.QAction(BaseWindow)
self.actionGrace_preferences.setObjectName("actionGrace_preferences") self.action_colorcycle.setObjectName("action_colorcycle")
self.actionSave_session = QtWidgets.QAction(BaseWindow) self.actionSave_session = QtWidgets.QAction(BaseWindow)
self.actionSave_session.setObjectName("actionSave_session") self.actionSave_session.setObjectName("actionSave_session")
self.actionMouse_behaviour = QtWidgets.QAction(BaseWindow) self.actionMouse_behaviour = QtWidgets.QAction(BaseWindow)
@ -420,7 +420,7 @@ class Ui_BaseWindow(object):
self.menuFit.addAction(self.menuLimits.menuAction()) self.menuFit.addAction(self.menuLimits.menuAction())
self.menuOptions.addAction(self.actionMouse_behaviour) self.menuOptions.addAction(self.actionMouse_behaviour)
self.menuOptions.addSeparator() self.menuOptions.addSeparator()
self.menuOptions.addAction(self.actionGrace_preferences) self.menuOptions.addAction(self.action_colorcycle)
self.menuOptions.addAction(self.actionConfiguration) self.menuOptions.addAction(self.actionConfiguration)
self.menuView.addAction(self.actionTile) self.menuView.addAction(self.actionTile)
self.menuView.addAction(self.actionCascade_windows) self.menuView.addAction(self.actionCascade_windows)
@ -547,7 +547,7 @@ class Ui_BaseWindow(object):
self.actionShift.setText(_translate("BaseWindow", "&Shift/scale...")) self.actionShift.setText(_translate("BaseWindow", "&Shift/scale..."))
self.actionShow_log.setText(_translate("BaseWindow", "&Show log...")) self.actionShow_log.setText(_translate("BaseWindow", "&Show log..."))
self.action_create_fit_function.setText(_translate("BaseWindow", "&Create fit function...")) self.action_create_fit_function.setText(_translate("BaseWindow", "&Create fit function..."))
self.actionGrace_preferences.setText(_translate("BaseWindow", "&Grace preferences...")) self.action_colorcycle.setText(_translate("BaseWindow", "Color cycles..."))
self.actionSave_session.setText(_translate("BaseWindow", "Update session")) self.actionSave_session.setText(_translate("BaseWindow", "Update session"))
self.actionMouse_behaviour.setText(_translate("BaseWindow", "Mouse behaviour")) self.actionMouse_behaviour.setText(_translate("BaseWindow", "Mouse behaviour"))
self.actionMouse_behaviour.setToolTip(_translate("BaseWindow", "Switch between zoom and pan in graph.")) self.actionMouse_behaviour.setToolTip(_translate("BaseWindow", "Switch between zoom and pan in graph."))

View File

@ -15,12 +15,9 @@ class Ui_Dialog(object):
Dialog.setObjectName("Dialog") Dialog.setObjectName("Dialog")
Dialog.resize(390, 409) Dialog.resize(390, 409)
self.gridLayout = QtWidgets.QGridLayout(Dialog) self.gridLayout = QtWidgets.QGridLayout(Dialog)
self.gridLayout.setContentsMargins(3, 3, 3, 3)
self.gridLayout.setSpacing(3)
self.gridLayout.setObjectName("gridLayout") self.gridLayout.setObjectName("gridLayout")
self.append_palette_button = QtWidgets.QPushButton(Dialog)
self.append_palette_button.setObjectName("append_palette_button")
self.gridLayout.addWidget(self.append_palette_button, 2, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem, 4, 0, 1, 1)
self.palette_combobox = QtWidgets.QComboBox(Dialog) self.palette_combobox = QtWidgets.QComboBox(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -28,7 +25,7 @@ class Ui_Dialog(object):
sizePolicy.setHeightForWidth(self.palette_combobox.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.palette_combobox.sizePolicy().hasHeightForWidth())
self.palette_combobox.setSizePolicy(sizePolicy) self.palette_combobox.setSizePolicy(sizePolicy)
self.palette_combobox.setObjectName("palette_combobox") self.palette_combobox.setObjectName("palette_combobox")
self.gridLayout.addWidget(self.palette_combobox, 0, 0, 1, 1) self.gridLayout.addWidget(self.palette_combobox, 0, 1, 1, 2)
self.add_color_button = QtWidgets.QPushButton(Dialog) self.add_color_button = QtWidgets.QPushButton(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -36,24 +33,7 @@ class Ui_Dialog(object):
sizePolicy.setHeightForWidth(self.add_color_button.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.add_color_button.sizePolicy().hasHeightForWidth())
self.add_color_button.setSizePolicy(sizePolicy) self.add_color_button.setSizePolicy(sizePolicy)
self.add_color_button.setObjectName("add_color_button") self.add_color_button.setObjectName("add_color_button")
self.gridLayout.addWidget(self.add_color_button, 6, 0, 1, 1) self.gridLayout.addWidget(self.add_color_button, 3, 2, 1, 1)
self.color_combobox = ColorListEditor(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.color_combobox.sizePolicy().hasHeightForWidth())
self.color_combobox.setSizePolicy(sizePolicy)
self.color_combobox.setObjectName("color_combobox")
self.gridLayout.addWidget(self.color_combobox, 5, 0, 1, 1)
self.save_button = QtWidgets.QPushButton(Dialog)
self.save_button.setObjectName("save_button")
self.gridLayout.addWidget(self.save_button, 9, 1, 1, 1)
self.add_palette_button = QtWidgets.QPushButton(Dialog)
self.add_palette_button.setObjectName("add_palette_button")
self.gridLayout.addWidget(self.add_palette_button, 1, 0, 1, 1)
self.new_name_edit = QtWidgets.QLineEdit(Dialog)
self.new_name_edit.setObjectName("new_name_edit")
self.gridLayout.addWidget(self.new_name_edit, 9, 2, 1, 1)
self.colorlist = QtWidgets.QListWidget(Dialog) self.colorlist = QtWidgets.QListWidget(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -62,12 +42,50 @@ class Ui_Dialog(object):
self.colorlist.setSizePolicy(sizePolicy) self.colorlist.setSizePolicy(sizePolicy)
self.colorlist.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) self.colorlist.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
self.colorlist.setObjectName("colorlist") self.colorlist.setObjectName("colorlist")
self.gridLayout.addWidget(self.colorlist, 0, 1, 9, 2) self.gridLayout.addWidget(self.colorlist, 4, 1, 1, 2)
self.add_palette_button = QtWidgets.QPushButton(Dialog)
self.add_palette_button.setObjectName("add_palette_button")
self.gridLayout.addWidget(self.add_palette_button, 1, 1, 1, 1)
self.new_name_edit = QtWidgets.QLineEdit(Dialog)
self.new_name_edit.setObjectName("new_name_edit")
self.gridLayout.addWidget(self.new_name_edit, 6, 1, 1, 2)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox") self.buttonBox.setObjectName("buttonBox")
self.gridLayout.addWidget(self.buttonBox, 10, 0, 1, 3) self.gridLayout.addWidget(self.buttonBox, 7, 0, 1, 3)
self.color_combobox = ColorListEditor(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.color_combobox.sizePolicy().hasHeightForWidth())
self.color_combobox.setSizePolicy(sizePolicy)
self.color_combobox.setObjectName("color_combobox")
self.gridLayout.addWidget(self.color_combobox, 3, 1, 1, 1)
self.line = QtWidgets.QFrame(Dialog)
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.gridLayout.addWidget(self.line, 2, 0, 1, 3)
self.save_button = QtWidgets.QPushButton(Dialog)
self.save_button.setObjectName("save_button")
self.gridLayout.addWidget(self.save_button, 6, 0, 1, 1)
self.label = QtWidgets.QLabel(Dialog)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.append_palette_button = QtWidgets.QPushButton(Dialog)
self.append_palette_button.setObjectName("append_palette_button")
self.gridLayout.addWidget(self.append_palette_button, 1, 2, 1, 1)
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1)
self.line_2 = QtWidgets.QFrame(Dialog)
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.gridLayout.addWidget(self.line_2, 5, 0, 1, 3)
self.label.setBuddy(self.palette_combobox)
self.label_2.setBuddy(self.color_combobox)
self.retranslateUi(Dialog) self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept) self.buttonBox.accepted.connect(Dialog.accept)
@ -76,9 +94,11 @@ class Ui_Dialog(object):
def retranslateUi(self, Dialog): def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Color Palette")) Dialog.setWindowTitle(_translate("Dialog", "Color cycles"))
self.append_palette_button.setText(_translate("Dialog", "Append"))
self.add_color_button.setText(_translate("Dialog", "Add color")) self.add_color_button.setText(_translate("Dialog", "Add color"))
self.save_button.setText(_translate("Dialog", "Save as new list"))
self.add_palette_button.setText(_translate("Dialog", "Load")) self.add_palette_button.setText(_translate("Dialog", "Load"))
self.save_button.setText(_translate("Dialog", "Save as new list"))
self.label.setText(_translate("Dialog", "Color cycles"))
self.append_palette_button.setText(_translate("Dialog", "Append"))
self.label_2.setText(_translate("Dialog", "Available color"))
from ..lib.delegates import ColorListEditor from ..lib.delegates import ColorListEditor

View File

@ -14,7 +14,7 @@ from ...lib.lines import LineStyle
from ...lib.symbols import SymbolStyle, symbolcycle from ...lib.symbols import SymbolStyle, symbolcycle
from ...data.nmr import Spectrum, FID from ...data.nmr import Spectrum, FID
from ..Qt import QtCore from ..Qt import QtCore, QtGui
from ..io.exporters import GraceExporter from ..io.exporters import GraceExporter
from ..lib.decorators import plot_update from ..lib.decorators import plot_update
from ..lib.pg_objects import ErrorBars, PlotItem from ..lib.pg_objects import ErrorBars, PlotItem
@ -278,7 +278,9 @@ class ExperimentContainer(QtCore.QObject):
def get_properties(self) -> dict: def get_properties(self) -> dict:
props = OrderedDict() props = OrderedDict()
props['General'] = OrderedDict([('Name', self.name), ('Value', str(self.value)), ('Group', str(self.group))]) props['General'] = OrderedDict([('Name', self.name),
('Value', str(self.value)),
('Group', str(self.group))])
props['Symbol'] = OrderedDict() props['Symbol'] = OrderedDict()
props['Line'] = OrderedDict() props['Line'] = OrderedDict()
@ -302,15 +304,11 @@ class ExperimentContainer(QtCore.QObject):
return props return props
def setColor(self, color, symbol=False, line=False, mode='real'): def setColor(self, color, symbol=False, line=False, mode='real'):
if mode == 'real': if mode in ['real', 'all']:
self.plot_real.set_color(color, symbol=symbol, line=line) self.plot_real.set_color(color, symbol=symbol, line=line)
if self.plot_real.symbol != SymbolStyle.No and symbol: if self.plot_error is not None:
err_pen = self.plot_error.pen err_pen = self.plot_error.opts['pen']
err_pen.setColor(self.plot_real.symbolcolor.rbg()) err_pen.setColor(QtGui.QColor(*self.plot_real.symbolcolor.rgb()))
self.plot_error.setData(pen=err_pen)
elif line:
err_pen = self.plot_error.pen
err_pen.setColor(self.plot_real.linecolor.rbg())
self.plot_error.setData(pen=err_pen) self.plot_error.setData(pen=err_pen)
elif mode == 'imag' and self.plot_imag is not None: elif mode == 'imag' and self.plot_imag is not None:
@ -319,17 +317,25 @@ class ExperimentContainer(QtCore.QObject):
print('Updating color failed for ' + str(self.id)) print('Updating color failed for ' + str(self.id))
def setSymbol(self, symbol=None, color=None, size=None, mode='real'): def setSymbol(self, symbol=None, color=None, size=None, mode='real'):
if mode == 'real': if mode in ['real', 'all']:
self.plot_real.set_symbol(symbol=symbol, size=size, color=color) self.plot_real.set_symbol(symbol=symbol, size=size, color=color)
elif mode == 'imag' and self.plot_imag is not None: if color is not None and self.plot_error is not None and self.plot_real.symbol != SymbolStyle.No:
err_pen = self.plot_error.opts['pen']
err_pen.setColor(QtGui.QColor(*self.plot_real.symbolcolor.rgb()))
self.plot_error.setData(pen=err_pen)
elif mode in ['imag', 'all'] and self.plot_imag is not None:
self.plot_imag.set_symbol(symbol=symbol, size=size, color=color) self.plot_imag.set_symbol(symbol=symbol, size=size, color=color)
else: else:
print('Updating symbol failed for ' + str(self.id)) print('Updating symbol failed for ' + str(self.id))
def setLine(self, width=None, style=None, color=None, mode='real'): def setLine(self, width=None, style=None, color=None, mode='real'):
if mode == 'real': if mode in ['real', 'all']:
self.plot_real.set_line(width=width, style=style, color=color) self.plot_real.set_line(width=width, style=style, color=color)
elif mode == 'imag' and self.plot_imag is not None: if color is not None and self.plot_error is not None and self.plot_real.symbol == SymbolStyle.No:
err_pen = self.plot_error.opts['pen']
err_pen.setColor(QtGui.QColor(*self.plot_real.linecolor.rgb()))
self.plot_error.setData(pen=err_pen)
elif mode in ['imag', 'all'] and self.plot_imag is not None:
self.plot_imag.set_line(width=width, style=style, color=color) self.plot_imag.set_line(width=width, style=style, color=color)
else: else:
print('Updating line failed for ' + str(self.id)) print('Updating line failed for ' + str(self.id))
@ -532,12 +538,6 @@ class PointContainer(ExperimentContainer):
self.plot_error = ErrorBars(x=self._data.x, y=self._data.y, top=self._data.y_err, bottom=self._data.y_err, self.plot_error = ErrorBars(x=self._data.x, y=self._data.y, top=self._data.y_err, bottom=self._data.y_err,
pen=mkPen({'color': self.plot_real.linecolor.rgb()})) pen=mkPen({'color': self.plot_real.linecolor.rgb()}))
def update_property(self, key1: str, key2: str, value: Any):
# update default color
if key1 == 'Symbol' and key2 == 'Color':
self.plot_real.set_color(value, symbol=True, line=False)
super().update_property(key1, key2, value)
class FitContainer(ExperimentContainer): class FitContainer(ExperimentContainer):
def __init__(self, identifier, data, **kwargs): def __init__(self, identifier, data, **kwargs):

View File

@ -1,5 +1,6 @@
from typing import List, Tuple, Union from typing import List, Tuple, Union
from nmreval.lib.colors import available_cycles
from .properties import PropWidget from .properties import PropWidget
from ...Qt import QtWidgets, QtGui, QtCore from ...Qt import QtWidgets, QtGui, QtCore
from ..._py.datawidget import Ui_DataWidget from ..._py.datawidget import Ui_DataWidget
@ -99,6 +100,7 @@ class DataTree(QtWidgets.QTreeWidget):
child = item.child(i) child = item.child(i)
child.setCheckState(0, QtCore.Qt.Checked) child.setCheckState(0, QtCore.Qt.Checked)
to_be_shown.add(child.data(0, QtCore.Qt.UserRole)) to_be_shown.add(child.data(0, QtCore.Qt.UserRole))
self._checked_sets.add(child.data(0, QtCore.Qt.UserRole))
self.blockSignals(False) self.blockSignals(False)
# check state change to unchecked # check state change to unchecked
@ -303,10 +305,10 @@ class DataTree(QtWidgets.QTreeWidget):
iterator += 1 iterator += 1
def contextMenuEvent(self, evt): def contextMenuEvent(self, evt, color_list=None):
menu = QtWidgets.QMenu() menu = QtWidgets.QMenu()
d = menu.addAction('Hello') _ = menu.addAction('Hello')
d.setEnabled(False) _.setEnabled(False)
menu.addSeparator() menu.addSeparator()
idx = self.selectedIndexes() idx = self.selectedIndexes()
@ -326,6 +328,10 @@ class DataTree(QtWidgets.QTreeWidget):
cat_action = menu.addAction('Join us!') cat_action = menu.addAction('Join us!')
plt_action = None plt_action = None
save_action = None save_action = None
menu.addSeparator()
col_menu = menu.addMenu('Color cycle')
for c in available_cycles.keys():
col_menu.addAction(c)
idx = {} idx = {}
has_fits = False has_fits = False
@ -355,10 +361,11 @@ class DataTree(QtWidgets.QTreeWidget):
action = menu.exec(evt.globalPos()) action = menu.exec(evt.globalPos())
if action == del_action:
s = [] s = []
for gid, sets in idx.items(): for gid, sets in idx.items():
s.extend(sets) s.extend(sets)
if action == del_action:
self.management.delete_sets(s) self.management.delete_sets(s)
elif action == cp_action: elif action == cp_action:
@ -366,23 +373,17 @@ class DataTree(QtWidgets.QTreeWidget):
self.management.copy_sets(sets, gid) self.management.copy_sets(sets, gid)
elif action == cat_action: elif action == cat_action:
s = []
for gid, sets in idx.items():
s.extend(sets)
self.management.cat(s) self.management.cat(s)
elif action == plt_action: elif action == plt_action:
s = []
for gid, sets in idx.items():
s.extend(sets)
self.management.make_fit_parameter(s) self.management.make_fit_parameter(s)
elif action == save_action: elif action == save_action:
s = []
for gid, sets in idx.items():
s.extend(sets)
self.saveFits.emit(s) self.saveFits.emit(s)
elif action.parent() == col_menu:
self.management.set_cycle(s, action.text())
evt.accept() evt.accept()
def highlight(self, gid: str): def highlight(self, gid: str):

View File

@ -8,7 +8,7 @@ from typing import List, Union
from numpy import errstate, floor, log10 from numpy import errstate, floor, log10
from pyqtgraph import GraphicsObject, getConfigOption, mkColor from pyqtgraph import GraphicsObject, getConfigOption, mkColor
from ..lib.pg_objects import RegionItem from ..lib.pg_objects import LegendItemBlock, RegionItem
from ...utils.text import convert from ...utils.text import convert
from ..Qt import QtCore, QtWidgets, QtGui from ..Qt import QtCore, QtWidgets, QtGui
from .._py.graph import Ui_GraphWindow from .._py.graph import Ui_GraphWindow
@ -86,10 +86,10 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
ax.setStyle(showValues=False) ax.setStyle(showValues=False)
ax.setWidth(10) ax.setWidth(10)
self.legend = self.plotItem.addLegend() self.legend = LegendItemBlock(offset=(20, 20))
self.legend.setParentItem(self.plotItem.vb)
self.plotItem.legend = self.legend
self.legend.setVisible(True) self.legend.setVisible(True)
# self.legend.setBrush(color=self._bgcolor)
self.legend.layout.setContentsMargins(1, 1, 1, 1)
self.plotItem.setMenuEnabled(False, True) self.plotItem.setMenuEnabled(False, True)
self.plotItem.ctrl.logXCheck.blockSignals(True) self.plotItem.ctrl.logXCheck.blockSignals(True)

View File

@ -1,16 +1,16 @@
from ...configs import config_paths from ...configs import config_paths
from ..Qt import QtWidgets, QtCore, QtGui from ..Qt import QtWidgets, QtCore, QtGui
from .._py.color_palette import Ui_Dialog from .._py.color_palette import Ui_Dialog
from ...lib.colors import Colors, get_palettes from ...lib.colors import Colors, available_cycles
class PaletteDialog(QtWidgets.QDialog, Ui_Dialog): class ColorDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
self.setupUi(self) self.setupUi(self)
self._palettes = get_palettes() self._palettes = available_cycles
self.palette_combobox.addItems(self._palettes.keys()) self.palette_combobox.addItems(self._palettes.keys())
self.colorlist.installEventFilter(self) self.colorlist.installEventFilter(self)
@ -26,7 +26,7 @@ class PaletteDialog(QtWidgets.QDialog, Ui_Dialog):
@QtCore.pyqtSlot(name='on_add_palette_button_pressed') @QtCore.pyqtSlot(name='on_add_palette_button_pressed')
@QtCore.pyqtSlot(name='on_append_palette_button_pressed') @QtCore.pyqtSlot(name='on_append_palette_button_pressed')
def set_palette(self, clear=True): def set_palette(self, clear: bool = False):
if self.sender() == self.add_palette_button or clear: if self.sender() == self.add_palette_button or clear:
self.colorlist.clear() self.colorlist.clear()
@ -49,15 +49,15 @@ class PaletteDialog(QtWidgets.QDialog, Ui_Dialog):
return return
if not self.new_name_edit.text(): if not self.new_name_edit.text():
_ = QtWidgets.QMessageBox.warning(self, 'Error', 'New colors have no name.') _ = QtWidgets.QMessageBox.warning(self, 'Error', 'New list has no name.')
return return
color_name = self.new_name_edit.text() color_name = self.new_name_edit.text() # type: str
if color_name in self._palettes: if color_name in self._palettes:
_ = QtWidgets.QMessageBox.warning(self, 'Error', 'Name already used.') _ = QtWidgets.QMessageBox.warning(self, 'Error', 'Name is already used.')
return return
color_file = config_paths() / 'colorschemes.cfg' color_file = config_paths() / 'colors.cfg'
new_palette = [] new_palette = []
with color_file.open('a') as f: with color_file.open('a') as f:
@ -66,8 +66,7 @@ class PaletteDialog(QtWidgets.QDialog, Ui_Dialog):
item = self.colorlist.item(i) item = self.colorlist.item(i)
r, g, b = item.data(QtCore.Qt.DecorationRole).getRgbF()[:3] r, g, b = item.data(QtCore.Qt.DecorationRole).getRgbF()[:3]
new_palette.append(Colors.from_rgb(r, g, b, normed=True)) new_palette.append(Colors.from_rgb(r, g, b, normed=True))
f.write('{r*255:.1f}, {g*255:.1f}, {b*255:.1f}\n') f.write(f'{r*255:.1f}, {g*255:.1f}, {b*255:.1f}\n')
f.write('%.1f, %.1f}, %.1f}\n' % (r*255, g*255, b*255))
f.write('\n') f.write('\n')
self._palettes[color_name] = new_palette self._palettes[color_name] = new_palette

View File

@ -2,7 +2,7 @@ import re
from ..Qt import QtWidgets, QtGui, QtCore from ..Qt import QtWidgets, QtGui, QtCore
from ...lib.colors import BaseColor, TUColors from ...lib.colors import BaseColor, Colors
from ...lib.lines import LineStyle from ...lib.lines import LineStyle
from ...lib.symbols import SymbolStyle, make_symbol_pixmap from ...lib.symbols import SymbolStyle, make_symbol_pixmap
@ -106,7 +106,7 @@ class ColorListEditor(QtWidgets.QComboBox):
break break
def populateList(self): def populateList(self):
for i, colorName in enumerate(TUColors): for i, colorName in enumerate(Colors):
color = QtGui.QColor(*colorName.value) color = QtGui.QColor(*colorName.value)
self.insertItem(i, colorName.name) self.insertItem(i, colorName.name)
self.setItemData(i, colorName) self.setItemData(i, colorName)

View File

@ -145,9 +145,9 @@ class FormWidget(QtWidgets.QWidget):
if self._type == 'str': if self._type == 'str':
self.vals.setText(val) self.vals.setText(val)
elif self._type == 'int': elif self._type == 'int':
self.vals.setText(f'{val:.0f}') self.vals.setText(f'{float(val):.0f}')
else: else:
self.vals.setText(f'{val:.5g}') self.vals.setText(f'{float(val):.5g}')
def setChecked(self, enable): def setChecked(self, enable):
if self._checkable: if self._checkable:

View File

@ -5,6 +5,7 @@ from pyqtgraph import (
LinearRegionItem, mkBrush, LinearRegionItem, mkBrush,
mkColor, mkPen, mkColor, mkPen,
PlotDataItem, PlotDataItem,
LegendItem,
) )
from ...lib.colors import BaseColor, Colors, TUColors from ...lib.colors import BaseColor, Colors, TUColors
@ -438,3 +439,24 @@ class RegionItem(LinearRegionItem):
self.prepareGeometryChange() self.prepareGeometryChange()
return br return br
class LegendItemBlock(LegendItem):
"""
Simple subclass that stops dragging legend outside of view
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.layout.setContentsMargins(1, 1, 1, 1)
def mouseDragEvent(self, ev):
if ev.button() == QtCore.Qt.LeftButton:
ev.accept()
dpos = ev.pos() - ev.lastPos()
vb_rect = self.parentItem().rect()
pos = self.pos()
# upper left corner and a point a little more to the bottom right must be inside
if vb_rect.contains(pos+dpos) and vb_rect.contains(pos+dpos+QtCore.QPointF(20., 20.)):
self.autoAnchor(pos + dpos)
else:
self.autoAnchor(pos)

View File

@ -3,13 +3,13 @@ from contextlib import contextmanager
from numpy import linspace from numpy import linspace
from scipy.interpolate import interp1d from scipy.interpolate import interp1d
from ..Qt import QtGui, QtWidgets from ..Qt import QtGui, QtWidgets, QtCore
@contextmanager @contextmanager
def busy_cursor(): def busy_cursor():
try: try:
cursor = QtGui.QCursor(QtGui.QPixmap('/autohome/dominik/Downloads/slowbro.gif')) cursor = QtGui.QCursor(QtCore.Qt.ForbiddenCursor)
QtWidgets.QApplication.setOverrideCursor(cursor) QtWidgets.QApplication.setOverrideCursor(cursor)
yield yield

View File

@ -936,6 +936,12 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
dialog = GeneralConfiguration(self) dialog = GeneralConfiguration(self)
dialog.show() dialog.show()
@QtCore.pyqtSlot(name='on_action_colorcycle_triggered')
def open_color_dialog(self):
from ..lib.color_dialog import ColorDialog
dialog = ColorDialog(self)
dialog.show()
def close(self): def close(self):
write_state({'recent_path': str(self.path)}) write_state({'recent_path': str(self.path)})

View File

@ -9,7 +9,7 @@ from ...fit import data as fit_d
from ...fit.model import Model from ...fit.model import Model
from ...fit.result import FitResult from ...fit.result import FitResult
from ...fit.minimizer import FitRoutine from ...fit.minimizer import FitRoutine
from ...lib.colors import TUColorsC from ...lib.colors import TUColorsC, available_cycles
from ...math.interpol import interpolate from ...math.interpol import interpolate
from ...math.logfourier import logft from ...math.logfourier import logft
from ...math.smooth import smooth from ...math.smooth import smooth
@ -697,10 +697,10 @@ class UpperManagement(QtCore.QObject):
self.newData.emit(new_data, self.current_graph) self.newData.emit(new_data, self.current_graph)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def update_color(self): def set_cycle(self, set_idx: list, cycle_name: str):
UpperManagement._colors = cycle(TUColors) col = cycle(available_cycles[cycle_name])
for i in self.active: for s_id in set_idx:
self.data[i].color = next(UpperManagement._colors) self.data[s_id].setColor(next(col), symbol=True, line=True, mode='all')
@QtCore.pyqtSlot(dict, tuple) @QtCore.pyqtSlot(dict, tuple)
def shift_scale(self, values: dict, options: tuple): def shift_scale(self, values: dict, options: tuple):

View File

@ -1,5 +1,6 @@
import enum import enum
import re import re
from math import atan2, cos, exp, pi, sin, sqrt
from ..configs import config_paths from ..configs import config_paths
@ -49,10 +50,11 @@ class BaseColor(enum.Enum):
if normed: if normed:
return hue/360, saturation, lightness return hue/360, saturation, lightness
else: else:
return hue, saturation*255, lightness*255 return hue, saturation*100, lightness*100
def xyz(self): def xyz(self, normed=True):
rgb = list(self.rgb(normed=True)) rgb = list(self.rgb(normed=True))
for i, val in enumerate(rgb): for i, val in enumerate(rgb):
rgb[i] = ((val+0.055)/1.055)**2.4 if val > 0.04045 else val/12.92 rgb[i] = ((val+0.055)/1.055)**2.4 if val > 0.04045 else val/12.92
@ -60,7 +62,10 @@ class BaseColor(enum.Enum):
y = sum(i*j for i, j in zip([0.2126, 0.7152, 0.0722], rgb)) y = sum(i*j for i, j in zip([0.2126, 0.7152, 0.0722], rgb))
z = sum(i*j for i, j in zip([0.0193, 0.1192, 0.9505], rgb)) z = sum(i*j for i, j in zip([0.0193, 0.1192, 0.9505], rgb))
if normed:
return x, y, z return x, y, z
else:
return x*100, y*100, z*100
def hsv(self, normed=False): def hsv(self, normed=False):
r, g, b = self.rgb(normed=True) r, g, b = self.rgb(normed=True)
@ -95,17 +100,17 @@ class BaseColor(enum.Enum):
if normed: if normed:
return hue / 360, saturation, col_max return hue / 360, saturation, col_max
else: else:
return hue, saturation * 255, col_max * 255 return hue, saturation * 100, col_max * 100
def lab(self): def lab(self):
x, y, z = self.xyz() x, y, z = self.xyz(normed=False)
x /= 95.0489 x /= 95.0489
y /= 100 y /= 100
z /= 108.884 z /= 108.884
x = x**(1 / 3) if x > 0.008856 else 7.787 * x + 16 / 116 x = x**(1./3.) if x > 0.008856 else 7.787 * x + 16 / 116
y = y**(1 / 3) if y > 0.008856 else 7.787 * y + 16 / 116 y = y**(1./3.) if y > 0.008856 else 7.787 * y + 16 / 116
z = z**(1 / 3) if z > 0.008856 else 7.787 * z + 16 / 116 z = z**(1./3.) if z > 0.008856 else 7.787 * z + 16 / 116
l = 116 * y - 16 l = 116 * y - 16
a = 500 * (x - y) a = 500 * (x - y)
@ -127,7 +132,11 @@ class BaseColor(enum.Enum):
if normed: if normed:
return c, m, y, k return c, m, y, k
else: else:
return c*255, m*255, y*255, k*255 return c*100, m*100, y*100, k*100
def hex(self):
r, g, b = self.value
return f'#{r:02x}{g:02x}{b:02x}'
@classmethod @classmethod
def from_rgb(cls, r, g, b, normed=False): def from_rgb(cls, r, g, b, normed=False):
@ -262,6 +271,19 @@ class Tab20(BaseColor):
TabTurquoise2 = (158, 218, 229) TabTurquoise2 = (158, 218, 229)
class ColorBlind(BaseColor):
c0 = (0, 107, 164)
c1 = (255, 128, 14)
c2 = (171, 171, 171)
c3 = (89, 89, 89)
c4 = (95, 158, 209)
c5 = (200, 82, 0)
c6 = (137, 137, 137)
c7 = (162, 200, 237)
c8 = (255, 188, 121)
c9 = (207, 207, 207)
class GraceColors(BaseColor): class GraceColors(BaseColor):
Red = (255, 0, 0) Red = (255, 0, 0)
Green = (0, 255, 0) Green = (0, 255, 0)
@ -272,7 +294,7 @@ class GraceColors(BaseColor):
Violet = (148, 0, 211) Violet = (148, 0, 211)
Cyan = (0, 255, 255) Cyan = (0, 255, 255)
Magenta = (255, 0, 255) Magenta = (255, 0, 255)
Orange = (255, 255, 255) Orange = (255, 165, 0)
Indigo = (114, 33, 188) Indigo = (114, 33, 188)
Maroon = (103, 7, 72) Maroon = (103, 7, 72)
Turquoise = (64, 224, 208) Turquoise = (64, 224, 208)
@ -292,26 +314,107 @@ TUColors = enum.Enum(
Colors = enum.Enum( Colors = enum.Enum(
value='Colors', value='Colors',
names={member.name: member.value for palette in [TUColors, TUGrays, GraceColors, Tab10, BlackWhite] for member in palette}, names={member.name: member.value for palette in [TUColors, TUGrays, GraceColors] for member in palette},
type=BaseColor, type=BaseColor,
) )
def ciede2000(c1: BaseColor, c2: BaseColor):
"""
Calculate difference between to colors with CIEDE2000 [1]_
Args:
c1: Color
c2: Color
[1]: G. Sharma, W.Wu, E. N. Dalal: The CIEDE2000 color-difference formula:
Implementation notes, supplementary test data, and mathematical observations. Color (2004)
https://doi.org/10.1002/col.20070
"""
l1, a1, b1 = c1.lab()
l2, a2, b2 = c2.lab()
l_bar = (l1 + l2) / 2
delta_l = l2 - l1
c1 = sqrt(a1**2 + b1**2)
c2 = sqrt(a2**2 + b2**2)
c_bar = (c1 + c2) / 2
c_scale = (1 - sqrt(c_bar**7 / (c_bar**7 + 25**7))) / 2
a1_prime = a1 * (1 + c_scale)
a2_prime = a2 * (1 + c_scale)
c1_prime = sqrt(a1_prime**2 + b1**2)
c2_prime = sqrt(a2_prime**2 + b2**2)
c_bar_prime = (c1_prime + c2_prime) / 2
delta_c = c2_prime - c1_prime
h1 = (atan2(b1, a1) * 180 / pi + 360) % 360
h2 = (atan2(b2, a2) * 180 / pi + 360) % 360
if c1_prime * c2_prime == 0:
dh = 0
else:
if abs(h1 - h2) <= 180:
dh = h2 - h1
else:
if h2 > h1:
dh = h2 - h1 - 360
else:
dh = h2 - h1 + 360
delta_h = 2 * sqrt(c1_prime * c2_prime) * sin(dh * pi / 360)
if c1 * c2 == 0:
h_bar = h1 + h2
else:
dh_abs = abs(h1 - h2)
h_bar = h1 + h2
if dh_abs > 180:
if h_bar < 360:
h_bar += 360
else:
h_bar -= 360
h_bar /= 2
t = 1 - 0.17 * cos((h_bar - 30) * pi / 180) + 0.25 * cos(h_bar * pi / 90) + 0.32 * cos(
(3 * h_bar - 6) * pi / 180) - 0.2 * cos((4 * h_bar - 63) * pi / 180)
s_l = 1 + 0.015 * (l_bar - 50)**2 / sqrt(20 + (l_bar - 50)**2)
s_c = 1 + 0.045 * c_bar_prime
s_h = 1 + 0.015 * c_bar_prime * t
r_t = -2 * sqrt(c_bar_prime**7 / (c_bar_prime**7 + 25**7)) * sin(pi / 3 * exp(-((h_bar - 275) / 25)**2))
delta_e = (delta_l / s_l)**2 + (delta_c / s_c)**2 + (delta_h / s_h)**2 + r_t * delta_c / s_c * delta_h / s_h
return sqrt(delta_e)
def get_palettes(): def get_palettes():
palettes = { palettes = {
'Full': Colors, 'TuDa': TUColors,
'TuDa:a': TUColorsA, 'TuDa:a': TUColorsA,
'TuDa:b': TUColorsB, 'TuDa:b': TUColorsB,
'TuDa:c': TUColorsC, 'TuDa:c': TUColorsC,
'TuDa:d': TUColorsD, 'TuDa:d': TUColorsD,
'Tab10': Tab10, 'TuDa:gray': TUGrays,
'Grace': GraceColors 'Grace': GraceColors,
'mpl': [Colors.TuDa2b, Colors.TuDa8a, Colors.TuDa4d, Colors.TuDa9b, Colors.TuDa11a,
Colors.TuDa8d, Colors.TuDa10a, Colors.TuDa0a, Colors.TuDa5c, Colors.TuDa2a],
'colorblind': [Colors.TuDa2c, Colors.TuDa8a, Colors.TuDa0b, Colors.TuDa0d, Colors.TuDa2a,
Colors.TuDa8c, Colors.TuDa0c, Colors.TuDa2b, Colors.TuDa7a, Colors.TuDa0a],
} }
with (config_paths() / 'colorschemes.cfg').open() as f: user_colors = config_paths() / 'colors.cfg'
if user_colors.exists():
with user_colors.open() as f:
palette_open = False palette_open = False
for line in f: for line in f:
if line.startswith('%--'): if line.startswith('#--'):
color_name = line[4:-1] color_name = line[4:-1]
palette_open = True palette_open = True
color_list = [] color_list = []
@ -327,4 +430,4 @@ def get_palettes():
return palettes return palettes
available_cycles = get_palettes()

View File

@ -1,5 +1,5 @@
import numpy as np import numpy as np
from ..utils.constants import * from nmreval.utils.constants import *
r""" r"""
Create user-defined fitfunctions using this template. Create user-defined fitfunctions using this template.
@ -44,23 +44,27 @@ class Template(object):
""" """
class _Template(object): class Template:
name = 'Template' name = 'Template'
type = 'User defined' type = 'User defined'
equation = r'A_{infty} x^{2} - k_{B} \beta_{1} exp(-x) + C_{\delta} + \gamma' equation = r'A_{\infty} x^{2} - k_{B} \beta_{1} exp(-x) + C_{\delta} + \gamma'
params = [r'A_{\infty}', r'\beta_{1}'] params = [r'A_{\infty}', r'\beta_{1}', r'C_{\delta}']
bounds = [(0, None), (7, 8)] bounds = [(0, None), (7, 8), (None, None)]
choices = [('a', {'choice 1': 'x', 'choice 2': 'inv_x'}), ('g', gamma)] choices = [('name in dialog', 'c1',
{'Increase by': 'increase', 'Invert': 'inv_x'}),
('\gamma', 'g', gamma)]
@staticmethod @staticmethod
def func(p, x, a, g): def func(x,
# p: list of fit parameters and external parameters: a_inf, beta, delta,
# [A_infty, beta_1, C_delta] c1='inv_x', gamma=gamma['1H']):
# a: first choice (x or inv_x)
# g: gyromagnetic ratio of chosen nucleus (e.g. gamma['1H']) if c1 == 'increase':
if a == 'x': x = x
x = x elif c1 == 'inv_x':
elif a == 'inv_x': x = 1/x
x = 1/x else:
x = x
return a_inf * x**2 - kB * beta * np.exp(-x) + delta + gamma
return p[0] * x**2 - kB * p[1] * np.exp(-x) + p[2] + g

333
resources/Default.agr Normal file
View File

@ -0,0 +1,333 @@
# Grace project file
#
@version 50125
@page size 841, 595
@page scroll 5%
@page inout 5%
@link page off
@map font 14 to "Charter-Regular", "Charter-Regular"
@map font 8 to "Courier", "Courier"
@map font 10 to "Courier-Bold", "Courier-Bold"
@map font 11 to "Courier-BoldOblique", "Courier-BoldOblique"
@map font 15 to "Courier-Italic", "Courier-Italic"
@map font 9 to "Courier-Oblique", "Courier-Oblique"
@map font 17 to "Courier-Regular", "Courier-Regular"
@map font 19 to "Dingbats-Regular", "Dingbats-Regular"
@map font 20 to "FrontPage-Medium", "FrontPage-Medium"
@map font 21 to "FrontPage-Regular", "FrontPage-Regular"
@map font 4 to "Helvetica", "Helvetica"
@map font 6 to "Helvetica-Bold", "Helvetica-Bold"
@map font 7 to "Helvetica-BoldOblique", "Helvetica-BoldOblique"
@map font 5 to "Helvetica-Oblique", "Helvetica-Oblique"
@map font 34 to "NimbusMonoL-Bold", "NimbusMonoL-Bold"
@map font 35 to "NimbusMonoL-BoldOblique", "NimbusMonoL-BoldOblique"
@map font 36 to "NimbusMonoL-Regular", "NimbusMonoL-Regular"
@map font 37 to "NimbusMonoL-RegularOblique", "NimbusMonoL-RegularOblique"
@map font 38 to "NimbusRomanNo9L-Medium", "NimbusRomanNo9L-Medium"
@map font 39 to "NimbusRomanNo9L-MediumItalic", "NimbusRomanNo9L-MediumItalic"
@map font 40 to "NimbusRomanNo9L-Regular", "NimbusRomanNo9L-Regular"
@map font 41 to "NimbusRomanNo9L-RegularItalic", "NimbusRomanNo9L-RegularItalic"
@map font 42 to "NimbusSansL-Bold", "NimbusSansL-Bold"
@map font 43 to "NimbusSansL-BoldCondensed", "NimbusSansL-BoldCondensed"
@map font 44 to "NimbusSansL-BoldCondensedItalic", "NimbusSansL-BoldCondensedItalic"
@map font 45 to "NimbusSansL-BoldItalic", "NimbusSansL-BoldItalic"
@map font 46 to "NimbusSansL-Regular", "NimbusSansL-Regular"
@map font 47 to "NimbusSansL-RegularCondensed", "NimbusSansL-RegularCondensed"
@map font 48 to "NimbusSansL-RegularCondensedItalic", "NimbusSansL-RegularCondensedItalic"
@map font 49 to "NimbusSansL-RegularItalic", "NimbusSansL-RegularItalic"
@map font 54 to "Stafford-Regular", "Stafford-Regular"
@map font 57 to "StandardSymbolsL-Regular", "StandardSymbolsL-Regular"
@map font 12 to "Symbol", "Symbol"
@map font 2 to "Times-Bold", "Times-Bold"
@map font 3 to "Times-BoldItalic", "Times-BoldItalic"
@map font 1 to "Times-Italic", "Times-Italic"
@map font 0 to "Times-Roman", "Times-Roman"
@map font 64 to "URWBookmanL-DemiBold", "URWBookmanL-DemiBold"
@map font 65 to "URWBookmanL-DemiBoldItalic", "URWBookmanL-DemiBoldItalic"
@map font 66 to "URWBookmanL-Light", "URWBookmanL-Light"
@map font 67 to "URWBookmanL-LightItalic", "URWBookmanL-LightItalic"
@map font 68 to "URWChanceryL-MediumItalic", "URWChanceryL-MediumItalic"
@map font 69 to "URWGothicL-Book", "URWGothicL-Book"
@map font 70 to "URWGothicL-BookOblique", "URWGothicL-BookOblique"
@map font 71 to "URWGothicL-Demi", "URWGothicL-Demi"
@map font 72 to "URWGothicL-DemiOblique", "URWGothicL-DemiOblique"
@map font 73 to "URWPalladioL-Bold", "URWPalladioL-Bold"
@map font 74 to "URWPalladioL-BoldItalic", "URWPalladioL-BoldItalic"
@map font 75 to "URWPalladioL-Italic", "URWPalladioL-Italic"
@map font 76 to "URWPalladioL-Roman", "URWPalladioL-Roman"
@map font 61 to "Utopia-Bold", "Utopia-Bold"
@map font 62 to "Utopia-BoldItalic", "Utopia-BoldItalic"
@map font 63 to "Utopia-Italic", "Utopia-Italic"
@map font 13 to "ZapfDingbats", "ZapfDingbats"
@map color 0 to (255, 255, 255), "white"
@map color 1 to (0, 0, 0), "black"
@map color 2 to (93, 133, 195), "TuDa1a"
@map color 3 to (0, 156, 218), "TuDa2a"
@map color 4 to (80, 182, 149), "TuDa3a"
@map color 5 to (176, 204, 80), "TuDa4a"
@map color 6 to (221, 223, 72), "TuDa5a"
@map color 7 to (255, 224, 92), "TuDa6a"
@map color 8 to (248, 186, 60), "TuDa7a"
@map color 9 to (238, 122, 52), "TuDa8a"
@map color 10 to (233, 80, 62), "TuDa9a"
@map color 11 to (201, 48, 142), "TuDa10a"
@map color 12 to (128, 69, 151), "TuDa11a"
@map color 13 to (0, 90, 169), "TuDa1b"
@map color 14 to (0, 130, 204), "TuDa2b"
@map color 15 to (0, 157, 129), "TuDa3b"
@map color 16 to (153, 192, 0), "TuDa4b"
@map color 17 to (201, 212, 0), "TuDa5b"
@map color 18 to (253, 202, 0), "TuDa6b"
@map color 19 to (248, 163, 0), "TuDa7b"
@map color 20 to (236, 101, 0), "TuDa8b"
@map color 21 to (239, 0, 26), "TuDa9b"
@map color 22 to (166, 0, 132), "TuDa10b"
@map color 23 to (114, 16, 133), "TuDa11b"
@map color 24 to (0, 78, 138), "TuDa1c"
@map color 25 to (0, 104, 157), "TuDa2c"
@map color 26 to (0, 136, 119), "TuDa3c"
@map color 27 to (127, 171, 22), "TuDa4c"
@map color 28 to (177, 189, 0), "TuDa5c"
@map color 29 to (215, 172, 0), "TuDa6c"
@map color 30 to (210, 135, 0), "TuDa7c"
@map color 31 to (204, 76, 3), "TuDa8c"
@map color 32 to (185, 15, 34), "TuDa9c"
@map color 33 to (149, 17, 105), "TuDa10c"
@map color 34 to (97, 28, 115), "TuDa11c"
@map color 35 to (36, 53, 114), "TuDa1d"
@map color 36 to (0, 78, 115), "TuDa2d"
@map color 37 to (0, 113, 94), "TuDa3d"
@map color 38 to (106, 139, 55), "TuDa4d"
@map color 39 to (153, 166, 4), "TuDa5d"
@map color 40 to (174, 142, 0), "TuDa6d"
@map color 41 to (190, 111, 0), "TuDa7d"
@map color 42 to (169, 73, 19), "TuDa8d"
@map color 43 to (188, 28, 38), "TuDa9d"
@map color 44 to (115, 32, 84), "TuDa10d"
@map color 45 to (76, 34, 106), "TuDa11d"
@map color 46 to (220, 220, 220), "TuDa0a"
@map color 47 to (181, 181, 181), "TuDa0b"
@map color 48 to (137, 137, 137), "TuDa0c"
@map color 49 to (83, 83, 83), "TuDa0d"
@map color 50 to (255, 0, 0), "red"
@map color 51 to (0, 255, 0), "green"
@map color 52 to (0, 0, 255), "blue"
@map color 53 to (255, 255, 0), "yellow"
@map color 54 to (188, 143, 143), "brown"
@map color 55 to (148, 0, 211), "violet"
@map color 56 to (0, 255, 255), "cyan"
@map color 57 to (255, 0, 255), "magenta"
@map color 58 to (255, 165, 0), "orange"
@map color 59 to (114, 33, 188), "indigo"
@map color 60 to (103, 7, 72), "maroon"
@map color 61 to (64, 224, 208), "turquoise"
@map color 62 to (0, 139, 0), "green4"
@reference date 0
@date wrap off
@date wrap year 1950
@default linewidth 1.0
@default linestyle 1
@default color 1
@default pattern 1
@default font 0
@default char size 1.000000
@default symbol size 1.000000
@default sformat "%.8g"
@background color 0
@page background fill on
@timestamp off
@timestamp 0.03, 0.03
@timestamp color 1
@timestamp rot 0
@timestamp font 0
@timestamp char size 1.000000
@timestamp def "Thu Apr 14 17:47:29 2022"
@r0 off
@link r0 to g0
@r0 type above
@r0 linestyle 1
@r0 linewidth 1.0
@r0 color 1
@r0 line 0, 0, 0, 0
@r1 off
@link r1 to g0
@r1 type above
@r1 linestyle 1
@r1 linewidth 1.0
@r1 color 1
@r1 line 0, 0, 0, 0
@r2 off
@link r2 to g0
@r2 type above
@r2 linestyle 1
@r2 linewidth 1.0
@r2 color 1
@r2 line 0, 0, 0, 0
@r3 off
@link r3 to g0
@r3 type above
@r3 linestyle 1
@r3 linewidth 1.0
@r3 color 1
@r3 line 0, 0, 0, 0
@r4 off
@link r4 to g0
@r4 type above
@r4 linestyle 1
@r4 linewidth 1.0
@r4 color 1
@r4 line 0, 0, 0, 0
@g0 on
@g0 hidden false
@g0 type XY
@g0 stacked false
@g0 bar hgap 0.000000
@g0 fixedpoint off
@g0 fixedpoint type 0
@g0 fixedpoint xy 0.000000, 0.000000
@g0 fixedpoint format general general
@g0 fixedpoint prec 6, 6
@with g0
@ world 0, 0, 1, 1
@ stack world 0, 0, 0, 0
@ znorm 1
@ view 0.150000, 0.120000, 1.314214, 0.870000
@ title ""
@ title font 4
@ title size 1.250000
@ title color 1
@ subtitle ""
@ subtitle font 4
@ subtitle size 1.250000
@ subtitle color 1
@ xaxes scale Normal
@ yaxes scale Normal
@ xaxes invert off
@ yaxes invert off
@ xaxis on
@ xaxis type zero false
@ xaxis offset 0.000000 , 0.000000
@ xaxis bar on
@ xaxis bar color 1
@ xaxis bar linestyle 1
@ xaxis bar linewidth 2.0
@ xaxis label ""
@ xaxis label layout para
@ xaxis label place auto
@ xaxis label char size 1.250000
@ xaxis label font 4
@ xaxis label color 1
@ xaxis label place normal
@ xaxis tick on
@ xaxis tick major 0.2
@ xaxis tick minor ticks 1
@ xaxis tick default 6
@ xaxis tick place rounded true
@ xaxis tick in
@ xaxis tick major size 1.000000
@ xaxis tick major color 1
@ xaxis tick major linewidth 1.5
@ xaxis tick major linestyle 1
@ xaxis tick major grid off
@ xaxis tick minor color 1
@ xaxis tick minor linewidth 1.5
@ xaxis tick minor linestyle 1
@ xaxis tick minor grid off
@ xaxis tick minor size 0.500000
@ xaxis ticklabel on
@ xaxis ticklabel format general
@ xaxis ticklabel prec 5
@ xaxis ticklabel formula ""
@ xaxis ticklabel append ""
@ xaxis ticklabel prepend ""
@ xaxis ticklabel angle 0
@ xaxis ticklabel skip 0
@ xaxis ticklabel stagger 0
@ xaxis ticklabel place normal
@ xaxis ticklabel offset auto
@ xaxis ticklabel offset 0.000000 , 0.010000
@ xaxis ticklabel start type auto
@ xaxis ticklabel start 0.000000
@ xaxis ticklabel stop type auto
@ xaxis ticklabel stop 0.000000
@ xaxis ticklabel char size 1.250000
@ xaxis ticklabel font 4
@ xaxis ticklabel color 1
@ xaxis tick place both
@ xaxis tick spec type none
@ yaxis on
@ yaxis type zero false
@ yaxis offset 0.000000 , 0.000000
@ yaxis bar on
@ yaxis bar color 1
@ yaxis bar linestyle 1
@ yaxis bar linewidth 2.0
@ yaxis label ""
@ yaxis label layout para
@ yaxis label place auto
@ yaxis label char size 1.250000
@ yaxis label font 4
@ yaxis label color 1
@ yaxis label place normal
@ yaxis tick on
@ yaxis tick major 0.2
@ yaxis tick minor ticks 1
@ yaxis tick default 6
@ yaxis tick place rounded true
@ yaxis tick in
@ yaxis tick major size 1.000000
@ yaxis tick major color 1
@ yaxis tick major linewidth 1.5
@ yaxis tick major linestyle 1
@ yaxis tick major grid off
@ yaxis tick minor color 1
@ yaxis tick minor linewidth 1.5
@ yaxis tick minor linestyle 1
@ yaxis tick minor grid off
@ yaxis tick minor size 0.500000
@ yaxis ticklabel on
@ yaxis ticklabel format general
@ yaxis ticklabel prec 5
@ yaxis ticklabel formula ""
@ yaxis ticklabel append ""
@ yaxis ticklabel prepend ""
@ yaxis ticklabel angle 0
@ yaxis ticklabel skip 0
@ yaxis ticklabel stagger 0
@ yaxis ticklabel place normal
@ yaxis ticklabel offset auto
@ yaxis ticklabel offset 0.000000 , 0.010000
@ yaxis ticklabel start type auto
@ yaxis ticklabel start 0.000000
@ yaxis ticklabel stop type auto
@ yaxis ticklabel stop 0.000000
@ yaxis ticklabel char size 1.250000
@ yaxis ticklabel font 4
@ yaxis ticklabel color 1
@ yaxis tick place both
@ yaxis tick spec type none
@ altxaxis off
@ altyaxis off
@ legend on
@ legend loctype view
@ legend 0.8, 0.8
@ legend box color 1
@ legend box pattern 1
@ legend box linewidth 1.0
@ legend box linestyle 0
@ legend box fill color 0
@ legend box fill pattern 1
@ legend font 4
@ legend char size 1.250000
@ legend color 1
@ legend length 4
@ legend vgap 1
@ legend hgap 1
@ legend invert false
@ frame type 0
@ frame linestyle 1
@ frame linewidth 1.5
@ frame color 1
@ frame pattern 1
@ frame background color 0
@ frame background pattern 0

View File

@ -250,7 +250,7 @@
</property> </property>
<addaction name="actionMouse_behaviour"/> <addaction name="actionMouse_behaviour"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionGrace_preferences"/> <addaction name="action_colorcycle"/>
<addaction name="actionConfiguration"/> <addaction name="actionConfiguration"/>
</widget> </widget>
<widget class="QMenu" name="menuWindow"> <widget class="QMenu" name="menuWindow">
@ -665,9 +665,9 @@
<string>&amp;Create fit function...</string> <string>&amp;Create fit function...</string>
</property> </property>
</action> </action>
<action name="actionGrace_preferences"> <action name="action_colorcycle">
<property name="text"> <property name="text">
<string>&amp;Grace preferences...</string> <string>Color cycles...</string>
</property> </property>
</action> </action>
<action name="actionSave_session"> <action name="actionSave_session">

View File

@ -11,30 +11,25 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Color Palette</string> <string>Color cycles</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="0"> <property name="leftMargin">
<widget class="QPushButton" name="append_palette_button"> <number>3</number>
<property name="text">
<string>Append</string>
</property> </property>
</widget> <property name="topMargin">
</item> <number>3</number>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="rightMargin">
<size> <number>3</number>
<width>20</width>
<height>40</height>
</size>
</property> </property>
</spacer> <property name="bottomMargin">
</item> <number>3</number>
<item row="0" column="0"> </property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="palette_combobox"> <widget class="QComboBox" name="palette_combobox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
@ -44,7 +39,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="3" column="2">
<widget class="QPushButton" name="add_color_button"> <widget class="QPushButton" name="add_color_button">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
@ -57,34 +52,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="4" column="1" colspan="2">
<widget class="ColorListEditor" name="color_combobox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QPushButton" name="save_button">
<property name="text">
<string>Save as new list</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="add_palette_button">
<property name="text">
<string>Load</string>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLineEdit" name="new_name_edit"/>
</item>
<item row="0" column="1" rowspan="9" colspan="2">
<widget class="QListWidget" name="colorlist"> <widget class="QListWidget" name="colorlist">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -97,7 +65,17 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0" colspan="3"> <item row="1" column="1">
<widget class="QPushButton" name="add_palette_button">
<property name="text">
<string>Load</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLineEdit" name="new_name_edit"/>
</item>
<item row="7" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -107,6 +85,64 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1">
<widget class="ColorListEditor" name="color_combobox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QPushButton" name="save_button">
<property name="text">
<string>Save as new list</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Color cycles</string>
</property>
<property name="buddy">
<cstring>palette_combobox</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="append_palette_button">
<property name="text">
<string>Append</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Available color</string>
</property>
<property name="buddy">
<cstring>color_combobox</cstring>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>