gnome-shell-dark-theme/gnome-shell-sass/_drawing.scss
2024-09-19 20:40:52 -04:00

472 lines
15 KiB
SCSS

//
// Drawing functions
//
// Function to convert px values to em
@function to_em($input, $base: 16px) {
// multiplied and divided by 1000 to make up for round() shortcoming
$em_value: ($input / $base) * 1.091 * 1000;
@return round($em_value) / 1000 * 1em;
}
// Boost the contrast of a color by mixing it with high contrast defined colors
@function hc_color_mix($c, $mc:$hc_mix_color, $mf:$hc_mix_factor) {
//
// $c: input color
// $mc: mix color, defined in High Contrast specific stylesheet
// $mf: mix factor (%), defined in High Contrast specific stylesheet
//
@return st-mix($c, $mc, $mf);
}
// Function to mix the color and make the focus background
@function focus_bg_color($bg, $fc:$focus_color) {
@return st-mix($fc, $bg, 5%);
}
//
// Drawing mixins
//
// Draw the inset for High Contrast elements
@mixin draw_hc_inset($width: 1px, $ic: $hc_inset_color, $border: false, $no_inset: false) {
//
// $width width of the inset, in pixels
// $ic color of the inset
//
// $border if true, use a border instead of a box-shadow to draw inset
// $no_inset if true, override the mixin to not draw an iset
//
box-shadow: inset 0 0 0 $width $ic;
// draw inset as border
@if $border {
border: $width solid $ic;
box-shadow: none;
}
// don't draw an inset at all
@if $no_inset {
box-shadow: none;
border: none;
}
}
// Draw the focus ring
@mixin focus_ring($width: 2px, $fc: $focus_border_color, $border: false) {
box-shadow: inset 0 0 0 $width $fc !important;
@if $border {
border:$width solid $fc !important;
box-shadow: none;
}
}
// Mixin to convert provided font size in pt to em units
@mixin fontsize($size, $base: 16px, $unit: pt) {
// if pt, convert into unitless value with the assumption: 1pt = 1.091px
$adjusted_size: if($unit == pt, $size * 1.091, $size) * 1000;
$rounded_size: round($adjusted_size / $base) / 1000;
font-size: $rounded_size * 1em;
// font-size: round($size) + pt;
}
// Function to fill the background of a panel button
@mixin panel_button_fill($bg) {
// use a box-shadow to fill the background
// this is done because panel buttons use a transparent border to fake padding
box-shadow: inset 0 0 0 100px $bg;
}
// Text entries drawing function
@mixin entry($type, $c:$fg_color, $bc:$bg_color, $style: null, $always_dark: false) {
//
// $type: entry type, possible values: normal, focus, hover, insensitive
// $c: text color
// $bc: background color
// $always_dark: override the light theme check to use dark colors, true or false
//
// entry colors
$entry_fg_color: $c;
$entry_bg_color: mix($c, $bc, $background_mix_factor);
$entry_focus_color: $focus_color;
// entry color overrides for lockscreen style
@if $style == 'lockscreen' {
$entry_bg_color: transparentize($c, .9);
$entry_focus_color: transparentize($entry_fg_color, 0.6);
@if $contrast == 'high' {
$entry_focus_color: transparentize($entry_fg_color, 0.3);
}
}
// background color adjustment factors
// the % a color is lightened or darkened for button states
$hover_factor: 4%;
$insensitive_factor: 3%;
// entry state background colors
$hover_entry_bg_color: if($variant == 'light', darken($entry_bg_color, $hover_factor), lighten($entry_bg_color, $hover_factor));
$insensitive_entry_bg_color: if($variant == 'light', lighten($entry_bg_color, $insensitive_factor), darken($entry_bg_color, $insensitive_factor));
// override entry background colours if element is always dark
@if $always_dark {
$hover_entry_bg_color: lighten($entry_bg_color, $hover_factor);
$insensitive_entry_bg_color: darken($entry_bg_color, $insensitive_factor);
}
@if $contrast == 'high' {
@include draw_hc_inset();
}
// normal
@if $type == 'normal' {
background-color: $entry_bg_color;
color: transparentize($c, 0.3);
}
// focus styles
@if $type == 'focus' {
@include focus_ring();
background-color: focus_bg_color($entry_bg_color);
color: $entry_fg_color;
// lockscreen style
@if $style == 'lockscreen' {
@include focus_ring($fc:$entry_focus_color);
background-color: focus_bg_color($entry_bg_color, $fc:$entry_focus_color);
}
}
// hover styles
@if $type == 'hover' {
background-color: $hover_entry_bg_color;
color: $entry_fg_color;
}
// insensitive styles
@if $type == 'insensitive' {
background-color: $insensitive_entry_bg_color;
color: transparentize($entry_fg_color, 0.5);
}
}
// Button drawing function
@mixin button($type, $tc:$fg_color, $c:$bg_color, $style: null, $always_dark: false) {
//
// $type: button type, possible values:
// - normal, focus, hover, active, checked, insensitive, default, undecorated
// $c: button bg color, derived from bg_color
// $tc: button text color, derived from fg_color
// $style: button style, possible values: card, notification, dialog, flat, default
// $always_dark: override the light theme check to use dark colors, true or false
//
// mix input colors to get button background color
$button_bg_color: st-mix($tc, $c, $background_mix_factor);
// background color override for card elements
@if $style == 'card' { $button_bg_color: $card_bg_color;}
// background color mix override for flat style; the button bg color is the background color input
@if $style == 'flat' { $button_bg_color: $c;}
// background color mix override for default button style
@if $style == 'default' { $button_bg_color: $c;}
// background color adjustment factors
// the % a color is lightened or darkened for button states
$hover_factor: 4%;
$active_factor: 9%;
$checked_factor: 8%;
$insensitive_factor: 3%;
// flat style overrides
@if $style == 'flat' {
$hover_factor: 7%; // stronger factor in flat style
}
// button base state background colors
$hover_button_bg_color: if($variant == 'light', st-darken($button_bg_color, $hover_factor), st-lighten($button_bg_color, $hover_factor));
$active_button_bg_color: if($variant == 'light', st-darken($button_bg_color, $active_factor), st-lighten($button_bg_color, $active_factor));
$checked_button_bg_color: if($variant == 'light', st-darken($button_bg_color, $checked_factor), st-lighten($button_bg_color, $checked_factor));
$insensitive_button_bg_color: if($variant == 'light', st-lighten($button_bg_color, $insensitive_factor), st-darken($button_bg_color, $insensitive_factor));
// button extended state background colors
$active_hover_button_bg_color: if($variant == 'light', st-darken($active_button_bg_color, $hover_factor), st-lighten($active_button_bg_color, $hover_factor));
$checked_hover_button_bg_color: if($variant == 'light', st-darken($checked_button_bg_color, $hover_factor), st-lighten($checked_button_bg_color, $hover_factor));
$checked_active_button_bg_color: if($variant == 'light', st-darken($checked_button_bg_color, $active_factor), st-lighten($checked_button_bg_color, $active_factor));
// override button background colours if element is always dark
@if $always_dark {
$hover_button_bg_color: st-lighten($button_bg_color, $hover_factor);
$active_button_bg_color: st-lighten($button_bg_color, $active_factor);
$checked_button_bg_color: st-lighten($button_bg_color, $checked_factor);
$insensitive_button_bg_color: st-darken($button_bg_color, $insensitive_factor);
// extended
$active_hover_button_bg_color: st-lighten($active_button_bg_color, $hover_factor);
$checked_hover_button_bg_color: st-lighten($checked_button_bg_color, $hover_factor);
$checked_active_button_bg_color: st-lighten($checked_button_bg_color, $active_factor);
}
// background color override for buttons that use transparency
// styles: dialogs bubbles, lockscreen
@if $style == 'dialog' or $style == 'lockscreen' {
$button_bg_color: transparentize($tc, .9);
$hover_button_bg_color: transparentize($tc, .87);
$active_button_bg_color: transparentize($tc, .84);
$active_hover_button_bg_color: transparentize($tc, .81);
}
// background color overrides for notification style
@if $style == 'notification' {
$button_bg_color: transparentize($tc, .85);
$hover_button_bg_color: transparentize($tc, .7);
$insensitive_button_bg_color: transparentize($tc, .9);
$active_button_bg_color: transparentize($tc, .8);
$active_hover_button_bg_color: transparentize($tc, .8);
}
// flat style overrides
@if $style == 'flat' {
$insensitive_button_bg_color: $button_bg_color;
}
// high contrast overrides
@if $contrast == 'high' {
// override button background colors for high contrast
$button_bg_color: hc_color_mix($button_bg_color);
$hover_button_bg_color: hc_color_mix($hover_button_bg_color);
$active_button_bg_color: hc_color_mix($active_button_bg_color);
$checked_button_bg_color: hc_color_mix($checked_button_bg_color);
// also draw the inset border
@include draw_hc_inset();
// duplicate flat bg color for High Contrast
@if $style == 'flat' {
$button_bg_color: $c;
}
@if $style == 'default' {
@include draw_hc_inset($no_inset: true);
}
}
// normal style
@if $type == 'normal' {
color: $tc;
background-color: $button_bg_color;
// no inset in High Contrast when the style is flat
@if $style == 'flat' and $contrast == 'high' {
@include draw_hc_inset($no_inset: true);
}
}
// hover button
@else if $type == 'hover' {
color: $tc;
background-color: $hover_button_bg_color;
}
// active button
@else if $type == 'active' {
color: $tc;
background-color: $active_button_bg_color;
&:hover { background-color: $active_hover_button_bg_color;}
&:focus {
// otherwise use focus bg color mixin
$bg: focus_bg_color($active_button_bg_color);
background-color: $bg;
}
}
// checked button
@else if $type == 'checked' {
color: $tc;
background-color: $checked_button_bg_color;
&:hover { background-color: $checked_hover_button_bg_color;}
&:active { background-color: $checked_active_button_bg_color;}
}
// insensitive button
@else if $type == 'insensitive' {
$insensitive_button_fg_color: if($variant == 'light', st-transparentize($tc, .6), st-transparentize($tc, .5));
color: $insensitive_button_fg_color;
background-color: $insensitive_button_bg_color;
// no outline in High Contrast for insensitive buttons
@if $contrast == 'high' {
@include draw_hc_inset($no_inset: true);
}
}
// focused button
@else if $type == 'focus' {
color: $tc;
@include focus_ring();
// use a different focus ring color for default style
@if $style == 'default' {
@include focus_ring($fc:$accent_borders_color);
}
// change background color if style is flat
@if $style == 'flat' {
$button_bg_color: transparentize($button_bg_color, 0.75);
}
background-color: focus_bg_color($button_bg_color);
&:hover {
background-color: focus_bg_color($hover_button_bg_color);
}
}
// reset (unstyled button)
@else if $type == 'undecorated' {
background-color: transparent;
border-color: transparent;
box-shadow: none;
&:insensitive {
background-color: transparent !important;
}
}
}
// Helper mixin for button-like elements with an icon
@mixin tile_button($fg:$system_fg_color, $bg:$system_bg_color, $raised: false, $system: true) {
//
// $fg: foreground color
// $bg: background color
//
// $raised: uses raised style, true or false
// $system: uses system styles, true or false
//
@extend %tile;
@if $raised {
@include button(normal, $tc:$fg, $c:$bg, $always_dark: $system);
&:focus { @include button(focus, $tc:$fg, $c:$bg, $always_dark: $system);}
&:hover { @include button(hover, $tc:$fg, $c:$bg, $always_dark: $system);}
&:active { @include button(active, $tc:$fg, $c:$bg, $always_dark: $system);}
&:highlighted,&:selected,
&:checked { @include button(checked, $tc:$fg, $c:$bg, $always_dark: $system);}
&:insensitive { @include button(insensitive, $tc:$fg, $c:$bg, $always_dark: $system);}
} @else {
@include button(normal, $tc:$fg, $c:$bg, $style: flat, $always_dark: $system);
&:focus { @include button(focus, $tc:$fg, $c:$bg, $style: flat, $always_dark: $system);}
&:hover { @include button(hover, $tc:$fg, $c:$bg, $style: flat, $always_dark: $system);}
&:active { @include button(active, $tc:$fg, $c:$bg, $style: flat, $always_dark: $system);}
&:highlighted,&:selected,
&:checked { @include button(checked, $tc:$fg, $c:$bg, $style: flat, $always_dark: $system);}
&:insensitive { @include button(insensitive, $tc:$fg, $c:$bg, $style: flat, $always_dark: $system);}
}
&:drop {
background-color: st-transparentize(-st-accent-color, .8);
box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, .2);
}
}
// styling for all menuitems in popovers
@mixin menuitem($bg, $style: flat) {
// extend common styles
@extend %menuitem;
@if $style == 'flat' {
@include button(undecorated);
} @else {
@include button(normal, $c:$bg);
}
&:hover {
@include button(hover, $c:$bg);
}
&:active {@include button(active, $c:$bg);}
&:selected,
&:checked {@include button(checked, $c:$bg);}
&:insensitive {@include button(insensitive, $c:$bg);}
}
// Panel menu/button drawing function
@mixin panel_button($bg:$panel_fg_color, $fg:$panel_fg_color, $style: null, $highlighted_child: false, $child_class:"") {
//
// $bg: background color, derived from $panel_fg_color
// $fg: foreground color, also derived from $panel_fg_color
// $style: can be set to 'filled' if button uses a colored background
//
// $highlighted_child: if true, applies some special overrides for to a
// child element, see _panel.scss for details
// $child_class: class name of the child element
//
transition-duration: 150ms;
border: 3px solid transparent;
background-color: transparent;
border-radius: $forced_circular_radius;
font-weight: bold;
color: $fg;
// background fill defines
$fill: transparent;
$hover_fill: transparentize($fg, .83);
$active_fill: transparentize($fg, .72);
$active_hover_fill: transparentize($fg, .68);
@if $style == 'filled' {
$fill: $bg;
$hover_fill: if($variant == 'light', darken($bg, 5%), lighten($bg, 5%));
$active_fill: if($variant == 'light', darken($bg, 9%), lighten($bg, 9%));
$active_hover_fill: if($variant == 'light', darken($bg, 11%), lighten($bg, 11%));
}
@include panel_button_fill($fill);
&:focus, &:hover {
@include panel_button_fill($hover_fill);
}
&:active, &:checked {
@include panel_button_fill($active_fill);
&:hover{
@include panel_button_fill($active_hover_fill);
}
}
// some overrides to style a child element
@if $highlighted_child {
// remove the common styles from the parent
background: none !important;
box-shadow: none !important;
border: none !important;
// add them to the child
#{$child_class} {
transition-duration: 150ms;
border: 3px solid transparent;
border-radius: $forced_circular_radius;
}
&:focus, &:hover {
#{$child_class} {
@include panel_button_fill($hover_fill);
}
}
&:active, &:checked {
#{$child_class} {
@include panel_button_fill($active_fill);
&:hover {
@include panel_button_fill($active_hover_fill);
}
}
}
}
}