diff --git a/data/media/adwaita_style.css b/data/media/adwaita_style.css
deleted file mode 100644
index 6e1b8ed..0000000
--- a/data/media/adwaita_style.css
+++ /dev/null
@@ -1,4 +0,0 @@
-@define-color dark_bg #353535;
-@define-color light_bg #F6F5F4;
-
-@import url("style.css");
diff --git a/data/media/arc_style.css b/data/media/arc_style.css
deleted file mode 100644
index 0fce002..0000000
--- a/data/media/arc_style.css
+++ /dev/null
@@ -1,4 +0,0 @@
-@define-color dark_bg #31373D;
-@define-color light_bg #EDEDED;
-
-@import url("style.css");
diff --git a/data/media/style.css b/data/media/css/_gtk_base.css
similarity index 73%
rename from data/media/style.css
rename to data/media/css/_gtk_base.css
index 43aea46..399e8c2 100644
--- a/data/media/style.css
+++ b/data/media/css/_gtk_base.css
@@ -27,19 +27,8 @@
.uberwriter_window {
-gtk-key-bindings: window-bindings;
/*border-radius: 7px 7px 3px 3px;*/
- background: @light_bg;
- caret-color: @dark_bg;
-}
-
-.uberwriter_window.dark_mode {
- background: @dark_bg;
- caret-color: @light_bg;
-}
-
-.uberwriter_window.dark_mode .uberwriter-editor text{
- background: @dark_bg;
- caret-color: @light_bg;
- color: @light_bg;
+ background: @background_color;
+ caret-color: @foreground_color;
}
.uberwriter_window.small .uberwriter-editor {
@@ -47,12 +36,7 @@
font-size: 12px;
}
.uberwriter_window grid {
- background-color: @light_bg;
-}
-
-.uberwriter_window.dark_mode grid,
-.uberwriter_window.dark_mode scrolledwindow {
- background-color: @dark_bg;
+ background-color: @background_color;
}
#UberwriterWindow.medium .uberwriter-editor {
@@ -75,25 +59,22 @@
}
#titlebar_container {
- background: @light_bg;
-}
-
-#titlebar_container.dark_mode {
- background: @dark_bg;
+ background: @background_color;
}
.uberwriter-editor {
border: none;
background-color: transparent;
- color: #222;
+ text-decoration-color: #ff0000;
/*-GtkWidget-cursor-color: shade(#4D9FCE, 0.9);*/
/*-GtkWidget-cursor-aspect-ratio: 0.1;*/
-gtk-key-bindings: editor-bindings;
}
.uberwriter-editor text {
- background-color: @light_bg;
- color: #222;
+ background-color: @background_color;
+ color: @foreground_color;
+ caret-color: @foreground_color;
}
.uberwriter-editor:selected {
@@ -120,7 +101,7 @@
.status_bar_box button {
/* finding reset */
- background-color: @light_bg;
+ background-color: @background_color;
text-shadow: inherit;
/*icon-shadow: inherit;*/
box-shadow: initial;
@@ -146,13 +127,13 @@
.status_bar_box button:hover,
.status_bar_box button:checked {
transition: 0s ease-in;
- color: @light_bg;
+ color: @background_color;
background-color: #666;
}
.status_bar_box button:hover label,
.status_bar_box button:checked label {
- color: @light_bg;
+ color: @background_color;
}
.status_bar_box button:active {
@@ -161,22 +142,7 @@
background-image: none;
box-shadow: 0 0 2px rgba(0,0,0,0.4)
}
-.dark_mode .status_bar_box button {
- background-color: @dark_bg;
-}
-.dark_mode .status_bar_box label {
- color: @light_bg;
-}
-.dark_mode .status_bar_box button:hover,
-.dark_mode .status_bar_box button:checked {
- background-color: @light_bg;
- color: #666;
-}
-.dark_mode .status_bar_box button:hover label,
-.dark_mode .status_bar_box button:checked label{
- color: #666;
-}
.status_bar_box separator {
border-color: #999;
border-right: none;
@@ -198,9 +164,9 @@
/*font: serif 10;*/
font-family: serif;
font-size: 10px;
- background: @light_bg;
+ background: @background_color;
border-radius: 4px;
- border-color: @light_bg;
+ border-color: @background_color;
margin: 5px;
padding: 5px;
}
@@ -211,7 +177,7 @@
border: 1px solid #333;
background: @ligth_bg;
border-radius: 3px;
- border-color: @light_bg;
+ border-color: @background_color;
} */
#LexikonBubble label {
@@ -219,9 +185,8 @@
}
#LexikonBubble {
- background-color: @light_bg;
- border: 5px solid @light_bg;
- border-color: @light_bg
+ background-color: @background_color;
+ border: 5px solid @background_color;
}
#LexikonBubble .lexikon_heading {
@@ -240,15 +205,15 @@
}
.QuickPreviewPopup {
- background-color: @light_bg;
+ background-color: @background_color;
}
.QuickPreviewPopup grid {
- background-color: @light_bg;
- color: @dark_bg;
- border-color: @light_bg;
+ background-color: @background_color;
+ color: @foreground_color;
+ border-color: @background_color;
}
.QuickPreviewPopup label {
- color: @dark_bg;
-}
+ color: @foreground_color;
+}
\ No newline at end of file
diff --git a/data/media/github-md.css b/data/media/css/_web_base.css
similarity index 83%
rename from data/media/github-md.css
rename to data/media/css/_web_base.css
index dde07c6..3dd9ecc 100644
--- a/data/media/github-md.css
+++ b/data/media/css/_web_base.css
@@ -1,45 +1,60 @@
@font-face {
font-family: fira-sans;
- src: url('fonts/fira-sans-v9-greek_latin-ext_latin_cyrillic-ext_cyrillic_greek-ext_vietnamese-regular.woff2') format('woff2');
+ src: url("../fonts/fira-sans-v9-vietnamese_latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2") format("woff2");
}
@font-face {
font-family: fira-mono;
- src: url('fonts/fira-mono-v7-greek_latin-ext_latin_cyrillic-ext_cyrillic_greek-ext-regular.woff2') format('woff2');
+ src: url("../fonts/fira-mono-v7-latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2") format("woff2");
}
@font-face {
- font-family: "color-emoji";
+ font-family: color-emoji;
src: local("Noto Color Emoji"), local("Apple Color Emoji"), local("Segoe UI Emoji"), local("Segoe UI Symbol");
}
:root {
- --text-color: #242424;
- --background-color: #f6f5f4;
- --alt-background-color: #ebebeb;
+ /* This is GitHub's default color scheme, which should be overridden per theme. */
+ --text-color: #24292e;
+ --background-color: #ffffff;
+ --alt-background-color: #f6f8fa;
--link-color: #0366d6;
- --blockquote-text-color: #606060;
- --blockquote-border-color: #d8d8d8;
- --header-border-color: #e2e2e2;
- --hr-background-color: #dadada;
- --hr-border-color: #e4e4e4;
- --code-background-color: #eeeeee;
- --table-td-border-color: #d8d8d8;
- --table-tr-border-color: #c1c1c1;
- --kbd-text-color: #444444;
- --kbd-background-color: #f2f2f2;
- --kbd-border-color: #c1c1c1;
- --kbd-shadow-color: #939393;
+ --blockquote-text-color: #6a737d;
+ --blockquote-border-color: #dfe2e5;
+ --header-border-color: #eaecef;
+ --hr-background-color: #e1e4e8;
+ --table-tr-border-color: #c6cbd1;
+ --table-td-border-color: #dfe2e5;
+ --kbd-text-color: #444d56;
+ --kbd-background-color: #fafbfc;
+ --kbd-border-color: #c6cbd1;
+ --kbd-shadow-color: #959da5;
}
* {
box-sizing: border-box;
}
+html {
+ font-size: 16px;
+}
+
+@media screen and (max-width: 799px) {
+ html {
+ font-size: 14px;
+ }
+}
+
+@media screen and (min-width: 1000px) {
+ html {
+ font-size: 18px;
+ }
+}
+
body {
color: var(--text-color);
background-color: var(--background-color);
- font-family: fira-sans, sans-serif, color-emoji;
+ font-family: "Fira Sans", fira-sans, sans-serif, color-emoji;
line-height: 1.5;
text-size-adjust: 100%;
word-wrap: break-word;
@@ -77,7 +92,6 @@ hr {
overflow: hidden;
background-color: var(--hr-background-color);
border: 0;
- border-bottom: 1px solid var(--hr-border-color);
}
hr::before {
@@ -183,8 +197,7 @@ dd {
code,
kbd,
pre {
- font-family: fira-mono, monospace, color-emoji;
- background-color: var(--code-background-color);
+ font-family: "Fira Mono", fira-mono, monospace, color-emoji;
font-size: 1em;
word-wrap: normal;
}
diff --git a/data/media/css/gtk_adwaita.css b/data/media/css/gtk_adwaita.css
new file mode 100644
index 0000000..f75dcde
--- /dev/null
+++ b/data/media/css/gtk_adwaita.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #2e3436;
+@define-color background_color #f6f5f4;
+@define-color math_text_color #00364c;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/gtk_adwaita_dark.css b/data/media/css/gtk_adwaita_dark.css
new file mode 100644
index 0000000..a41d20c
--- /dev/null
+++ b/data/media/css/gtk_adwaita_dark.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #eeeeec;
+@define-color background_color #353535;
+@define-color math_text_color #ffc9b3;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/gtk_arc.css b/data/media/css/gtk_arc.css
new file mode 100644
index 0000000..967c919
--- /dev/null
+++ b/data/media/css/gtk_arc.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #3b3e45;
+@define-color background_color #f5f6f7;
+@define-color math_text_color #00364c;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/gtk_arc_dark.css b/data/media/css/gtk_arc_dark.css
new file mode 100644
index 0000000..3edd842
--- /dev/null
+++ b/data/media/css/gtk_arc_dark.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #d3dae3;
+@define-color background_color #383c4a;
+@define-color math_text_color #ffc9b3;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/gtk_arc_darker.css b/data/media/css/gtk_arc_darker.css
new file mode 100644
index 0000000..44c667b
--- /dev/null
+++ b/data/media/css/gtk_arc_darker.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #3b3e45;
+@define-color background_color #f5f6f7;
+@define-color math_text_color #00364C;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/gtk_high_contrast.css b/data/media/css/gtk_high_contrast.css
new file mode 100644
index 0000000..254215e
--- /dev/null
+++ b/data/media/css/gtk_high_contrast.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #000000;
+@define-color background_color #ffffff;
+@define-color math_text_color #000000;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/gtk_high_contrast_inverse.css b/data/media/css/gtk_high_contrast_inverse.css
new file mode 100644
index 0000000..b9790d4
--- /dev/null
+++ b/data/media/css/gtk_high_contrast_inverse.css
@@ -0,0 +1,5 @@
+@define-color foreground_color #ffffff;
+@define-color background_color #000000;
+@define-color math_text_color #ffffff;
+
+@import url("_gtk_base.css");
diff --git a/data/media/css/web_adwaita.css b/data/media/css/web_adwaita.css
new file mode 100644
index 0000000..ecfde17
--- /dev/null
+++ b/data/media/css/web_adwaita.css
@@ -0,0 +1,19 @@
+@import url("_web_base.css");
+
+:root {
+ --text-color: #2e3436;
+ --background-color: #f6f5f4;
+ --alt-background-color: #edeeef;
+ --link-color: #0d71de;
+ --blockquote-text-color: #747e85;
+ --blockquote-border-color: #d6d8da;
+ --header-border-color: #e1e2e4;
+ --hr-background-color: #d8dadd;
+ --table-tr-border-color: #bdc1c6;
+ --table-td-border-color: #d6d8da;
+ --kbd-text-color: #4e585e;
+ --kbd-background-color: #f1f1f1;
+ --kbd-border-color: #bdc1c6;
+ --kbd-shadow-color: #8c939a;
+
+}
\ No newline at end of file
diff --git a/data/media/github-md-dark.css b/data/media/css/web_adwaita_dark.css
similarity index 62%
rename from data/media/github-md-dark.css
rename to data/media/css/web_adwaita_dark.css
index 928f3ca..320a657 100644
--- a/data/media/github-md-dark.css
+++ b/data/media/css/web_adwaita_dark.css
@@ -1,19 +1,17 @@
-@import url("github-md.css");
+@import url("_web_base.css");
:root {
- --text-color: #dbdbdb;
+ --text-color: #eeeeec;
--background-color: #353535;
--alt-background-color: #3a3a3a;
- --link-color: #4388d6;
- --blockquote-text-color: #959595;
+ --link-color: #b5daff;
+ --blockquote-text-color: #a8a8a6;
--blockquote-border-color: #525252;
--header-border-color: #474747;
--hr-background-color: #505050;
- --hr-border-color: #464646;
- --code-background-color: #3e3e3e;
- --table-td-border-color: #525252;
--table-tr-border-color: #696969;
- --kbd-text-color: #bbbbbb;
+ --table-td-border-color: #525252;
+ --kbd-text-color: #cececc;
--kbd-background-color: #3c3c3c;
--kbd-border-color: #696969;
--kbd-shadow-color: #979797;
diff --git a/data/media/css/web_arc.css b/data/media/css/web_arc.css
new file mode 100644
index 0000000..c5ccb04
--- /dev/null
+++ b/data/media/css/web_arc.css
@@ -0,0 +1,18 @@
+@import url("_web_base.css");
+
+:root {
+ --text-color: #3b3e45;
+ --background-color: #f5f6f7;
+ --alt-background-color: #eceff2;
+ --link-color: #1a7bed;
+ --blockquote-text-color: #818894;
+ --blockquote-border-color: #d5d9dd;
+ --header-border-color: #e0e3e7;
+ --hr-background-color: #d7dbe0;
+ --table-tr-border-color: #bcc2c9;
+ --table-td-border-color: #d5d9dd;
+ --kbd-text-color: #5b626d;
+ --kbd-background-color: #f0f2f4;
+ --kbd-border-color: #bcc2c9;
+ --kbd-shadow-color: #8b949d;
+}
\ No newline at end of file
diff --git a/data/media/css/web_arc_dark.css b/data/media/css/web_arc_dark.css
new file mode 100644
index 0000000..b0c6a45
--- /dev/null
+++ b/data/media/css/web_arc_dark.css
@@ -0,0 +1,18 @@
+@import url("_web_base.css");
+
+:root {
+ --text-color: #d3dae3;
+ --background-color: #383c4a;
+ --alt-background-color: #3d414f;
+ --link-color: #9ac6ff;
+ --blockquote-text-color: #8d949d;
+ --blockquote-border-color: #555967;
+ --header-border-color: #4a4e5c;
+ --hr-background-color: #535765;
+ --table-tr-border-color: #6c707e;
+ --table-td-border-color: #555967;
+ --kbd-text-color: #b3bac3;
+ --kbd-background-color: #3f4351;
+ --kbd-border-color: #6c707e;
+ --kbd-shadow-color: #9a9eac;
+}
\ No newline at end of file
diff --git a/data/media/css/web_arc_darker.css b/data/media/css/web_arc_darker.css
new file mode 100644
index 0000000..cc6a95e
--- /dev/null
+++ b/data/media/css/web_arc_darker.css
@@ -0,0 +1 @@
+@import url("web_arc.css");
\ No newline at end of file
diff --git a/data/media/css/web_high_contrast.css b/data/media/css/web_high_contrast.css
new file mode 100644
index 0000000..b9db89e
--- /dev/null
+++ b/data/media/css/web_high_contrast.css
@@ -0,0 +1,26 @@
+@import url("_web_base.css");
+
+a {
+ text-decoration: underline;
+}
+
+pre {
+ border: 1px solid;
+}
+
+:root {
+ --text-color: #000000;
+ --background-color: #ffffff;
+ --alt-background-color: #ffffff;
+ --link-color: #000000;
+ --blockquote-text-color: #000000;
+ --blockquote-border-color: #000000;
+ --header-border-color: #000000;
+ --hr-background-color: #000000;
+ --table-tr-border-color: #000000;
+ --table-td-border-color: #000000;
+ --kbd-text-color: #000000;
+ --kbd-background-color: #ffffff;
+ --kbd-border-color: #000000;
+ --kbd-shadow-color: #000000;
+}
\ No newline at end of file
diff --git a/data/media/css/web_high_contrast_inverse.css b/data/media/css/web_high_contrast_inverse.css
new file mode 100644
index 0000000..646e1f0
--- /dev/null
+++ b/data/media/css/web_high_contrast_inverse.css
@@ -0,0 +1,26 @@
+@import url("_web_base.css");
+
+a {
+ text-decoration: underline;
+}
+
+pre {
+ border: 1px solid;
+}
+
+:root {
+ --text-color: #ffffff;
+ --background-color: #000000;
+ --alt-background-color: #000000;
+ --link-color: #ffffff;
+ --blockquote-text-color: #ffffff;
+ --blockquote-border-color: #ffffff;
+ --header-border-color: #ffffff;
+ --hr-background-color: #ffffff;
+ --table-tr-border-color: #ffffff;
+ --table-td-border-color: #ffffff;
+ --kbd-text-color: #ffffff;
+ --kbd-background-color: #000000;
+ --kbd-border-color: #ffffff;
+ --kbd-shadow-color: #ffffff;
+}
\ No newline at end of file
diff --git a/data/media/fonts/fira-mono-v7-latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2 b/data/media/fonts/fira-mono-v7-latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2
new file mode 100644
index 0000000..7762d83
Binary files /dev/null and b/data/media/fonts/fira-mono-v7-latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2 differ
diff --git a/data/media/fonts/fira-sans-v9-vietnamese_latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2 b/data/media/fonts/fira-sans-v9-vietnamese_latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2
new file mode 100644
index 0000000..c648c80
Binary files /dev/null and b/data/media/fonts/fira-sans-v9-vietnamese_latin_cyrillic-ext_cyrillic_greek-ext_latin-ext_greek-regular.woff2 differ
diff --git a/data/media/uberwriter.css b/data/media/uberwriter.css
deleted file mode 100644
index 7cb0bd6..0000000
Binary files a/data/media/uberwriter.css and /dev/null differ
diff --git a/data/media/uberwriter_dark.css b/data/media/uberwriter_dark.css
deleted file mode 100644
index bae9e17..0000000
Binary files a/data/media/uberwriter_dark.css and /dev/null differ
diff --git a/scripts/color_palette_generator.py b/scripts/color_palette_generator.py
new file mode 100644
index 0000000..5a2f50f
--- /dev/null
+++ b/scripts/color_palette_generator.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python3
+#
+# Generates color palettes based on the specified background/foreground colors.
+#
+# Usage: python color_palette_generator.py #fg_hex #bg_hex light|dark
+#
+# The light variant is based on GitHub's style, while the dark variant is based on pre-existing UberWriter styles.
+#
+# Accessibility is not accounted for, so make sure to verify contrast: https://webaim.org/resources/contrastchecker/
+
+import operator
+import os
+import sys
+
+
+def hex_to_tuple(h):
+ return tuple(int(h.lstrip('#')[i:i + 2], 16) for i in (0, 2, 4))
+
+
+def tuple_to_hex(t):
+ (r, g, b) = t
+ if r < 0 or g < 0 or b < 0 or r > 255 or g > 255 or b > 255:
+ return '#%02x%02x%02x (clamped)' % tuple(map(lambda x: max(0, min(x, 255)), t))
+ else:
+ return '#%02x%02x%02x' % t
+
+
+def sub_tuples(t1, t2):
+ return tuple(map(operator.sub, t1, t2))
+
+
+if __name__ == '__main__':
+ if len(sys.argv) != 4:
+ print("Usage: {} foreground_color background_color light|dark\n" +
+ "Both colors must be in hexadecimal format, eg. #f6f5f4".format(os.path.basename(__file__)))
+ exit()
+
+ target_foreground_color = hex_to_tuple(sys.argv[1])
+ target_background_color = hex_to_tuple(sys.argv[2])
+ dark = sys.argv[3] == "dark"
+
+ gh_text_color = hex_to_tuple("#dbdbdb" if dark else "#24292e")
+ gh_background_color = hex_to_tuple("#353535" if dark else "#ffffff")
+ gh_alt_background_color = hex_to_tuple("#3a3a3a" if dark else "#f6f8fa")
+ gh_link_color = hex_to_tuple("#a2c7f8" if dark else "#0366d6")
+ gh_blockquote_text_color = hex_to_tuple("#959595" if dark else "#6a737d")
+ gh_blockquote_border_color = hex_to_tuple("#525252" if dark else "#dfe2e5")
+ gh_header_border_color = hex_to_tuple("#474747" if dark else "#eaecef")
+ gh_hr_background_color = hex_to_tuple("#505050" if dark else "#e1e4e8")
+ gh_table_tr_border_color = hex_to_tuple("#696969" if dark else "#c6cbd1")
+ gh_table_td_border_color = hex_to_tuple("#525252" if dark else "#dfe2e5")
+ gh_kbd_text_color = hex_to_tuple("#bbbbbb" if dark else "#444d56")
+ gh_kbd_background_color = hex_to_tuple("#3c3c3c" if dark else "#fafbfc")
+ gh_kbd_border_color = hex_to_tuple("#696969" if dark else "#c6cbd1")
+ gh_kbd_shadow_color = hex_to_tuple("#979797" if dark else "#959da5")
+
+ text_color_diff = sub_tuples(gh_text_color, target_foreground_color)
+ background_color_diff = sub_tuples(gh_background_color, target_background_color)
+
+ text_color = tuple_to_hex(target_foreground_color)
+ background_color = tuple_to_hex(target_background_color)
+ alt_background_color = tuple_to_hex(sub_tuples(gh_alt_background_color, background_color_diff))
+ link_color = tuple_to_hex(sub_tuples(gh_link_color, text_color_diff))
+ blockquote_text_color = tuple_to_hex(sub_tuples(gh_blockquote_text_color, text_color_diff))
+ blockquote_border_color = tuple_to_hex(sub_tuples(gh_blockquote_border_color, background_color_diff))
+ header_border_color = tuple_to_hex(sub_tuples(gh_header_border_color, background_color_diff))
+ hr_background_color = tuple_to_hex(sub_tuples(gh_hr_background_color, background_color_diff))
+ table_tr_border_color = tuple_to_hex(sub_tuples(gh_table_tr_border_color, background_color_diff))
+ table_td_border_color = tuple_to_hex(sub_tuples(gh_table_td_border_color, background_color_diff))
+ kbd_text_color = tuple_to_hex(sub_tuples(gh_kbd_text_color, text_color_diff))
+ kbd_background_color = tuple_to_hex(sub_tuples(gh_kbd_background_color, background_color_diff))
+ kbd_border_color = tuple_to_hex(sub_tuples(gh_kbd_border_color, background_color_diff))
+ kbd_shadow_color = tuple_to_hex(sub_tuples(gh_kbd_shadow_color, background_color_diff))
+
+ print(("--text-color: {};\n" +
+ "--background-color: {};\n" +
+ "--alt-background-color: {};\n" +
+ "--link-color: {};\n" +
+ "--blockquote-text-color: {};\n" +
+ "--blockquote-border-color: {};\n" +
+ "--header-border-color: {};\n" +
+ "--hr-background-color: {};\n" +
+ "--table-tr-border-color: {};\n" +
+ "--table-td-border-color: {};\n" +
+ "--kbd-text-color: {};\n" +
+ "--kbd-background-color: {};\n" +
+ "--kbd-border-color: {};\n" +
+ "--kbd-shadow-color: {};\n").format(
+ text_color,
+ background_color,
+ alt_background_color,
+ link_color,
+ blockquote_text_color,
+ blockquote_border_color,
+ header_border_color,
+ hr_background_color,
+ table_tr_border_color,
+ table_td_border_color,
+ kbd_text_color,
+ kbd_background_color,
+ kbd_border_color,
+ kbd_shadow_color))
diff --git a/uberwriter/MarkupBuffer.py b/uberwriter/MarkupBuffer.py
index bbc762c..c413482 100644
--- a/uberwriter/MarkupBuffer.py
+++ b/uberwriter/MarkupBuffer.py
@@ -16,6 +16,7 @@
import re
import gi
+
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Pango
@@ -46,14 +47,10 @@ class MarkupBuffer():
self.normal_indent = self.text_buffer.create_tag('normal_indent', indent=100)
- self.green_text = self.text_buffer.create_tag("greentext",
- foreground="#00364C")
+ self.math_text = self.text_buffer.create_tag('math_text')
- self.grayfont = self.text_buffer.create_tag('graytag',
- foreground="gray")
-
- self.blackfont = self.text_buffer.create_tag('blacktag',
- foreground="#222")
+ self.unfocused_text = self.text_buffer.create_tag('graytag',
+ foreground="gray")
self.underline = self.text_buffer.create_tag("underline",
underline=Pango.Underline.SINGLE)
@@ -101,7 +98,8 @@ class MarkupBuffer():
self.table_env.set_property('pixels-above-lines', 0)
self.table_env.set_property('pixels-below-lines', 0)
- # self.ftag = self.TextBuffer.create_tag("pix_front", pixels_above_lines = 100)
+ self.update_style()
+
regex = {
"ITALIC": re.compile(r"(\*|_)(.*?)\1", re.UNICODE), # *asdasd* // _asdasd asd asd_
"STRONG": re.compile(r"(\*\*|__)(.*?)\1", re.UNICODE), # **as das** // __asdasd asd ad a__
@@ -120,6 +118,13 @@ class MarkupBuffer():
"LINK": re.compile(r"\(http(.+?)\)")
}
+ def update_style(self):
+ (found, color) = self.parent.get_style_context().lookup_color('math_text_color')
+ if not found:
+ (_, color) = self.parent.get_style_context().lookup_color('foreground_color')
+
+ self.math_text.set_property("foreground", color.to_string())
+
def markup_buffer(self, mode=0):
buf = self.text_buffer
@@ -178,13 +183,13 @@ class MarkupBuffer():
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.strikethrough, start_iter, end_iter)
- self.text_buffer.remove_tag(self.green_text, context_start, context_end)
+ self.text_buffer.remove_tag(self.math_text, context_start, context_end)
matches = re.finditer(self.regex["MATH"], text)
for match in matches:
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
- self.text_buffer.apply_tag(self.green_text, start_iter, end_iter)
+ self.text_buffer.apply_tag(self.math_text, start_iter, end_iter)
for margin in self.rev_leftmargin:
self.text_buffer.remove_tag(margin, context_start, context_end)
@@ -266,15 +271,13 @@ class MarkupBuffer():
self.focusmode_highlight()
def focusmode_highlight(self):
- self.text_buffer.apply_tag(
- self.grayfont,
- self.text_buffer.get_start_iter(),
- self.text_buffer.get_end_iter())
+ start_document = self.text_buffer.get_start_iter()
+ end_document = self.text_buffer.get_end_iter()
self.text_buffer.remove_tag(
- self.blackfont,
- self.text_buffer.get_start_iter(),
- self.text_buffer.get_end_iter())
+ self.unfocused_text,
+ start_document,
+ end_document)
cursor = self.text_buffer.get_mark("insert")
cursor_iter = self.text_buffer.get_iter_at_mark(cursor)
@@ -293,9 +296,14 @@ class MarkupBuffer():
start_sentence = cursor_iter.copy()
start_sentence.backward_sentence_start()
+ # grey out everything before
self.text_buffer.apply_tag(
- self.blackfont,
- start_sentence, end_sentence)
+ self.unfocused_text,
+ self.text_buffer.get_start_iter(), start_sentence)
+
+ self.text_buffer.apply_tag(
+ self.unfocused_text,
+ end_sentence, self.text_buffer.get_end_iter())
def set_multiplier(self, multiplier):
self.multiplier = multiplier
@@ -311,13 +319,3 @@ class MarkupBuffer():
new_margin = (lm - multiplier) + multiplier + multiplier * (i + 1)
self.leftmargin[i].set_property("left-margin", 0 if new_margin < 0 else new_margin)
self.leftmargin[i].set_property("indent", - (multiplier - 1) * (i + 1) - multiplier)
-
- def dark_mode(self, active=False):
- if active:
- self.green_text.set_property("foreground", "#FA5B0F")
- self.grayfont.set_property("foreground", "#666")
- self.blackfont.set_property("foreground", "#CCC")
- else:
- self.green_text.set_property("foreground", "#00364C")
- self.grayfont.set_property("foreground", "gray")
- self.blackfont.set_property("foreground", "#222")
diff --git a/uberwriter/Theme.py b/uberwriter/Theme.py
new file mode 100644
index 0000000..cd408bc
--- /dev/null
+++ b/uberwriter/Theme.py
@@ -0,0 +1,61 @@
+from gi.repository import Gtk
+
+from uberwriter.Settings import Settings
+from uberwriter_lib.helpers import get_css_path
+
+
+class Theme:
+ """
+ The Theme enum lists all supported themes using their "gtk-theme-name" value.
+
+ The light variant is listed first, followed by the dark variant, if any.
+ """
+
+ settings = Settings.new()
+
+ def __init__(self, name, gtk_css_path, web_css_path, is_dark, inverse_name):
+ self.name = name
+ self.gtk_css_path = gtk_css_path
+ self.web_css_path = web_css_path
+ self.is_dark = is_dark
+ self.inverse_name = inverse_name
+
+ @classmethod
+ def get_for_name(cls, name, default=None):
+ current_theme = default or defaultThemes[0]
+ for theme in defaultThemes:
+ if name == theme.name:
+ current_theme = theme
+ return current_theme
+
+ @classmethod
+ def get_current(cls):
+ theme_name = Gtk.Settings.get_default().get_property('gtk-theme-name')
+ dark_mode = cls.settings.get_value('dark-mode').get_boolean()
+ current_theme = cls.get_for_name(theme_name)
+ # Technically, we could very easily allow the user to force the light ui on a dark theme.
+ # However, as there is no inverse of "gtk-application-prefer-dark-theme", we shouldn't do that.
+ if dark_mode and not current_theme.is_dark and current_theme.inverse_name:
+ current_theme = cls.get_for_name(current_theme.inverse_name, current_theme.name)
+ return current_theme
+
+
+defaultThemes = [
+ # https://gitlab.gnome.org/GNOME/gtk/tree/master/gtk/theme/Adwaita
+ Theme('Adwaita', get_css_path('gtk_adwaita.css'),
+ get_css_path('web_adwaita.css'), False, 'Adwaita-dark'),
+ Theme('Adwaita-dark', get_css_path('gtk_adwaita_dark.css'),
+ get_css_path('web_adwaita_dark.css'), True, 'Adwaita'),
+ # https://github.com/NicoHood/arc-theme/tree/master/common/gtk-3.0/3.20/sass
+ Theme('Arc', get_css_path('gtk_arc.css'),
+ get_css_path('web_arc.css'), False, 'Arc-Dark'),
+ Theme('Arc-Darker', get_css_path('gtk_arc_darker.css'),
+ get_css_path('web_arc_darker.css'), False, 'Arc-Dark'),
+ Theme('Arc-Dark', get_css_path('gtk_arc_dark.css'),
+ get_css_path('web_arc_dark.css'), True, 'Arc'),
+ # https://gitlab.gnome.org/GNOME/gtk/tree/master/gtk/theme/HighContrast
+ Theme('HighContrast', get_css_path('gtk_high_contrast.css'),
+ get_css_path('web_high_contrast.css'), False, 'HighContrastInverse'),
+ Theme('HighContrastInverse', get_css_path('gtk_high_contrast_inverse.css'),
+ get_css_path('web_high_contrast_inverse.css'), True, 'HighContrast'),
+]
diff --git a/uberwriter/UberwriterExportDialog.py b/uberwriter/UberwriterExportDialog.py
index ec6ad8b..167329a 100644
--- a/uberwriter/UberwriterExportDialog.py
+++ b/uberwriter/UberwriterExportDialog.py
@@ -24,6 +24,9 @@ import logging
from gettext import gettext as _
import gi
+
+from uberwriter.Theme import Theme
+
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
@@ -215,7 +218,7 @@ class Export:
args.append("-o%s.odt" % basename)
elif export_format == "html":
- css = helpers.get_media_file('github-md.css')
+ css = Theme.ADWAITA.get_gtk_css_file()
relativize = helpers.get_script_path('relative_to_absolute.lua')
task_list = helpers.get_script_path('task-list.lua')
args.append("-c%s" % css)
diff --git a/uberwriter/UberwriterWindow.py b/uberwriter/UberwriterWindow.py
index c51f828..f3c4429 100644
--- a/uberwriter/UberwriterWindow.py
+++ b/uberwriter/UberwriterWindow.py
@@ -14,20 +14,22 @@
# with this program. If not, see .
# END LICENSE
-import locale
-import subprocess
-import os
import codecs
-import webbrowser
-import urllib
+import locale
import logging
-
import mimetypes
+import os
import re
-
+import subprocess
+import urllib
+import webbrowser
from gettext import gettext as _
import gi
+from gi.repository.GObject import param_spec_string
+
+from uberwriter.Theme import Theme
+
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit2', '4.0') # pylint: disable=wrong-import-position
from gi.repository import Gtk, Gdk, GObject, GLib, Gio
@@ -181,21 +183,13 @@ class UberwriterWindow(Gtk.ApplicationWindow):
# Init file name with None
self.set_filename()
- # self.style_provider = Gtk.CssProvider()
- # self.style_provider.load_from_path(helpers.get_media_path('arc_style.css'))
-
- # Gtk.StyleContext.add_provider_for_screen(
- # Gdk.Screen.get_default(), self.style_provider,
- # Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
- # )
-
# Markup and Shortcuts for the TextBuffer
self.markup_buffer = MarkupBuffer(
self, self.text_buffer, base_leftmargin)
self.markup_buffer.markup_buffer()
- # Setup dark mode if so
- self.toggle_dark_mode(self.settings.get_value("dark-mode"))
+ # Set current theme
+ self.apply_current_theme()
# Scrolling -> Dark or not?
self.textchange = False
@@ -266,6 +260,18 @@ class UberwriterWindow(Gtk.ApplicationWindow):
'close-window': (GObject.SIGNAL_ACTION, None, ())
}
+ def apply_current_theme(self):
+ """Adjusts both the window and the CSD for the current theme.
+ """
+
+ self.markup_buffer.update_style()
+
+ # Reload preview if it exists, otherwise redraw contents of window (self)
+ if self.preview_webview:
+ self.show_preview()
+ else:
+ self.queue_draw()
+
def scrolled(self, widget):
"""if window scrolled + focusmode make font black again"""
# if self.focusmode:
@@ -387,7 +393,7 @@ class UberwriterWindow(Gtk.ApplicationWindow):
else:
self.remove_typewriter()
self.focusmode = False
- self.text_buffer.remove_tag(self.markup_buffer.grayfont,
+ self.text_buffer.remove_tag(self.markup_buffer.unfocused_text,
self.text_buffer.get_start_iter(),
self.text_buffer.get_end_iter())
self.text_buffer.remove_tag(self.markup_buffer.blackfont,
@@ -487,8 +493,8 @@ class UberwriterWindow(Gtk.ApplicationWindow):
self.window_height = widget.get_allocation().height
w_width = widget.get_allocation().width
# Calculate left / right margin
- width_request = 600
if w_width < 900:
+ width_request = 600
self.markup_buffer.set_multiplier(8)
self.current_font_size = 12
self.alignment_padding = 30
@@ -498,8 +504,8 @@ class UberwriterWindow(Gtk.ApplicationWindow):
self.get_style_context().add_class("small")
elif w_width < 1400:
- self.markup_buffer.set_multiplier(10)
width_request = 800
+ self.markup_buffer.set_multiplier(10)
self.current_font_size = 15
self.alignment_padding = 40
lm = 7 * 10
@@ -508,9 +514,9 @@ class UberwriterWindow(Gtk.ApplicationWindow):
self.get_style_context().add_class("medium")
else:
+ width_request = 1000
self.markup_buffer.set_multiplier(13)
self.current_font_size = 17
- width_request = 1000
self.alignment_padding = 60
lm = 7 * 13
self.get_style_context().remove_class("medium")
@@ -865,20 +871,13 @@ class UberwriterWindow(Gtk.ApplicationWindow):
base_path = ''
os.environ['PANDOC_PREFIX'] = base_path + '/'
- # Set the styles according the color theme
- if self.settings.get_value("dark-mode"):
- stylesheet = helpers.get_media_path('github-md-dark.css')
- else:
- stylesheet = helpers.get_media_path('github-md.css')
-
args = ['pandoc',
'-s',
'--from=markdown',
'--to=html5',
'--mathjax',
- '--css=' + stylesheet,
- '--lua-filter=' +
- helpers.get_script_path('relative_to_absolute.lua'),
+ '--css=' + Theme.get_current().web_css_path,
+ '--lua-filter=' + helpers.get_script_path('relative_to_absolute.lua'),
'--lua-filter=' + helpers.get_script_path('task-list.lua')]
proc = subprocess.Popen(
@@ -906,32 +905,6 @@ class UberwriterWindow(Gtk.ApplicationWindow):
self.preview_webview.load_html(output.decode("utf-8"), 'file://localhost/')
- def toggle_dark_mode(self, state):
- """Toggle the dark mode, both for the window and for the CSD
-
- Arguments:
- state {gtk bool} -- Desired state of the dark mode (enabled/disabled)
- """
-
- # Save state for saving settings later
- if state:
- # Dark Mode is on
- self.get_style_context().add_class("dark_mode")
- self.headerbar.hb_container.get_style_context().add_class("dark_mode")
- self.markup_buffer.dark_mode(True)
- else:
- # Dark mode off
- self.get_style_context().remove_class("dark_mode")
- self.headerbar.hb_container.get_style_context().remove_class("dark_mode")
- self.markup_buffer.dark_mode(False)
-
- # Reload preview if it exists
- if self.preview_webview:
- self.show_preview()
-
- # Redraw contents of window (self)
- self.queue_draw()
-
def load_file(self, filename=None):
"""Open File from command line or open / open recent etc."""
if self.check_change() == Gtk.ResponseType.CANCEL:
diff --git a/uberwriter_lib/AppWindow.py b/uberwriter_lib/AppWindow.py
index d25161a..3e446ae 100644
--- a/uberwriter_lib/AppWindow.py
+++ b/uberwriter_lib/AppWindow.py
@@ -16,13 +16,14 @@ from gettext import gettext as _
import gi
+from uberwriter.Theme import Theme
+
gi.require_version('Gtk', '3.0') # pylint: disable=wrong-import-position
from gi.repository import GLib, Gio, Gtk, Gdk, GdkPixbuf
from uberwriter import UberwriterWindow
from uberwriter.Settings import Settings
from uberwriter_lib import set_up_logging
-from uberwriter_lib import helpers
from uberwriter_lib.PreferencesDialog import PreferencesDialog
from . helpers import get_builder, get_media_path
@@ -36,30 +37,6 @@ class Application(Gtk.Application):
self.window = None
self.settings = Settings.new()
- def init(self):
- """Init main application"""
-
- # set theme variant (dark/light)
- dark = self.settings.get_value("dark-mode")
- Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", dark)
-
- # set css for current theme
- self.style_provider = Gtk.CssProvider()
-
- themes = {
- "Arc": "arc_style.css",
- "Arc-Dark": "arc_style.css",
- "Arc-Darker": "arc_style.css",
- }
-
- theme = Gtk.Settings.get_default().get_property("gtk-theme-name")
- self.style_provider.load_from_path(helpers.get_media_path(themes.get(theme,"adwaita_style.css")))
-
- Gtk.StyleContext.add_provider_for_screen(
- Gdk.Screen.get_default(), self.style_provider,
- Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
- )
-
def do_startup(self, *args, **kwargs):
Gtk.Application.do_startup(self)
@@ -176,7 +153,7 @@ class Application(Gtk.Application):
self.set_accels_for_action("app.save", ["s"])
self.set_accels_for_action("app.save_as", ["s"])
- self.init()
+ self.apply_current_theme()
def do_activate(self, *args, **kwargs):
# We only allow a single window and raise any existing ones
@@ -209,6 +186,23 @@ class Application(Gtk.Application):
self.activate()
return 0
+ def apply_current_theme(self):
+ # get current theme
+ theme = Theme.get_current()
+
+ # set theme variant (dark/light)
+ Gtk.Settings.get_default().set_property(
+ "gtk-application-prefer-dark-theme",
+ GLib.Variant("b", theme.is_dark))
+
+ # set theme css
+ style_provider = Gtk.CssProvider()
+ style_provider.load_from_path(theme.gtk_css_path)
+ Gtk.StyleContext.add_provider_for_screen(
+ Gdk.Screen.get_default(), style_provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
+ )
+
def on_about(self, _action, _param):
builder = get_builder('About')
about_dialog = builder.get_object("AboutDialog")
@@ -234,14 +228,13 @@ class Application(Gtk.Application):
def on_dark_mode(self, action, value):
action.set_state(value)
- self.settings.set_value("dark-mode",
- GLib.Variant("b", value))
- self.window.toggle_dark_mode(value)
+ self.settings.set_value("dark-mode", GLib.Variant("b", value))
# this changes the headerbar theme accordingly
- self.dark_setting = Gtk.Settings.get_default()
- self.dark_setting.set_property(
- "gtk-application-prefer-dark-theme", value)
+ self.apply_current_theme()
+
+ # adjust window for theme
+ self.window.apply_current_theme()
def on_focus_mode(self, action, value):
action.set_state(value)
diff --git a/uberwriter_lib/helpers.py b/uberwriter_lib/helpers.py
index f46bf52..ec682ee 100644
--- a/uberwriter_lib/helpers.py
+++ b/uberwriter_lib/helpers.py
@@ -49,16 +49,12 @@ def get_builder(builder_file_name):
# Owais Lone : To get quick access to icons and stuff.
-def get_media_file(media_file_name):
+def get_media_file(media_file_path):
"""Return the full path of a given filename under the media dir
(starts with file:///)
"""
- media_filename = get_data_file('media', '%s' % (media_file_name,))
- if not os.path.exists(media_filename):
- media_filename = None
-
- return "file:///" + media_filename
+ return "file:///" + get_media_path(media_file_path)
def get_media_path(media_file_name):
@@ -66,19 +62,26 @@ def get_media_path(media_file_name):
(doesn't start with file:///)
"""
- media_filename = get_data_file('media', '%s' % (media_file_name,))
- if not os.path.exists(media_filename):
- media_filename = None
- return media_filename
+ media_path = get_data_file('media', '%s' % (media_file_name,))
+ if not os.path.exists(media_path):
+ media_path = None
+ return media_path
+
+
+def get_css_path(css_file_name):
+ """Return the full path of a given filename under the css dir
+ (doesn't start with file:///)
+ """
+ return get_media_path("css/{}".format(css_file_name))
def get_script_path(script_file_name):
"""Return the full path of a given filename under the script dir
"""
- script_filename = get_data_file('lua', '%s' % (script_file_name,))
- if not os.path.exists(script_filename):
- script_filename = None
- return script_filename
+ script_path = get_data_file('lua', '%s' % (script_file_name,))
+ if not os.path.exists(script_path):
+ script_path = None
+ return script_path
class NullHandler(logging.Handler):