1// Drawing mixins 2 3// generic drawing of more complex things 4 5@function _widget_edge($c:$borders_edge) { 6// outer highlight "used" on most widgets 7 @if $c == none { @return none; } 8 @else { @return 0 1px $c; } 9} 10 11@mixin _shadows($list...) { 12// 13// Helper mixin to stack up to box-shadows; 14// 15 $shadows: null; 16 17 @each $shadow in $list { 18 @if $shadow!=none { $shadows: $shadows, $shadow; } 19 } 20 21 box-shadow: $shadows; 22} 23 24// entries // Yaru change: we detached focus from selection 25@function entry_focus_border($fc:$focus_border_color) { 26 @if $variant == 'light' { @return $fc; } 27 @else { @return $focus_border_color } 28} 29 30@function entry_focus_shadow($fc:$focus_border_color) { @return inset 0 0 0 1px $fc; } // Yaru change: we detached focus from selection 31 32@mixin entry($t, $fc:$focus_border_color, $edge: none) { // Yaru change: we detached focus from selection 33// 34// Entries drawing function 35// 36// $t: entry type 37// $fc: focus color 38// $edge: set to none to not draw the bottom edge or specify a color to not 39// use the default one 40// 41// possible $t values: 42// normal, focus, insensitive, backdrop, backdrop-insensitive, osd, osd-focus, osd-backdrop; 43// 44 45 $_blank_edge: if($edge == none, none, 0 1px transparentize($edge, 1)); 46 $_entry_edge: if($edge == none, none, _widget_edge($edge)); 47 48 @if $t==normal { 49 color: $text_color; 50 border-color: $borders_color; 51 background-color: $base_color; 52 @include _shadows(entry_focus_shadow(transparentize($fc, 1)), $_entry_edge); 53 // for the transition to work the number of shadows in different states needs to match, hence the transparent shadow here. 54 } 55 @if $t==focus { 56 @include _shadows(entry_focus_shadow($fc), $_entry_edge); 57 border-color: entry_focus_border($fc); 58 } 59 @if $t==insensitive { 60 color: $insensitive_fg_color; 61 border-color: $borders_color; 62 background-color: $insensitive_bg_color; 63 box-shadow: $_entry_edge; 64 } 65 @if $t==backdrop { 66 color: $backdrop_text_color; 67 border-color: $backdrop_borders_color; 68 background-color: $backdrop_base_color; 69 box-shadow: $_blank_edge; 70 } 71 @if $t==backdrop-insensitive { 72 color: $backdrop_insensitive_color; 73 border-color: $backdrop_borders_color; 74 background-color: $insensitive_bg_color; 75 box-shadow: $_blank_edge; 76 } 77 @if $t==osd { 78 color: $osd_text_color; 79 border-color: $osd_borders_color; 80 background-color: transparentize(opacify($osd_borders_color, 1), 0.5); 81 background-clip: padding-box; 82 box-shadow: none; 83 text-shadow: 0 1px black; 84 -gtk-icon-shadow: 0 1px black; 85 } 86 @if $t==osd-focus { 87 color: $osd_text_color; 88 border-color: $selected_bg_color; 89 background-color: transparentize(opacify($osd_borders_color, 1), 0.5); 90 background-clip: padding-box; 91 box-shadow: entry_focus_shadow($fc); 92 text-shadow: 0 1px black; 93 -gtk-icon-shadow: 0 1px black; 94 } 95 @if $t==osd-insensitive { 96 color: $osd_insensitive_fg_color; 97 border-color: $osd_borders_color; 98 background-color: $osd_insensitive_bg_color; 99 background-clip: padding-box; 100 box-shadow: none; 101 text-shadow: none; 102 -gtk-icon-shadow: none; 103 } 104 @if $t==osd-backdrop { 105 color: $osd_text_color; 106 border-color: $osd_borders_color; 107 background-color: transparentize(opacify($osd_borders_color, 1), 0.5); 108 background-clip: padding-box; 109 box-shadow: none; 110 text-shadow: none; 111 -gtk-icon-shadow: none; 112 } 113} 114 115// buttons 116 117@function _border_color($c, $darker: false) { 118 @if $darker == true { @return darken($c, 20%); } 119 @else { @return darken($c, 10%); } 120} 121 122@function _text_shadow_color ($tc: $fg_color, $bg: $bg_color) { 123// 124// calculate the color of text shadows 125// 126// $tc is the text color 127// $bg is the background color 128// 129 $_lbg: lightness($bg)/100%; 130 @if lightness($tc)<50% { @return transparentize(white, 1-$_lbg/($_lbg*1.3)); } 131 @else { @return transparentize(black, $_lbg*0.8); } 132} 133 134@function _button_hilight_color($c) { 135// 136// calculate the right top hilight color for buttons 137// 138// $c: base color; 139// 140 @if lightness($c)>95% { @return white; } 141 @else if lightness($c)>90% { @return transparentize(white, 0.2); } 142 @else if lightness($c)>80% { @return transparentize(white, 0.5); } 143 @else if lightness($c)>50% { @return transparentize(white, 0.8); } 144 @else if lightness($c)>40% { @return transparentize(white, 0.9); } 145 @else { @return transparentize(white, 0.98); } 146} 147 148@mixin _button_text_shadow ($tc:$fg_color, $bg:$bg_color) { 149// 150// helper function for the text emboss effect 151// 152// $tc is the optional text color, not the shadow color 153// 154// TODO: this functions needs a way to deal with special cases 155// 156 157 $_shadow: _text_shadow_color($tc, $bg); 158 159 @if lightness($tc)<50% { 160 text-shadow: 0 1px $_shadow; 161 -gtk-icon-shadow: 0 1px $_shadow; 162 } 163 @else { 164 text-shadow: 0 -1px $_shadow; 165 -gtk-icon-shadow: 0 -1px $_shadow; 166 } 167} 168 169@mixin button($t, $c:$bg_color, $tc:$fg_color, $edge: none) { 170// 171// Button drawing function 172// 173// $t: button type, 174// $c: base button color for colored* types 175// $tc: optional text color for colored* types 176// $edge: set to none to not draw the bottom edge or specify a color to not 177// use the default one 178// 179// possible $t values: 180// normal, hover, active, insensitive, insensitive-active, 181// backdrop, backdrop-active, backdrop-insensitive, backdrop-insensitive-active, 182// osd, osd-hover, osd-active, osd-insensitive, osd-backdrop, undecorated 183// 184// This mixin sets the $button_fill global variable which containts the button background-image 185// 186 $_hilight_color: _button_hilight_color($c); 187 $_button_edge: if($edge == none, none, _widget_edge($edge)); 188 $_blank_edge: if($edge == none, none, _widget_edge(transparentize($edge,1))); 189 $_button_shadow: 0 1px 2px transparentize($shadow_color, 0.03); 190 191 @if $t==normal { 192 // 193 // normal button 194 // 195 color: $tc; 196 outline-color: $focus_border_color; // Yaru change: we detached focus from selection 197 border-color: if($c != $bg_color, _border_color($c), $borders_color); 198 // border-bottom-color: if($c != $bg_color, _border_color($c, true), $alt_borders_color); 199 // Yaru change: we don't want to use gradients on buttons 200 $button_fill: if($c == $bg_color, if($variant == 'light', image(lighten($c, 2%)), image(lighten($c, 4%))), image(lighten($c, 2%))) !global; 201 background-image: $button_fill; 202 @include _button_text_shadow($tc, $c); 203 @include _shadows(0 1px transparentize(black, 0.95)); // Yaru change: stronger shadows for flatter buttons 204 } 205 206 @else if $t==hover { 207 // 208 // hovered button 209 // 210 color: $tc; 211 outline-color: $focus_border_color; // Yaru change: we detached focus from selection 212 border-color: if($c != $bg_color, _border_color($c), $borders_color); 213 border-bottom-color: if($c != $bg_color, _border_color($c, true), $alt_borders_color); 214 @if $variant == 'light' { 215 $button_fill: linear-gradient(to top, $c, lighten($c, 1%) 1px) !global; 216 @include _button_text_shadow($tc, lighten($c, 6%)); 217 @include _shadows(inset 0 1px _button_hilight_color(lighten($c, 6%)), $_button_edge, $_button_shadow); 218 } 219 @else { 220 $button_fill: linear-gradient(to top, darken($c,1%), lighten($c, 1%) 1px) !global; 221 @include _button_text_shadow($tc,lighten($c, 6%)); 222 @include _shadows(inset 0 1px _button_hilight_color(darken($c, 2%)), $_button_edge, $_button_shadow); 223 } 224 box-shadow: 0 1px transparentize(black, if($variant=='light', 0.85, 0.9)); // Yaru change: stronger shadows for flatter buttons 225 background-image: if($c == $bg_color, if($variant == 'light', image(lighten($c, 4%)), image(lighten($c, 6%))), image(lighten($c, 4%))); 226 } 227 228 @if $t==normal-alt { 229 // 230 // normal button alternative look 231 // 232 color: $tc; 233 outline-color: $focus_border_color; // Yaru change: we detached focus from selection 234 border-color: if($c != $bg_color, _border_color($c, true), $alt_borders_color); 235 @include _button_text_shadow($tc, $c); 236 @if $variant == 'light' { 237 background-image: linear-gradient(to bottom, lighten($c, 5%) 20%, $c 90%); 238 @include _shadows(inset 0 1px _button_hilight_color(lighten($c, 6%)), 239 $_button_edge, $_button_shadow); 240 } 241 @else { 242 background-image: linear-gradient(to bottom, darken($c, 3%) 20%, darken($c, 6%) 90%); 243 @include _shadows(inset 0 1px $_hilight_color, 244 $_button_edge, $_button_shadow); 245 } 246 @include _shadows(0 1px transparentize(black, 0.95)); // Yaru change: stronger shadows for flatter buttons 247 background-image: image(if($variant=='light', lighten($c, 10%), $warm_gray)); // Yaru change: brighter alt 248 background-clip: padding-box; // Yaru change: fix background overflow 249 } 250 251 @else if $t==hover-alt { 252 // 253 // hovered button alternative look 254 // 255 color: $tc; 256 outline-color: $focus_border_color; // Yaru change: we detached focus from selection 257 border-color: if($c != $bg_color, _border_color($c, true), $alt_borders_color); 258 @if $variant == 'light' { 259 $button_fill: linear-gradient(to bottom, lighten($c, 9%) 10%, lighten($c, 4%) 90%) !global; 260 @include _shadows(inset 0 1px _button_hilight_color(lighten($c, 6%)), 261 $_button_edge, $_button_shadow); 262 } 263 @else { 264 $button_fill: linear-gradient(to bottom, $c 20%, darken($c, 4%) 90%) !global; 265 @include _shadows(inset 0 1px $_hilight_color, 266 $_button_edge, $_button_shadow); 267 } 268 background-image: image(if($variant=='light', lighten($c, 16%), lighten($warm_gray, 4%))); // Yaru change: brighter alt hover 269 box-shadow: 0 1px transparentize(black, 0.85); // Yaru change: stronger shadows for flatter buttons 270 } 271 272 @else if $t==active { 273 // 274 // pushed button 275 // 276 color: $tc; 277 outline-color: $focus_border_color; // Yaru change: we detached focus from selection 278 border-color: if($c != $bg_color, _border_color($c), $borders_color); 279 $button_fill: if($variant == 'light', image(darken($c, 14%)), image(darken($c, 9%))) !global; 280 background-image: $button_fill; 281 @include _shadows(inset 0 1px transparentize($_hilight_color, 1), $_button_edge); 282 283 text-shadow: none; 284 -gtk-icon-shadow: none; 285 } 286 287 @else if $t==insensitive { 288 // 289 // insensitive button 290 // 291 $_bg: if($c != $bg_color, mix($c, $base_color, 85%), $insensitive_bg_color); 292 293 color: if($tc != $fg_color, mix($tc, $_bg, 50%), $insensitive_fg_color); 294 border-color: if($c != $bg_color, _border_color($c), $insensitive_borders_color); 295 $button_fill: image($_bg) !global; 296 background-image: $button_fill; 297 text-shadow: none; 298 -gtk-icon-shadow: none; 299 // white with 0 alpha to avoid an ugly transition, since no color means 300 // black with 0 alpha 301 @include _shadows(inset 0 1px transparentize(white, 1), $_button_edge); 302 } 303 304 @else if $t==insensitive-active { 305 // 306 // insensitive pushed button 307 // 308 $_bg: if($variant == 'light', darken(mix($c, $base_color, 85%), 8%), darken(mix($c, $base_color, 85%), 6%)); 309 $_bc: if($c != $bg_color, _border_color($c), $insensitive_borders_color); 310 311 color: if($c != $bg_color, mix($tc, $_bg, 60%), $insensitive_fg_color); 312 border-color: $_bc; 313 $button_fill: image($_bg) !global; 314 background-image: $button_fill; 315 // white with 0 alpha to avoid an ugly transition, since no color means 316 // black with 0 alpha 317 @include _shadows(inset 0 1px transparentize(white, 1), $_button_edge); 318 } 319 320 @else if $t==backdrop { 321 // 322 // backdrop button 323 // 324 $_bg: if($c != $bg_color, $c, $backdrop_bg_color); 325 $_bc: if($variant == 'light', $c, _border_color($c)); 326 327 color: if($tc != $fg_color, mix($tc, $_bg, 80%), $backdrop_fg_color); 328 border-color: if($c != $bg_color, $_bc, $backdrop_borders_color); 329 $button_fill: image($_bg) !global; 330 background-image: $button_fill; 331 text-shadow: none; 332 -gtk-icon-shadow: none; 333 @include _shadows(inset 0 1px transparentize(white, 1), $_blank_edge); 334 } 335 336 @else if $t==backdrop-active { 337 // 338 // backdrop pushed button 339 // 340 $_bg: if($variant == 'light', darken(mix($c, $base_color, 85%), 8%), darken(mix($c, $base_color, 85%), 4%)); 341 $_bc: if($variant == 'light', $_bg ,_border_color($c)); 342 343 color: if($tc != $fg_color, mix($tc, $_bg, 80%), $backdrop_fg_color); 344 border-color: if($c != $bg_color, $_bc, $backdrop_borders_color); 345 $button_fill: image($_bg) !global; 346 background-image: $button_fill; 347 @include _shadows(inset 0 1px transparentize(white, 1), $_blank_edge); 348 } 349 350 @else if $t==backdrop-insensitive { 351 // 352 // backdrop insensitive button 353 // 354 355 $_bg: if($c != $bg_color, mix($c, $base_color, 85%), if($variant=='light', $insensitive_bg_color, lighten($insensitive_bg_color, 3%))); // Yaru change 356 $_bc: if($variant == 'light', $_bg,_border_color($c)); 357 358 color: if($c != $bg_color, mix($tc, $_bg, 35%), $backdrop_insensitive_color); 359 border-color: if($c != $bg_color, $_bc, $backdrop_borders_color); 360 $button_fill: image($_bg) !global; 361 background-image: $button_fill; 362 text-shadow: none; 363 -gtk-icon-shadow: none; 364 // white with 0 alpha to avoid an ugly transition, since no color means 365 // black with 0 alpha 366 @include _shadows(inset 0 1px transparentize(white, 1), $_blank_edge); 367 } 368 369 @else if $t==backdrop-insensitive-active { 370 // 371 // backdrop insensitive pushed button 372 // 373 374 $_bg: if($variant == 'light', darken(mix($c, $base_color, 85%), 8%), darken(mix($c, $base_color, 85%), 4%)); 375 $_bc: if($variant == 'light', $_bg, _border_color($c)); 376 377 color: if($c != $bg_color, mix($tc, $_bg, 35%), $backdrop_insensitive_color); 378 border-color: if($c != $bg_color, $_bc, $backdrop_borders_color); 379 $button_fill: image($_bg) !global; 380 background-image: $button_fill; 381 @include _shadows(inset 0 1px transparentize(white, 1), $_blank_edge); 382 } 383 384 @else if $t==osd { 385 // 386 // normal osd button 387 // 388 $_bg: if($c != $bg_color, transparentize($c, 0.5), lighten($osd_bg_color, 9%)); // Yaru change: make osd buttons visible 389 390 color: $osd_fg_color; 391 border-color: $osd_borders_color; 392 background-color: transparent; 393 $button_fill: image($_bg) !global; 394 background-image: $button_fill; 395 background-clip: padding-box; 396 // box-shadow: inset 0 1px transparentize(white, 0.9); // Yaru change: remove the shadow 397 text-shadow: 0 1px black; 398 -gtk-icon-shadow: 0 1px black; 399 outline-color: transparentize($osd_fg_color, 0.7); 400 } 401 402 @else if $t==osd-hover { 403 // 404 // active osd button 405 // 406 $_bg: if($c != $bg_color, transparentize($c, 0.3), lighten($osd_bg_color, 12%)); 407 408 color: white; 409 border-color: $osd_borders_color; 410 background-color: transparent; 411 $button_fill: image($_bg) !global; 412 background-image: $button_fill; 413 background-clip: padding-box; 414 // box-shadow: inset 0 1px transparentize(white, 0.9); // Yaru change: remove the shadow 415 text-shadow: 0 1px black; 416 -gtk-icon-shadow: 0 1px black; 417 outline-color: transparentize($osd_fg_color, 0.7); 418 } 419 420 @else if $t==osd-active { 421 // 422 // active osd button 423 // 424 $_bg: if($c != $bg_color, $c, $osd_borders_color); 425 426 color: white; 427 border-color: $osd_borders_color; 428 background-color: transparent; 429 $button_fill: image($_bg) !global; 430 background-image: $button_fill; 431 background-clip: padding-box; 432 box-shadow: none; 433 text-shadow: none; 434 -gtk-icon-shadow: none; 435 outline-color: transparentize($osd_fg_color, 0.7); 436 } 437 438 @else if $t==osd-insensitive { 439 // 440 // insensitive osd button 441 // 442 color: $osd_insensitive_fg_color; 443 border-color: $osd_borders_color; 444 background-color: transparent; 445 $button_fill: image($osd_insensitive_bg_color) !global; 446 background-image: $button_fill; 447 background-clip: padding-box; 448 box-shadow: none; 449 text-shadow: none; 450 -gtk-icon-shadow: none; 451 } 452 453 @else if $t==osd-backdrop { 454 // 455 // backdrop osd button 456 // 457 $_bg: if($c != $bg_color, transparentize($c, 0.5), $osd_bg_color); 458 459 color: $osd_fg_color; 460 border-color: $osd_borders_color; 461 background-color: transparent; 462 $button_fill: image($_bg) !global; 463 background-image: $button_fill; 464 background-clip: padding-box; 465 box-shadow: none; 466 text-shadow: none; 467 -gtk-icon-shadow: none; 468 } 469 470 @else if $t==undecorated { 471 // 472 // reset 473 // 474 border-color: transparent; 475 background-color: transparent; 476 $button_fill: none !global; 477 background-image: $button_fill; 478 479 @include _shadows(inset 0 1px transparentize(white, 1), $_blank_edge); 480 481 text-shadow: none; 482 -gtk-icon-shadow: none; 483 } 484} 485 486@mixin headerbar_fill($c:$headerbar_color, $hc:$top_hilight, $ov: none) { 487// 488// headerbar fill 489// 490// $c: base color 491// $hc: top highlight color 492// $ov: a background layer for background shorthand (hence no commas!) 493// 494 $gradient: linear-gradient(to top, darken($c, 0%), lighten($c, 0%)); // Yaru change: no gradients 495 496 @if $variant == 'dark' { $gradient: linear-gradient(to top, lighten($c, 6%), lighten($c, 6%)); } // Yaru change: no gradients 497 498 @if $ov != none { background: $c $ov, $gradient; } 499 @else { background: $c $gradient; } 500 501 box-shadow: inset 0 1px $hc; // top highlight 502} 503 504@mixin overshoot($p, $t:normal, $c:$fg_color) { 505// 506// overshoot 507// 508// $p: position 509// $t: type 510// $c: base color 511// 512// possible $p values: 513// top, bottom, right, left 514// 515// possible $t values: 516// normal, backdrop 517// 518 519 $_small_gradient_length: 5%; 520 $_big_gradient_length: 100%; 521 522 $_position: center top; 523 $_small_gradient_size: 100% $_small_gradient_length; 524 $_big_gradient_size: 100% $_big_gradient_length; 525 526 @if $p==bottom { 527 $_position: center bottom; 528 $_linear_gradient_direction: to top; 529 } 530 531 @else if $p==right { 532 $_position: right center; 533 $_small_gradient_size: $_small_gradient_length 100%; 534 $_big_gradient_size: $_big_gradient_length 100%; 535 } 536 537 @else if $p==left { 538 $_position: left center; 539 $_small_gradient_size: $_small_gradient_length 100%; 540 $_big_gradient_size: $_big_gradient_length 100%; 541 } 542 543 $_small_gradient_color: $c; 544 $_big_gradient_color: $c; 545 546 @if $c==$fg_color { 547 $_small_gradient_color: darken($borders_color, 10%); 548 $_big_gradient_color: $fg_color; 549 550 @if $t==backdrop { $_small_gradient_color: $backdrop_borders_color; } 551 } 552 553 $_small_gradient: -gtk-gradient(radial, 554 $_position, 0, 555 $_position, 0.5, 556 to($_small_gradient_color), 557 to(transparentize($_small_gradient_color, 1))); 558 559 $_big_gradient: -gtk-gradient(radial, 560 $_position, 0, 561 $_position, 0.6, 562 from(transparentize($_big_gradient_color, 0.93)), 563 to(transparentize($_big_gradient_color, 1))); 564 565 @if $t==normal { 566 background-image: $_small_gradient, $_big_gradient; 567 background-size: $_small_gradient_size, $_big_gradient_size; 568 } 569 570 @else if $t==backdrop { 571 background-image: $_small_gradient; 572 background-size: $_small_gradient_size; 573 } 574 575 background-repeat: no-repeat; 576 background-position: $_position; 577 578 background-color: transparent; // reset some properties to be sure to not inherit them somehow 579 border: none; // 580 box-shadow: none; // 581} 582 583/*************************** 584 * Check and Radio buttons * 585 ***************************/ 586 587 @mixin check($t, $c:$bg_color, $tc:$fg_color, $checked: false) { 588 // Check/Radio drawing function 589 // 590 // $t: check/radio type, 591 // $c: base button color for colored* types 592 // $tc: optional text color for colored* types 593 // $checked: bool to chose between checked/unchecked 594 // 595 // possible $t values: 596 // normal, hover, active, insensitive, backdrop, backdrop-insensitive 597 598 $_border_color: if($c==$checkradio_bg_color, $c, $alt_borders_color); 599 $_dim_border_color: transparentize($_border_color, if($variant == 'light', 0.3, 0.7)); 600 601 @if $t==normal { // Yaru change: no gradients, better borders 602 background-clip: if($checked, border-box, padding-box); 603 background-image: image(lighten($c, if($variant=='dark', if($c==$checkradio_bg_color, 0%, 5%), 0%))); 604 border-color: $_border_color; 605 box-shadow: 0 1px transparentize(black, 0.95); 606 color: $tc; 607 } 608 609 @if $t==hover { 610 background-image: image(if($c==$checkradio_bg_color, lighten($c, 7%), if($variant=='light', darken($c, 4%), lighten($c, 7%)))); 611 border-color: if($c == $checkradio_bg_color, lighten($c, 7%), $alt_borders_color); 612 } 613 614 @if $t==active { 615 border-color: if($c==white, $_border_color, darken($c, 7%)); 616 background-image: image(if($c==white, $_border_color, darken($c, 7%))); 617 box-shadow: none; 618 } 619 620 @if $t==insensitive { 621 box-shadow: none; 622 color: $insensitive_fg_color; 623 border-color: $insensitive_borders_color; 624 background-image: image($insensitive_bg_color); 625 } 626 627 @if $t==backdrop { 628 background-image: image($c); 629 border-color: $_border_color; 630 box-shadow: none; 631 color: $tc; 632 } 633 634 @if $t==backdrop-insensitive { 635 box-shadow: none; 636 color: $backdrop_fg_color; 637 border-color: $insensitive_borders_color; 638 background-image: image($insensitive_bg_color); 639 } 640} 641