From 65a40ec1799eceff1170b20c3bf362642ea53dc7 Mon Sep 17 00:00:00 2001 From: Maxime Jacquemin <maxime.jacquemin@cea.fr> Date: Wed, 16 Feb 2022 18:38:42 +0100 Subject: [PATCH] [ivette] Dark mode for Ivette There is some stuff to do to polish everything but it starts to look good. --- ivette/src/colors/dark-code.css | 54 ++++++ ivette/src/colors/dark.css | 67 +++++++ ivette/src/colors/light.css | 67 +++++++ ivette/src/dome/main/dome.ts | 7 + ivette/src/dome/renderer/controls/style.css | 130 +++++++++----- ivette/src/dome/renderer/frame/style.css | 189 ++++++++++++++------ ivette/src/dome/renderer/frame/toolbars.tsx | 25 +++ ivette/src/dome/renderer/layout/style.css | 32 ++-- ivette/src/dome/renderer/style.css | 48 +++-- ivette/src/dome/renderer/table/style.css | 14 +- ivette/src/dome/renderer/text/style.css | 9 +- ivette/src/frama-c/kernel/ASTview.tsx | 1 - ivette/src/frama-c/kernel/SourceCode.tsx | 1 - ivette/src/frama-c/kernel/style.css | 10 +- ivette/src/frama-c/plugins/eva/style.css | 72 ++++++-- ivette/src/frama-c/plugins/eva/summary.css | 5 +- ivette/src/ivette/prefs.tsx | 27 ++- ivette/src/renderer/Application.tsx | 15 ++ ivette/src/renderer/index.js | 2 + ivette/src/renderer/style.css | 14 +- 20 files changed, 592 insertions(+), 197 deletions(-) create mode 100644 ivette/src/colors/dark-code.css create mode 100644 ivette/src/colors/dark.css create mode 100644 ivette/src/colors/light.css diff --git a/ivette/src/colors/dark-code.css b/ivette/src/colors/dark-code.css new file mode 100644 index 00000000000..18608ad9b8a --- /dev/null +++ b/ivette/src/colors/dark-code.css @@ -0,0 +1,54 @@ +.cm-s-dark-code.CodeMirror, .cm-s-dark-code .CodeMirror-gutters { + background-color: #1e2b3d; + color: var(--text-discrete); +} + +.cm-s-dark-code .CodeMirror-gutters { + background: #1e2b3d; + border-right: 0px; +} + +.cm-s-dark-code .CodeMirror-linenumber { + color: var(--disabled-text); +} + +.cm-s-dark-code .CodeMirror-cursor { + border-left: 1px solid var(--text); +} + +.cm-s-dark-code.cm-fat-cursor .CodeMirror-cursor { + background-color: #8e8d8875 !important; +} + +.cm-s-dark-code .cm-animate-fat-cursor { + background-color: #8e8d8875 !important; +} + + +.cm-s-dark-code div.CodeMirror-selected { + background: var(--info-text-discrete); +} + +.cm-s-dark-code span.cm-meta { color: #83a598; } + +.cm-s-dark-code span.cm-comment { color: var(--info-text); } +.cm-s-dark-code span.cm-number, span.cm-atom { color: #d3869b; } +.cm-s-dark-code span.cm-keyword { color: #d84954; } + +.cm-s-dark-code span.cm-variable { color: var(--text); } +.cm-s-dark-code span.cm-variable-2 { color: var(--text); } +.cm-s-dark-code span.cm-variable-3, .cm-s-dark-code span.cm-type { color: #bacd5f; } +.cm-s-dark-code span.cm-operator { color: var(--text); } +.cm-s-dark-code span.cm-callee { color: var(--text); } +.cm-s-dark-code span.cm-def { color: var(--text); } +.cm-s-dark-code span.cm-property { color: var(--text); } +.cm-s-dark-code span.cm-string { color: #93669b; } +.cm-s-dark-code span.cm-string-2 { color: #8ec07c; } +.cm-s-dark-code span.cm-qualifier { color: #8ec07c; } +.cm-s-dark-code span.cm-attribute { color: #8ec07c; } + +.cm-s-dark-code .CodeMirror-activeline-background { background: var(--background); } +.cm-s-dark-code .CodeMirror-matchingbracket { background: #928374; color:#282828 !important; } + +.cm-s-dark-code span.cm-builtin { color: #fe8039; } +.cm-s-dark-code span.cm-tag { color: #fe8039; } diff --git a/ivette/src/colors/dark.css b/ivette/src/colors/dark.css new file mode 100644 index 00000000000..23bec700da6 --- /dev/null +++ b/ivette/src/colors/dark.css @@ -0,0 +1,67 @@ +@media (prefers-color-scheme: dark) { + :root { + --text: #b4cacd; + --text-discrete: #879da0; + --disabled-text: #506679; + --info-text: #748a8d; + --info-text-discrete: #778d90; + + --code-hover: #005137; + --code-select: #4f3d24; + --code-select-hover: #5f4d34; + --dead-code: #bbb; + --non-terminating: #bbb; + --highlighted-marker: #ffff66; + --code-bullet: #0a2234; + + --splitter: #708294; + --border: #031b2d; + --border-discrete: #2a4254; + + --background: #2c394b; + --background-profound: #082032; + --background-profound-hover: #0e2638; + --background-disabled: #525f71; + --background-disabled-hover: #4c596b; + --background-intense: #132b3d; + --background-softer: #364455; + --background-sidebar: #183042; + --background-button-hover: #c0c0c0; + --background-alterning-odd: #354154; + --background-alterning-even: #475366; + --selected-element: #082032; + + --default-button-img: linear-gradient(to bottom, #3c495b 0%, #455164 100%); + --default-button-hover: #364355; + --default-button-active: #303d4f; + + --primary-button-img: linear-gradient(to bottom, #146bbf 0%, #1960b2 100%); + --primary-button-hover: #0e65b9; + --primary-button-active: #085fb3; + + --positive-button-img: linear-gradient(to bottom, #327024 0%, #2e6c20 100%); + --positive-button-hover: #28661a; + --positive-button-active: #226014; + + --negative-button-img: linear-gradient(to bottom, #bc150e 0%, #cf1c17 100%); + --negative-button-hover: #b60f08; + --negative-button-active: #b00903; + + --warning-button-img: linear-gradient(to bottom, #a4601a 0%, #a6571c 100%); + --warning-button-hover: #9e5114; + --warning-button-active: #984b0e; + + --cancel-button-img: #082032; + --cancel-button-hover: #0e2638; + --cancel-button-active: #041c2e; + + --selected-button-img: #355174; + --selected-button-hover: #456184; + + --grid-layout-holder: #266475; + --grid-layout-target: #34b4c0; + + --error: darkorange; + --warning: darkorange; + } +} diff --git a/ivette/src/colors/light.css b/ivette/src/colors/light.css new file mode 100644 index 00000000000..eeb4402facd --- /dev/null +++ b/ivette/src/colors/light.css @@ -0,0 +1,67 @@ +@media (prefers-color-scheme: light) { + :root { + --text: #333333; + --text-discrete: #606060; + --disabled-text: #b0b0b0; + --info-text: #777; + --info-text-discrete: #888; + + --code-hover: lightgreen; + --code-select: #ffda95; + --code-select-hover: orange; + --dead-code: #bbb; + --non-terminating: #bbb; + --highlighted-marker: #ffff66; + --code-bullet: #ddd; + + --splitter: #aaa; + --border: #afafaf; + --border-discrete: #d0d0d0; + + --background: #e6e6e6; + --background-profound: #c0c0c0; + --background-profound-hover: #c6c6c6; + --background-disabled: #a0a0a0; + --background-disabled-hover: #a6a6a6; + --background-intense: #e0e0e0; + --background-softer: #f0f0f0; + --background-sidebar: #e3e8ec; + --background-button-hover: #c0c0c0; + --background-alterning-odd: #fdfdfd; + --background-alterning-even: #efefef; + --selected-element: #8ce0fb; + + --default-button-img: linear-gradient(to bottom, #e8e8e8 0%, #f1f1f1 100%); + --default-button-hover: #ffffff; + --default-button-active: #f9f9f9; + + --primary-button-img: linear-gradient(to bottom, #449bef 0%, #4990e2 100%); + --primary-button-hover: #00b6ff; + --primary-button-active: #ddd; + + --positive-button-img: linear-gradient(to bottom, #34ff52 0%, #48fd64 100%); + --positive-button-hover: #ffffff; + --positive-button-active: #ffffff; + + --negative-button-img: linear-gradient(to bottom, #ec453e 0%, #ff4c47 100%); + --negative-button-hover: red; + --negative-button-active: #ffffff; + + --warning-button-img: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%); + --warning-button-hover: orange; + --warning-button-active: #ffffff; + + --cancel-button-img: #c0c0c0; + --cancel-button-hover: #c4c4c4; + --cancel-button-active: #bcbcbc; + + --selected-button-img: #afafaf; + --selected-button-hover: #a9a9a9; + + --grid-layout-holder: lightblue; + --grid-layout-target: #64b4f0; + + --error: darkorange; + --warning: darkorange; + } +} diff --git a/ivette/src/dome/main/dome.ts b/ivette/src/dome/main/dome.ts index 3ef9fdc5adb..5595324886e 100644 --- a/ivette/src/dome/main/dome.ts +++ b/ivette/src/dome/main/dome.ts @@ -49,6 +49,7 @@ import { IpcMainEvent, shell, dialog, + nativeTheme, } from 'electron'; import installExtension, { REACT_DEVELOPER_TOOLS } from 'dome/devtools'; import SYS, * as System from 'dome/system'; @@ -619,3 +620,9 @@ ipcMain.handle( ); // -------------------------------------------------------------------------- + +ipcMain.handle('theme-color:switch', (_, theme: 'dark' | 'light') => { + // const theme = nativeTheme.shouldUseDarkColors ? 'light' : 'dark'; + nativeTheme.themeSource = theme; + // return nativeTheme.shouldUseDarkColors; +}); diff --git a/ivette/src/dome/renderer/controls/style.css b/ivette/src/dome/renderer/controls/style.css index b98f47eef0c..e479237743a 100644 --- a/ivette/src/dome/renderer/controls/style.css +++ b/ivette/src/dome/renderer/controls/style.css @@ -48,8 +48,7 @@ background: #777 ; } -.dome-disabled .dome-xBadge -{ +.dome-disabled .dome-xBadge { background: #ccc ; color: #eee ; fill: #eee ; @@ -64,7 +63,6 @@ /* -------------------------------------------------------------------------- */ .dome-control-enabled { - color: #333 ; font-weight: normal ; } @@ -83,9 +81,11 @@ } /* -------------------------------------------------------------------------- */ -/* --- Styling Buttons --- */ +/* --- Styling Buttons (may be factorized with xToolBar) --- */ /* -------------------------------------------------------------------------- */ +/* Layout */ + .dome-xButton { flex: 0 0 auto ; align-self: baseline ; @@ -110,80 +110,130 @@ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06); } -.dome-xButton:disabled, -.dome-xButton:active:disabled -{ - fill: #b0b0b0 ; - border-color: #ccc ; - background-color: #f4f4f4 ; +/* Disabled */ + +.dome-xButton:disabled, .dome-xButton:active:disabled { + fill: var(--disabled-text); + color: var(--disabled-text); + border-color: var(--border-discrete) ; background-image: none; } -.dome-xButton:active { - background-color: #ddd; +/* Selected */ + +.dome-xButton-selected { + fill: var(--info-text); + color: var(--info-text); + border: 1px solid transparent ; + background-color: var(--selected-button-img); background-image: none; } -.dome-xButton-default { - border-color: #c2c0c2 ; - background-color: #f4f4f4 ; +.dome-xButton-selected:hover:not(:disabled) { + background-color: var(--selected-button-hover) ; + background-image: none ; } -.dome-xButton-default:hover:not(:disabled) { - background-color: #fff ; +/* Selected & Disabled */ + +.dome-xButton-selected:disabled { + fill: var(--info-text) ; + color: var(--info-text) ; + border: 1px solid var(--border-discrete) ; } -.dome-xButton-selected { - border-color: #c2c0c2 ; - background-color: #ccc ; +/* Default button behaviors */ + +.dome-xButton-default:not(:disabled) { + color: var(--text); + border-color: var(--border); + background-image: var(--default-button-img); } -.dome-xButton-selected:hover:not(:disabled) { - background-color: #fff ; +.dome-xButton-default:hover:not(:disabled) { + background-color: var(--default-button-hover); + background-image: none; +} + +.dome-xButton-default:active:not(:disabled) { + background-color: var(--default-button-active); + background-image: none; } -.dome-xButton-primary { - border-color: #888; - background-image: linear-gradient(to bottom, #449bef 0%, #4990e2 100%); +/* Primary button behaviors */ + +.dome-xButton-primary:not(:disabled) { + color: var(--text); + border-color: var(--border); + background-image: var(--primary-button-img); } .dome-xButton-primary:hover:not(:disabled) { - background-color: #00b6ff ; + background-color: var(--primary-button-hover); background-image: none ; } -.dome-xButton-positive { - border-color: #888; - background-image: linear-gradient(to bottom, #60f577 0%, #3efb5b 100%); +.dome-xButton-primary:active:not(:disabled) { + background-color: var(--primary-button-active); + background-image: none; +} + +/* Positive button behaviors */ + +.dome-xButton-positive:not(:disabled) { + color: var(--text); + border-color: var(--border); + background-image: var(--positive-button-img); } .dome-xButton-positive:hover:not(:disabled) { - background-color: #00ff00 ; + background-color: var(--positive-button-hover); background-image: none ; } -.dome-xButton-negative { - border-color: #888; - fill: #333; - color: #333 ; - background-image: linear-gradient(to bottom, #ff827d 0%, #fb3832 100%); +.dome-xButton-positive:active:not(:disabled) { + background-color: var(--positive-button-active); + background-image: none; +} + +/* Negative button behaviors */ + +.dome-xButton-negative:not(:disabled) { + color: var(--text); + border-color: var(--border); + background-image: var(--negative-button-img); } .dome-xButton-negative:hover:not(:disabled) { - background-color: #ff0000 ; + background-color: var(--negative-button-hover); background-image: none ; } -.dome-xButton-warning { - border-color: #888; - background-image: linear-gradient(to bottom, #ffd483 0%, #ffb426 100%); +.dome-xButton-negative:active:not(:disabled) { + background-color: var(--negative-button-active); + background-image: none; +} + +/* Warning button behaviors */ + +.dome-xButton-warning:not(:disabled) { + color: var(--text); + border-color: var(--border); + background-image: var(--warning-button-img); } .dome-xButton-warning:hover:not(:disabled) { - background-color: #ecdd09 ; + background-color: var(--warning-button-hover); background-image: none ; } +.dome-xButton-warning:active:not(:disabled) { + background-color: var(--warning-button-active); + background-image: none; +} + +/* Buttons' labels */ + .dome-xButton-label { position: relative ; padding: 2px ; diff --git a/ivette/src/dome/renderer/frame/style.css b/ivette/src/dome/renderer/frame/style.css index e00b12bc98c..91dddd918b6 100644 --- a/ivette/src/dome/renderer/frame/style.css +++ b/ivette/src/dome/renderer/frame/style.css @@ -39,13 +39,13 @@ } .dome-xTab.dome-inactive:hover { - background: #bababa ; + background: var(--background-disabled-hover) ; } .dome-xTab.dome-inactive { - color: #606060 ; - border-color: #9c9c9c ; - background: #b4b4b4 ; + color: var(--text-discrete) ; + border-color: var(--border) ; + background: var(--background-disabled) ; } /* Closing Tab button */ @@ -72,16 +72,11 @@ left: initial ; } -.dome-active .dome-xTab-closing:hover { - background: #c0c0c0 ; +.dome-xTab-closing:hover { + background: var(--background-button-hover); } -.dome-inactive .dome-xTab-closing:hover { - background: #a0a0a0 ; -} - -.dome-xTab:hover .dome-xTab-closing , .dome-xTab:hover .dome-xTab-closing -{ +.dome-xTab:hover .dome-xTab-closing { opacity: 1 ; } @@ -100,7 +95,7 @@ .dome-xSideBar.dome-color-frame, .dome-xSideBarSection-title.dome-color-frame { - background: #e3e8ec ; + background: var(--background-sidebar) ; } /* -------------------------------------------------------------------------- */ @@ -138,7 +133,7 @@ .dome-xSideBarSection-hideshow { flex: 0 0 ; margin: 1px ; - color: #aaa ; + color: var(--info-text) ; width: 32px ; font-weight: normal ; display: inline ; @@ -168,7 +163,7 @@ } .dome-xSideBarItem.dome-active { - background: #ccc ; + background: var(--background-profound) ; } .dome-xSideBarItem > .dome-xLabel { @@ -179,8 +174,8 @@ } .dome-xSideBarItem.dome-disabled > .dome-xLabel { - color: #b0b0b0 ; - fill: #b0b0b0 ; + color: var(--disabled-text) ; + fill: var(--disabled-text) ; } .dome-xSideBarItem > .dome-xLabel:last-child { @@ -202,7 +197,7 @@ display: flex ; flex-direction: row ; flex-wrap: wrap ; - align-items: baseline ; + align-items: center ; border-width: 1px ; border-bottom-style: solid ; } @@ -245,7 +240,7 @@ } .dome-xToolBar-vrule { - background: #aaa ; + background: var(--splitter) ; } /* -------------------------------------------------------------------------- */ @@ -274,95 +269,118 @@ margin-left: 4px ; } -/* Background */ +/* Default button behaviors */ .dome-xToolBar-control { - background-image: linear-gradient(to bottom, #e8e8e8 0, #f1f1f1 100%); - border-color: #bbb; + background-image: var(--default-button-img); + color: var(--text); + border-color: var(--border); } .dome-xToolBar-control:hover:not(:disabled) { - background-color: #ffffff ; + background-color: var(--default-button-hover); background-image: none ; } +.dome-xToolBar-control:active:not(:disabled) { + background-color: var(--default-button-active); + background-image: none; +} + +/* Positive button behaviors */ + .dome-xToolBar-control.dome-xToolBar-positive:not(:disabled) { - background-image: linear-gradient(to bottom, #34ff52 0%, #48fd64 100%); + background-image: var(--positive-button-img); } .dome-xToolBar-control.dome-xToolBar-positive:hover:not(:disabled) { - background-color: #00ff00 ; + background-color: var(--positive-button-hover); background-image: none ; } +.dome-xToolBar-control.dome-xToolBar-positive:active:not(:disabled) { + background-color: var(--positive-button-active); + background-image: none; +} + +/* Negative button behaviors */ + .dome-xToolBar-control.dome-xToolBar-negative:not(:disabled) { - color: #ccc ; - fill: #ccc ; - background-image: linear-gradient(to bottom, #ec453e 0%, #ff4c47 100%); + background-image: var(--negative-button-img); } .dome-xToolBar-control.dome-xToolBar-negative:hover:not(:disabled) { - background-color: red ; + background-color: var(--negative-button-hover); background-image: none ; } +.dome-xToolBar-control.dome-xToolBar-negative:active:not(:disabled) { + background-color: var(--negative-button-active); + background-image: none; +} + +/* Warning button behaviors */ + .dome-xToolBar-control.dome-xToolBar-warning:not(:disabled) { - background-image: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%); + background-image: var(--warning-button-img); } .dome-xToolBar-control.dome-xToolBar-warning:hover:not(:disabled) { - background-color: orange ; + background-color: var(--warning-button-hover); background-image: none ; } +.dome-xToolBar-control.dome-xToolBar-warning:active:not(:disabled) { + background-color: var(--warning-button-active); + background-image: none; +} + +/* Cancel button behaviors */ + .dome-xToolBar-control.dome-xToolBar-cancel:not(:disabled) { - background-color: #c2c0c2 ; + background-color: var(--cancel-button-img); background-image: none ; } .dome-xToolBar-control.dome-xToolBar-cancel:hover:not(:disabled) { - background-image: linear-gradient(to bottom, #e8e8e8 0, #f1f1f1 100%); + background-image: var(--cancel-button-hover); } -/* Activated */ - -.dome-xToolBar-control:active:not(:disabled) { - fill: #ddd ; - color: #ddd ; - background-color: gray ; - background-image: none ; +.dome-xToolBar-control.dome-xToolBar-cancel:active:not(:disabled) { + background-color: var(--cancel-button-active); + background-image: none; } /* Disabled */ .dome-xToolBar-control:disabled { - fill: #ccc ; - color: #ccc ; + fill: var(--disabled-text) ; + color: var(--disabled-text) ; box-shadow: none ; + border-color: var(--border-discrete) ; } /* Selected */ .dome-xToolBar-control.dome-selected { - fill: #fff; - color: #fff; + fill: var(--info-text); + color: var(--info-text); border: 1px solid transparent ; - background-color: #7f7f7f ; + background-color: var(--selected-button-img) ; background-image: none ; } .dome-xToolBar-control.dome-selected:hover { - background-color: #888 ; + background-color: var(--selected-button-hover) ; background-image: none ; } /* Selected & Disabled */ .dome-xToolBar-control.dome-selected:disabled { - fill: #ccc ; - color: #ccc ; - border: 1px solid #bbb ; - background-color: #ddd ; + fill: var(--info-text) ; + color: var(--info-text) ; + border: 1px solid var(--border-discrete) ; } /* -------------------------------------------------------------------------- */ @@ -408,12 +426,11 @@ .dome-xToolBar-control.dome-xToolBar-searchfield { background-image: none ; - background-color: #eee ; - margin-top: 1px ; - padding-top: 1px ; + background-color: var(--background-alterning-odd); padding-left: 20px ; border-radius: 12px ; - border-color: #aaa ; + border-color: var(--border); + color: var(--text); width: 32px ; transition: width 0.4s ease-in-out ; } @@ -431,7 +448,7 @@ z-Index: +1; height: 0px; width: 0px; - top: 2px ; + top: -7px ; left: 12px ; } @@ -444,8 +461,8 @@ left: -7px ; top: 4px ; padding: 0px ; - border: 1pt solid #aaa ; - background: #fff ; + border: 1pt solid var(--border) ; + background: var(--background-alterning-odd) ; } .dome-xToolBar-searchitem { @@ -460,11 +477,65 @@ .dome-xToolBar-searchitem:hover, .dome-xToolBar-searchindex { - background: lightblue !important; + background: var(--selected-element) !important; } .dome-xToolBar-searchitem:nth-child(even) { - background: #eef7f7; + background: var(--background-alterning-even); } /* -------------------------------------------------------------------------- */ + +.dome-xSwitch { + position: relative; + display: inline-block; + width: 34px; + height: 21px; +} + +.dome-xSwitch input { + opacite: 0; + width: 0; + height: 0; +} + +.dome-xSwitch-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: var(--background-softer); + box-shadow: 0 0 1px var(--border); + -webkit-transition: .4s; + transition: .4s; + border-radius: 21px; +} + +.dome-xSwitch-slider:before { + position: absolute; + content: ""; + height: 15px; + width: 15px; + left: 3px; + bottom: 3px; + background-color: var(--text-discrete); + -webkit-transition: .4s; + transition: .4s; + border-radius: 50%; +} + +/* input:checked + .dome-xSwitch-slider { */ +/* background-color: #2196F3; */ +/* } */ + +/* input:focus + .dome-xSwitch-slider { */ +/* box-shadow: 0 0 1px #2196F3; */ +/* } */ + +input:checked + .dome-xSwitch-slider:before { + -webkit-transform: translateX(13px); + -ms-transform: translateX(13px); + transform: translateX(13px); +} diff --git a/ivette/src/dome/renderer/frame/toolbars.tsx b/ivette/src/dome/renderer/frame/toolbars.tsx index ab7614418d2..21f8419bb57 100644 --- a/ivette/src/dome/renderer/frame/toolbars.tsx +++ b/ivette/src/dome/renderer/frame/toolbars.tsx @@ -149,6 +149,31 @@ export function Button<A = undefined>(props: ButtonProps<A>) { ); } +export interface SwitchProps { + /** Switch tooltip. */ + title?: string; + /** Switch position. */ + position?: 'left' | 'right'; + /** Click callback. */ + onClick?: () => void; +} + +/** Toolbar Switch. */ +export function Switch(props: SwitchProps) { + const { title = '', onClick = () => {}, position } = props; + const checked = position ? position === 'right' : undefined; + return ( + <label className={'dome-xSwitch'}> + <input type={'checkbox'} checked={checked}/> + <span + className={'dome-xSwitch-slider'} + title={title} + onClick={onClick} + /> + </label> + ); +} + // -------------------------------------------------------------------------- // --- Selection Props // -------------------------------------------------------------------------- diff --git a/ivette/src/dome/renderer/layout/style.css b/ivette/src/dome/renderer/layout/style.css index e90f9f94263..9e5f921a78f 100644 --- a/ivette/src/dome/renderer/layout/style.css +++ b/ivette/src/dome/renderer/layout/style.css @@ -35,6 +35,8 @@ /* --- Extensibility --- */ /* -------------------------------------------------------------------------- */ +/* TODO: Find why it does not work on my computer */ + .dome-xBoxes-pack { flex: 0 0 auto ; @@ -57,6 +59,16 @@ overflow: auto ; } +.dome-xBoxes-scroll::-webkit-scrollbar-track { + background: orange; +} + +.dome-xBoxes-scroll::-webkit-scrollbar-thumb { + background-color: blue; + border-radius: 20px; + border: 3px solid orange; +} + .dome-container > .dome-xBoxes-fill { width: 100% ; @@ -188,7 +200,7 @@ .dome-xSplitter-hline, .dome-xSplitter-vline { - background: #afafaf ; + background: var(--splitter) ; } /* -------------------------------------------------------------------------- */ @@ -217,7 +229,7 @@ z-index: 2 ; position: absolute ; border-radius: 12px ; - background: #64b4f0 ; + background: var(--grid-layout-target) ; opacity: 0.5 ; } @@ -225,7 +237,7 @@ z-index: -1 ; position: absolute ; overflow: hidden ; - background: lightblue ; + background: var(--grid-layout-holder) ; opacity: 0.5 ; } @@ -307,7 +319,7 @@ } .dome-xForm-section .dome-disabled { - color: #aaa ; + color: var(--background-disabled) ; } .dome-xForm-hsep @@ -321,7 +333,7 @@ { position: absolute ; top: 2px ; - fill: #888 ; + fill: var(--info-text-discrete) ; left: -14px ; } @@ -344,7 +356,7 @@ .dome-xForm-label.dome-disabled, .dome-xForm-field.dome-disabled { - color: #aaa ; + color: var(--background-disabled) ; opacity: 0.9 ; } @@ -357,7 +369,7 @@ { position: absolute ; top: -1px ; - fill: darkorange ; + fill: var(--error) ; margin-left: 6px ; } @@ -368,7 +380,7 @@ position: absolute ; top: 3px ; width: max-content ; - color: darkorange ; + color: var(--warning) ; margin-left: 4px ; font-size: smaller ; } @@ -395,7 +407,7 @@ .dome-xForm-textarea-field { - border-color: #d6d6d6 ; + border-color: var(--border-discrete) ; font-size: 10pt ; padding-top: 2px ; padding-bottom: 2px ; @@ -429,7 +441,7 @@ .dome-xForm-units { - color: #888 ; + color: var(--info-text-discrete) ; font-size: smaller ; margin-left: 4px ; } diff --git a/ivette/src/dome/renderer/style.css b/ivette/src/dome/renderer/style.css index ad13efbfe64..fb44e3a9de7 100644 --- a/ivette/src/dome/renderer/style.css +++ b/ivette/src/dome/renderer/style.css @@ -3,28 +3,28 @@ /* -------------------------------------------------------------------------- */ * { - user-select: none; - box-sizing: border-box; - margin: 0 ; - padding: 0 ; - } + user-select: none; + box-sizing: border-box; + margin: 0 ; + padding: 0 ; +} body { - overflow: hidden ; - position: fixed ; - font-family: sans-serif ; - font-size: 13px ; - color: #333333 ; - background: #f0f0f0 ; - top: 0 ; - bottom: 0 ; - left: 0 ; - right: 0 ; + color: var(--text); + background: var(--background-softer); + overflow: hidden ; + position: fixed ; + font-family: sans-serif ; + font-size: 13px ; + top: 0 ; + bottom: 0 ; + left: 0 ; + right: 0 ; } #app { - width: 100% ; - height: 100% ; + width: 100% ; + height: 100% ; } /* -------------------------------------------------------------------------- */ @@ -40,16 +40,10 @@ body { } .dome-color-frame { - fill: #606060 ; - color: #606060 ; - border-color: #afafaf ; - background: #d8d8d8 ; -} - -.dome-color-selected { - border-color: #e8e8e8 ; - background: #ff9504 ; - color: #ffffff ; + fill: var(--text-discrete) ; + color: var(--text-discrete) ; + border-color: var(--border) ; + background: var(--background-intense) ; } .dome-color-dragzone { diff --git a/ivette/src/dome/renderer/table/style.css b/ivette/src/dome/renderer/table/style.css index 23c95182929..4b632757b3d 100644 --- a/ivette/src/dome/renderer/table/style.css +++ b/ivette/src/dome/renderer/table/style.css @@ -19,9 +19,9 @@ .dome-xTable .ReactVirtualized__Table__headerRow { display: flex ; align-items: stretch ; - background: #eee ; - color: #555 ; - fill: #777 ; + background: var(--background-intense) ; + color: var(--text-discrete) ; + fill: var(--info-text) ; } .dome-xTable .ReactVirtualized__Table__headerColumn { @@ -29,7 +29,7 @@ padding-left: 4px ; padding-right: 4px ; margin: 0px ; /* Necessary for column alignement */ - border-color: #cfcfcf ; + border-color: var(--border-discrete) ; border-bottom-width: 1px ; border-bottom-style: solid ; } @@ -101,15 +101,15 @@ } .dome-xTable-selected { - background: #8ce0fb ; + background: var(--selected-element) ; } .dome-xTable-odd { - background: #fdfdfd ; + background: var(--background-alterning-odd) ; } .dome-xTable-even { - background: #efefef ; + background: var(--background-alterning-even) ; } .ReactVirtualized__Table__row.dome-color-selected { diff --git a/ivette/src/dome/renderer/text/style.css b/ivette/src/dome/renderer/text/style.css index 425a00b769c..3dd0c7e07f4 100644 --- a/ivette/src/dome/renderer/text/style.css +++ b/ivette/src/dome/renderer/text/style.css @@ -17,15 +17,15 @@ } .dome-xText-hover { - background: lightgreen ; + background: var(--code-hover) ; } .dome-xText-select { - background: #ffda95 !important ; + background: var(--code-select) !important ; } .dome-xText-select.dome-xText-hover { - background: orange !important ; + background: var(--code-select-hover) !important ; } /* -------------------------------------------------------------------------- */ @@ -33,7 +33,6 @@ /* -------------------------------------------------------------------------- */ .dome-xPages-note { - background: white ; padding: 2px ; } @@ -48,9 +47,7 @@ height: calc(100% - 16px) ; margin: 8px ; padding: 8px ; - background: white ; border-radius: 2px ; - box-shadow: 2px 2px 6px 3px lightgray ; overflow: auto ; } diff --git a/ivette/src/frama-c/kernel/ASTview.tsx b/ivette/src/frama-c/kernel/ASTview.tsx index d0a75469a82..cebfda57c71 100644 --- a/ivette/src/frama-c/kernel/ASTview.tsx +++ b/ivette/src/frama-c/kernel/ASTview.tsx @@ -167,7 +167,6 @@ export default function ASTview() { const { buttons: themeButtons, theme, fontSize, wrapText } = Preferences.useThemeButtons({ target: 'Internal AST', - theme: Preferences.AstTheme, fontSize: Preferences.AstFontSize, wrapText: Preferences.AstWrapText, disabled: !theFunction, diff --git a/ivette/src/frama-c/kernel/SourceCode.tsx b/ivette/src/frama-c/kernel/SourceCode.tsx index 89a2dfcddcf..882765aa55c 100644 --- a/ivette/src/frama-c/kernel/SourceCode.tsx +++ b/ivette/src/frama-c/kernel/SourceCode.tsx @@ -83,7 +83,6 @@ export default function SourceCode(): JSX.Element { const { buttons: themeButtons, theme, fontSize, wrapText } = Preferences.useThemeButtons({ target: 'Source Code', - theme: Preferences.SourceTheme, fontSize: Preferences.SourceFontSize, wrapText: Preferences.AstWrapText, disabled: !theFunction, diff --git a/ivette/src/frama-c/kernel/style.css b/ivette/src/frama-c/kernel/style.css index 29500873890..5b0bbdd6e43 100644 --- a/ivette/src/frama-c/kernel/style.css +++ b/ivette/src/frama-c/kernel/style.css @@ -14,21 +14,21 @@ /* -------------------------------------------------------------------------- */ .highlighted-marker { - background-color: #FFFF66; + background-color: var(--highlighted-marker); } .dead-code { - background-color: #BBB; - border-bottom: solid 0.1em #BBB; + background-color: var(--dead-code); + border-bottom: solid 0.1em var(--dead-code); } .non-terminating { - border-bottom: solid 0.2em #BBB; + border-bottom: solid 0.2em var(--non-terminating); } .bullet { width: 1.5em; - background: #DDD; + background: var(--code-bullet); } /* -------------------------------------------------------------------------- */ diff --git a/ivette/src/frama-c/plugins/eva/style.css b/ivette/src/frama-c/plugins/eva/style.css index ff501a38023..9acaed1f721 100644 --- a/ivette/src/frama-c/plugins/eva/style.css +++ b/ivette/src/frama-c/plugins/eva/style.css @@ -2,13 +2,55 @@ /* --- Probe Panel --- */ /* -------------------------------------------------------------------------- */ +.light-theme { + + --eva-info-text: #777; + --eva-info-background: #ccc; + + --eva-stmt-label: grey; + --eva-code-background: lightgrey; + + --eva-callsite-background: #eee; + --eva-callsite-fill: #7cacbb; + + --eva-focused: #cbe4cb; + --eva-focused-transient: #f9dca6; + + --eva-state-before: #95f5ff; + --eva-state-after: #fff819; + --eva-state-then: #c8e06e; + --eva-state-else: #ff834e; + +} + +.dark-theme { + + --eva-info-text: #748a8d; + --eva-info-background: #082032; + + --eva-stmt-label: #849a9d; + --eva-code-background: #334756; + + --eva-callsite-background: #eee; + --eva-callsite-fill: #7cacbb; + + --eva-focused: #cbe4cb; + --eva-focused-transient: #f9dca6; + + --eva-state-before: #95f5ff; + --eva-state-after: #fff819; + --eva-state-then: #c8e06e; + --eva-state-else: #ff834e; + +} + .eva-probeinfo { min-height: 32px; padding-left: 6px; padding-top: 2px; padding-bottom: 4px; width: 100%; - background: #ccc; + background: var(--eva-info-background); display: flex; } @@ -21,7 +63,7 @@ .eva-probeinfo-code { flex: 0 1 auto; height: fit-content; - background: lightgrey; + background: var(--eva-code-background); min-width: 120px; width: auto; border: thin solid black; @@ -56,7 +98,7 @@ .eva-info { width: 100%; flex-wrap: wrap; - background: #ccc; + background: var(--eva-info-background); padding-top: 3px; padding-left: 12px; padding-bottom: 2px; @@ -64,19 +106,19 @@ .eva-callsite { flex: 0 0 auto; - fill: #7cacbb; - background: #eee; + fill: var(--eva-callsite-fill); + background: var(--eva-callsite-background); border-radius: 4px; border: thin solid black; padding-right: 7px; } .eva-callsite.eva-focused { - background: #cbe4cb; + background: var(--eva-focused); } .eva-callsite.eva-focused.eva-transient { - background: #f9dca6; + background: var(--eva-focused-transient); } /* -------------------------------------------------------------------------- */ @@ -107,7 +149,7 @@ /* -------------------------------------------------------------------------- */ .eva-stmt { - color: grey; + color: var(--eva-stmt-label); text-select: none; } @@ -135,12 +177,12 @@ .eva-function { padding-top: 0px; - background: #ccc; + background: var(--eva-info-background); } .eva-head { padding-top: 2px; - color: #777; + color: var(--eva-info-text); text-align: center; border-left: thin solid black; border-bottom: thin solid black; @@ -220,11 +262,11 @@ .eva-diff-added { } .eva-diff-removed { text-decoration: strike } -.eva-state-Before .eva-diff { background: #95f5ff; } -.eva-state-After .eva-diff { background: #fff819; } -.eva-state-Cond .eva-diff { background: #95f5ff; } -.eva-state-Then .eva-diff { background: #c8e06e; } -.eva-state-Else .eva-diff { background: #ff834e; } +.eva-state-Before .eva-diff { background: var(--eva-state-before); } +.eva-state-After .eva-diff { background: var(--eva-state-after); } +.eva-state-Cond .eva-diff { background: var(--eva-state-before); } +.eva-state-Then .eva-diff { background: var(--eva-state-then); } +.eva-state-Else .eva-diff { background: var(--eva-state-else); } /* -------------------------------------------------------------------------- */ /* --- Table Rows Background --- */ diff --git a/ivette/src/frama-c/plugins/eva/summary.css b/ivette/src/frama-c/plugins/eva/summary.css index 41de1d07440..8802dac6c4d 100644 --- a/ivette/src/frama-c/plugins/eva/summary.css +++ b/ivette/src/frama-c/plugins/eva/summary.css @@ -8,7 +8,6 @@ } .eva-summary-box { - background-color: white; height: 100%; width: 100%; display: flex; @@ -74,7 +73,7 @@ } .eva-summary .alarms-table tr:nth-child(2n) { - background-color: #eee; + background-color: var(--background-alterning-even); } .eva-summary .alarms-table td:nth-child(1) { @@ -86,7 +85,7 @@ } .eva-summary .statuses-table tr :nth-child(5) { - background-color: #ddd; + background-color: var(--background-intense); } .eva-summary td { diff --git a/ivette/src/ivette/prefs.tsx b/ivette/src/ivette/prefs.tsx index 3e887a07834..a23c25351b9 100644 --- a/ivette/src/ivette/prefs.tsx +++ b/ivette/src/ivette/prefs.tsx @@ -33,13 +33,12 @@ import React from 'react'; -import { popupMenu } from 'dome'; +// import { popupMenu } from 'dome'; import * as Settings from 'dome/data/settings'; import { IconButton } from 'dome/controls/buttons'; import 'codemirror/mode/clike/clike'; -import 'codemirror/theme/ambiance.css'; -import 'codemirror/theme/solarized.css'; +import '../colors/dark-code.css'; export const THEMES = [ { id: 'default', label: 'Default' }, @@ -52,6 +51,7 @@ export const THEMES = [ // --- AST View Preferences // -------------------------------------------------------------------------- +export const ColorTheme = new Settings.GString('color-theme', 'light'); export const AstTheme = new Settings.GString('ASTview.theme', 'default'); export const AstFontSize = new Settings.GNumber('ASTview.fontSize', 12); export const AstWrapText = new Settings.GFalse('ASTview.wrapText'); @@ -62,7 +62,6 @@ export const SourceWrapText = new Settings.GFalse('SourceCode.wrapText'); export interface ThemeProps { target: string; - theme: Settings.GlobalSettings<string>; fontSize: Settings.GlobalSettings<number>; wrapText: Settings.GlobalSettings<boolean>; disabled?: boolean; @@ -80,17 +79,13 @@ export interface ThemeControls { } export function useThemeButtons(props: ThemeProps): ThemeControls { - const [theme, setTheme] = Settings.useGlobalSettings(props.theme); + const [themeColors] = Settings.useGlobalSettings(ColorTheme); + const theme = themeColors === 'dark' ? 'dark-code' : 'default'; const [fontSize, setFontSize] = Settings.useGlobalSettings(props.fontSize); const [wrapText, setWrapText] = Settings.useGlobalSettings(props.wrapText); const zoomIn = () => fontSize < 48 && setFontSize(fontSize + 2); const zoomOut = () => fontSize > 4 && setFontSize(fontSize - 2); const flipWrapText = () => setWrapText(!wrapText); - const selectTheme = (id?: string) => id && setTheme(id); - const themeItem = (th: { id: string; label: string }) => ( - { checked: th.id === theme, ...th } - ); - const themePopup = () => popupMenu(THEMES.map(themeItem), selectTheme); const { disabled = false } = props; return { theme, @@ -111,12 +106,12 @@ export function useThemeButtons(props: ThemeProps): ThemeControls { disabled={disabled} title="Increase font size" />, - <IconButton - key="theme" - icon="PAINTBRUSH" - onClick={themePopup} - title="Choose theme" - />, + // <IconButton + // key="theme" + // icon="PAINTBRUSH" + // onClick={themePopup} + // title="Choose theme" + // />, <IconButton key="wrap" icon="WRAPTEXT" diff --git a/ivette/src/renderer/Application.tsx b/ivette/src/renderer/Application.tsx index 0717096732c..598b24836db 100644 --- a/ivette/src/renderer/Application.tsx +++ b/ivette/src/renderer/Application.tsx @@ -35,7 +35,10 @@ import * as Sidebar from 'dome/frame/sidebars'; import * as Controller from './Controller'; import * as Extensions from './Extensions'; import * as Laboratory from './Laboratory'; +import { ipcRenderer } from 'electron'; +import * as Settings from 'dome/data/settings'; import './loader'; +import * as Preferences from 'ivette/prefs'; // -------------------------------------------------------------------------- // --- Main View @@ -51,6 +54,13 @@ export default function Application(): JSX.Element { if (hints.length === 1) Extensions.onSearchHint(hints[0]); }; + const [ th, setTh ] = Settings.useGlobalSettings(Preferences.ColorTheme); + const change = (t: string) => ipcRenderer.invoke('theme-color:switch', t); + React.useState(() => change(th)); + const other = th === 'dark' ? 'light' : 'dark'; + const themeTitle = 'Switch to ' + other + ' theme'; + const changeColorTheme = () => { change(other); setTh(other); }; + return ( <Vfill> <Toolbar.ToolBar> @@ -70,6 +80,11 @@ export default function Application(): JSX.Element { onHint={Extensions.onSearchHint} onSelect={onSelectedHints} /> + <Toolbar.Switch + title={themeTitle} + position={th === 'dark' ? 'right' : 'left'} + onClick={changeColorTheme} + /> <Toolbar.Button icon="ITEMS.GRID" title="Customize Main View" diff --git a/ivette/src/renderer/index.js b/ivette/src/renderer/index.js index b7fa5b20332..d65ee906500 100644 --- a/ivette/src/renderer/index.js +++ b/ivette/src/renderer/index.js @@ -46,6 +46,8 @@ import { isApplicationWindow, isPreferencesWindow, } from 'dome' ; +import '../colors/light.css'; +import '../colors/dark.css'; // You can change the name of the main components, // provided you define the makefile variable diff --git a/ivette/src/renderer/style.css b/ivette/src/renderer/style.css index 298e1b2d81b..a13fab9c371 100644 --- a/ivette/src/renderer/style.css +++ b/ivette/src/renderer/style.css @@ -10,7 +10,7 @@ } .component-info { - color: #555 ; + color: var(--text) ; min-width: 50px; padding-top: 4px; font-size: smaller; @@ -26,7 +26,7 @@ } .labview-stock:hover { - background: #ccc ; + background: var(--background-profound); } .labview-stock:hover * { @@ -36,19 +36,19 @@ .labview-stock.dome-dragging { border-radius: 4px ; - background: #ccc ; + background: var(--background-profound); border: thin solid black ; } .labview-content { - background: #e6e6e6 ; + background: var(--background); } .labview-titlebar { - background: #ccc ; - height: 24px ; + background: var(--background-profound); + height: 24px } .labview-handle @@ -63,7 +63,7 @@ } .labview-icon { - fill: #7d7d7d ; + fill: var(--info-text); } /* -------------------------------------------------------------------------- */ -- GitLab