diff --git a/novelwriter/assets/syntax/cyberpunk_night.conf b/novelwriter/assets/syntax/cyberpunk_night.conf new file mode 100644 index 00000000..96b6ed5c --- /dev/null +++ b/novelwriter/assets/syntax/cyberpunk_night.conf @@ -0,0 +1,26 @@ +[Main] +name = Cyberpunk Night +author = Anders Lemvigh +url = https://github.com/alemvigh +license = CC BY-SA 4.0 +licenseurl = https://creativecommons.org/licenses/by-sa/4.0/ + +[Syntax] +background = 0, 0, 0 +text = 150, 150, 150 +link = 77, 077, 255 +headertext = 255, 255, 255 +headertag = 50, 0, 180 +emphasis = 0, 255, 255 +straightquotes = 7, 27, 219 +doublequotes = 0, 255, 0 +singlequotes = 0, 140, 255 +hidden = 77, 77, 100 +shortcode = 255, 255, 0 +keyword = 255, 100, 255 +value = 255, 150, 10 +spellcheckline = 242, 72, 23 +errorline = 186, 218, 4 +replacetag = 0, 0, 180 +modifier = 144, 142, 176 +optional = 180, 180, 180 diff --git a/novelwriter/assets/syntax/tango.conf b/novelwriter/assets/syntax/tango.conf new file mode 100644 index 00000000..9b3a5c5d --- /dev/null +++ b/novelwriter/assets/syntax/tango.conf @@ -0,0 +1,23 @@ +[Main] +name = Tango +author = Veronica Berglyd Olsen (adaptation) + +[Syntax] +background = 48, 48, 47 +text = 238, 238, 236 +link = 115, 159, 207 +headertext = 115, 159, 207 +headertag = 52, 101, 164 +emphasis = 196, 160, 0 +straightquotes = 239, 41, 41 +doublequotes = 138, 226, 52 +singlequotes = 252, 233, 79 +hidden = 143, 143, 141 +shortcode = 115, 159, 207 +keyword = 239, 41, 41 +value = 173, 127, 168 +optional = 115, 159, 207 +spellcheckline = 239, 41, 41 +errorline = 138, 226, 52 +replacetag = 51, 226, 226 +modifier = 196, 160, 0 diff --git a/novelwriter/assets/themes/cyberpunk_night.conf b/novelwriter/assets/themes/cyberpunk_night.conf new file mode 100644 index 00000000..d0daff9c --- /dev/null +++ b/novelwriter/assets/themes/cyberpunk_night.conf @@ -0,0 +1,29 @@ +[Main] +name = Cyberpunk Night +description = A taste of the future 80s +author = Anders Lemvigh +url = https://github.com/alemvigh +license = CC BY-SA 4.0 +licenseurl = https://creativecommons.org/licenses/by-sa/4.0/ +icontheme = typicons_dark + +[Palette] +window = 0, 0, 0 +windowtext = 150, 150, 150 +base = 0, 0, 0 +alternatebase = 30, 20, 45 +text = 150, 150, 150 +tooltipbase = 40, 20, 70 +tooltiptext = 255, 255, 255 +button = 5, 0, 10 +buttontext = 150, 150, 150 +brighttext = 255, 255, 255 +highlight = 50, 30, 80 +highlightedtext = 255, 255, 255 +link = 77, 77, 255 +linkvisited = 50, 0, 80 + +[GUI] +statusnone = 50, 50, 50 +statussaved = 77, 255, 77 +statusunsaved = 255, 77, 77 diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index 412a5363..a6e23e29 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -344,7 +344,7 @@ class GuiTheme: if themeName: self._themeList.append((themeKey, themeName)) - self._themeList = sorted(self._themeList, key=lambda x: x[1]) + self._themeList = sorted(self._themeList, key=_sortTheme) return self._themeList @@ -360,7 +360,7 @@ class GuiTheme: if syntaxName: self._syntaxList.append((syntaxKey, syntaxName)) - self._syntaxList = sorted(self._syntaxList, key=lambda x: x[1]) + self._syntaxList = sorted(self._syntaxList, key=_sortTheme) return self._syntaxList @@ -725,6 +725,13 @@ class GuiIcons: # Module Functions # =============================================================================================== # + +def _sortTheme(data: tuple[str, str]) -> str: + """Key function for theme sorting.""" + key, name = data + return f"*{name}" if key.startswith("default_") else name + + def _loadInternalName(confParser: NWConfigParser, confFile: str | Path) -> str: """Open a conf file and read the 'name' setting.""" try: diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index b7a77dcd..f4050c0d 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -141,11 +141,12 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI): mp.setattr("builtins.open", causeOSError) assert mainTheme.listThemes() == [] - # Load the theme info + # Load the theme info, default themes first themesList = mainTheme.listThemes() assert themesList[0] == ("default_dark", "Default Dark Theme") assert themesList[1] == ("default_light", "Default Light Theme") - assert themesList[2] == ("default", "Qt Default Theme") + assert themesList[2] == ("cyberpunk_night", "Cyberpunk Night") + assert themesList[3] == ("default", "Qt Default Theme") # A second call should returned the cached list assert mainTheme.listThemes() == mainTheme._themeList