| 1 | /*********** |
| 2 | * Buttons * |
| 3 | ***********/ |
| 4 | // stuff for .needs-attention |
| 5 | $_dot_color: if($variant=='light', $selected_bg_color, |
| 6 | lighten($selected_bg_color,15%)); |
| 7 | |
| 8 | @keyframes needs_attention { |
| 9 | from { background-image: radial-gradient(farthest-side, $_dot_color 0%, transparentize($_dot_color, 1) 0%); } |
| 10 | to { background-image: radial-gradient(farthest-side, $_dot_color 95%, transparentize($_dot_color, 1)); } |
| 11 | } |
| 12 | |
| 13 | |
| 14 | %button, |
| 15 | button { |
| 16 | @at-root %button_basic, & { |
| 17 | min-height: 22px; |
| 18 | min-width: 16px; |
| 19 | padding: 4px 6px; |
| 20 | border: 1px solid $borders_color; |
| 21 | border-radius: 6px; |
| 22 | transition: $button_transition; |
| 23 | |
| 24 | @include button(normal); |
| 25 | |
| 26 | &.flat { |
| 27 | @include button(undecorated); |
| 28 | // to avoid adiacent buttons borders clashing when transitioning, the transition on the normal state is set |
| 29 | // to none, while it's added back in the hover state, so the button decoration will fade in on hover, but |
| 30 | // it won't fade out when the pointer leave the button allocation area. To make the transition more evident |
| 31 | // in this case the duration is increased. |
| 32 | transition: none; |
| 33 | |
| 34 | &:hover { |
| 35 | transition: $button_transition; |
| 36 | transition-duration: 500ms; |
| 37 | @include button(hover,$selected_bg_color,$selected_fg_color); |
| 38 | &:active { transition: $button_transition; } |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | &:hover { |
| 43 | @include button(hover,$selected_bg_color,$selected_fg_color); |
| 44 | -gtk-icon-filter: brightness(1.2); |
| 45 | } |
| 46 | |
| 47 | &:active, |
| 48 | &:checked { |
| 49 | @include button(active,darken($selected_bg_color,5%),$selected_fg_color); |
| 50 | |
| 51 | transition-duration: 50ms; |
| 52 | } |
| 53 | |
| 54 | &:backdrop { |
| 55 | &.flat, & { |
| 56 | @include button(backdrop); |
| 57 | |
| 58 | transition: $backdrop_transition; |
| 59 | -gtk-icon-filter: none; |
| 60 | |
| 61 | &:active, |
| 62 | &:checked { @include button(backdrop-active); } |
| 63 | |
| 64 | &:disabled { |
| 65 | @include button(backdrop-insensitive); |
| 66 | |
| 67 | &:active, |
| 68 | &:checked { @include button(backdrop-insensitive-active); } |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | &.flat { &:backdrop, &:disabled, &:backdrop:disabled { @include button(undecorated); }} |
| 74 | |
| 75 | &:disabled { |
| 76 | @include button(insensitive); |
| 77 | |
| 78 | &:active, |
| 79 | &:checked { @include button(insensitive-active); } |
| 80 | } |
| 81 | |
| 82 | &.image-button { |
| 83 | min-width: 24px; |
| 84 | padding-left: 4px; |
| 85 | padding-right: 4px; |
| 86 | } |
| 87 | &.image-button.circular,&.image-button.sidebar-button{ |
| 88 | padding: 6px 4px; |
| 89 | border-radius: 50px; |
| 90 | box-shadow: none; |
| 91 | } |
| 92 | |
| 93 | &.text-button { |
| 94 | padding-left: 16px; |
| 95 | padding-right: 16px; |
| 96 | } |
| 97 | |
| 98 | &.text-button.image-button { |
| 99 | padding-left: 8px; |
| 100 | padding-right: 8px; |
| 101 | border-radius: 6px; |
| 102 | label { |
| 103 | padding-left: 8px; |
| 104 | padding-right: 8px; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | &:drop(active) { |
| 109 | color: $drop_target_color; |
| 110 | border-color: $drop_target_color; |
| 111 | box-shadow: inset 0 0 0 1px $drop_target_color; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | @at-root %button_selected, & { |
| 116 | row:selected & { |
| 117 | @if $variant == 'light' { border-color: $selected_borders_color; } |
| 118 | |
| 119 | &.flat:not(:active):not(:checked):not(:hover):not(disabled) { |
| 120 | color: $selected_fg_color; |
| 121 | border-color: transparent; |
| 122 | |
| 123 | &:backdrop { color: if($variant=='light', $backdrop_base_color, $backdrop_fg_color); } |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | |
| 129 | // big standalone buttons like in Documents pager |
| 130 | &.osd { |
| 131 | min-width: 24px; |
| 132 | min-height: 20px; |
| 133 | |
| 134 | &.image-button { min-width: 32px; } |
| 135 | |
| 136 | color: $osd_fg_color; |
| 137 | border-radius: 6px; |
| 138 | outline-color: transparentize($osd_fg_color, 0.7); //FIXME: define a color var? |
| 139 | |
| 140 | @include button(osd); |
| 141 | |
| 142 | border: none; |
| 143 | box-shadow: none; |
| 144 | |
| 145 | &:hover { |
| 146 | @include button(osd-hover); |
| 147 | |
| 148 | border: none; |
| 149 | box-shadow: none; |
| 150 | } |
| 151 | |
| 152 | &:active, |
| 153 | &:checked { |
| 154 | @include button(osd-active); |
| 155 | |
| 156 | border: none; |
| 157 | box-shadow: none; |
| 158 | } |
| 159 | |
| 160 | &:disabled { |
| 161 | &:backdrop, & { |
| 162 | @include button(osd-insensitive); |
| 163 | |
| 164 | border: none; |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | &:backdrop { |
| 169 | @include button(osd-backdrop); |
| 170 | |
| 171 | border: none; |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | //overlay / OSD style |
| 176 | @at-root %osd_button, |
| 177 | .osd & { |
| 178 | @include button(osd); |
| 179 | |
| 180 | &:hover { @include button(osd-hover); } |
| 181 | |
| 182 | &:active, |
| 183 | &:checked { &:backdrop, & { @include button(osd-active); }} |
| 184 | |
| 185 | &:disabled { &:backdrop, & { @include button(osd-insensitive); }} |
| 186 | |
| 187 | &:backdrop { @include button(osd-backdrop); } |
| 188 | |
| 189 | &.flat { |
| 190 | @include button(undecorated); |
| 191 | |
| 192 | box-shadow: none; //FIXME respect no edge on the button mixin |
| 193 | text-shadow: 0 1px black; |
| 194 | -gtk-icon-shadow: 0 1px black; |
| 195 | |
| 196 | &:hover { @include button(osd-hover); } |
| 197 | |
| 198 | &:disabled { |
| 199 | @include button(osd-insensitive); |
| 200 | background-image: none; |
| 201 | border-color: transparent; |
| 202 | box-shadow: none; |
| 203 | } |
| 204 | |
| 205 | &:backdrop { @include button(undecorated); } |
| 206 | |
| 207 | &:active, |
| 208 | &:checked { @include button(osd-active); } |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // Suggested and Destructive Action buttons |
| 213 | @each $b_type, $b_color in (suggested-action, $cyan), |
| 214 | (destructive-action, $destructive_color) { |
| 215 | &.#{$b_type} { |
| 216 | border: none; |
| 217 | |
| 218 | @if $b_type == suggested-action { |
| 219 | @include button(rounded, $b_color, white); |
| 220 | } @else { |
| 221 | @include button(rounded-red, $b_color, white); |
| 222 | } |
| 223 | |
| 224 | &.flat { |
| 225 | // @include button(undecorated); |
| 226 | @include button(rounded, $b_color, white); |
| 227 | //color: $b_color; //FIXME: does it work on the dark variant? |
| 228 | } |
| 229 | |
| 230 | &:hover { @include button(hover, $b_color, white); opacity: 0.85;} |
| 231 | |
| 232 | &:active, |
| 233 | &:checked { @include button(active, $b_color, white); } |
| 234 | |
| 235 | &:backdrop, |
| 236 | &.flat:backdrop { |
| 237 | @include button(backdrop, $b_color, white); |
| 238 | label { color: transparentize(white, 0.5);} |
| 239 | &:active, |
| 240 | &:checked { @include button(backdrop-active, $b_color, white); } |
| 241 | |
| 242 | &:disabled { |
| 243 | @include button(backdrop-insensitive, $b_color, white); |
| 244 | label { color: transparentize(white, 0.5);} |
| 245 | |
| 246 | &:active, |
| 247 | &:checked { @include button(backdrop-insensitive-active, $b_color, white); } |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | &.flat { |
| 252 | &:backdrop, &:disabled, &:backdrop:disabled { |
| 253 | @include button(undecorated); |
| 254 | |
| 255 | color: transparentize($b_color, 0.2); |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | &:disabled { |
| 260 | @include button(insensitive, $b_color, white); |
| 261 | opacity: 0.75; |
| 262 | &:active, |
| 263 | &:checked { @include button(insensitive-active, $b_color, white); } |
| 264 | } |
| 265 | |
| 266 | .osd & { |
| 267 | @include button(osd, $b_color); |
| 268 | |
| 269 | &:hover { @include button(osd-hover, $b_color); } |
| 270 | |
| 271 | &:active, |
| 272 | &:checked { &:backdrop, & { @include button(osd-active, $b_color); }} |
| 273 | |
| 274 | &:disabled { &:backdrop, & { @include button(osd-insensitive, $b_color); }} |
| 275 | |
| 276 | &:backdrop { @include button(osd-backdrop, $b_color); } |
| 277 | } |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | .stack-switcher > & { |
| 282 | // to position the needs attention dot, padding is added to the button |
| 283 | // child, a label needs just lateral padding while an icon needs vertical |
| 284 | // padding added too. |
| 285 | |
| 286 | outline-offset: -3px; // needs to be set or it gets overriden by GtkRadioButton outline-offset |
| 287 | |
| 288 | > label { |
| 289 | padding-left: 6px; // label padding |
| 290 | padding-right: 6px; // |
| 291 | } |
| 292 | |
| 293 | > image { |
| 294 | padding-left: 6px; // image padding |
| 295 | padding-right: 6px; // |
| 296 | padding-top: 3px; // |
| 297 | padding-bottom: 3px; // |
| 298 | } |
| 299 | |
| 300 | &.text-button { |
| 301 | // compensate text-button paddings |
| 302 | padding-left: 10px; |
| 303 | padding-right: 10px; |
| 304 | } |
| 305 | |
| 306 | &.image-button { |
| 307 | // we want image buttons to have a 1:1 aspect ratio, so compensation |
| 308 | // of the padding added to the GtkImage is needed |
| 309 | padding-left: 2px; |
| 310 | padding-right: 2px; |
| 311 | } |
| 312 | |
| 313 | &.needs-attention { |
| 314 | > label, |
| 315 | > image { @extend %needs_attention; } |
| 316 | |
| 317 | &:active, |
| 318 | &:checked { |
| 319 | > label, |
| 320 | > image { |
| 321 | animation: none; |
| 322 | background-image: none; |
| 323 | } |
| 324 | } |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | //inline-toolbar buttons |
| 329 | .inline-toolbar &, .inline-toolbar &:backdrop { |
| 330 | border-radius: 6px; |
| 331 | border-width: 1px; |
| 332 | @extend %linked; |
| 333 | } |
| 334 | |
| 335 | .primary-toolbar &, .primary-toolbar .raised & { // tango icons don't need shadows |
| 336 | -gtk-icon-shadow: none; |
| 337 | |
| 338 | &:hover, |
| 339 | &:focus { |
| 340 | @include button(hover,$selected_bg_color,$selected_fg_color); |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | .linked > &, |
| 345 | .linked > &:hover, |
| 346 | .linked > &:active, |
| 347 | .linked > &:checked, |
| 348 | .linked > &:backdrop { @extend %linked; } |
| 349 | |
| 350 | .linked.vertical > &, |
| 351 | .linked.vertical > &:hover, |
| 352 | .linked.vertical > &:active, |
| 353 | .linked.vertical > &:checked, |
| 354 | .linked.vertical > &:backdrop { @extend %linked_vertical; } |
| 355 | } |
| 356 | |
| 357 | %needs_attention { |
| 358 | animation: needs_attention 150ms ease-in; |
| 359 | $_dot_shadow: _text_shadow_color(); |
| 360 | $_dot_shadow_r: if($variant=='light',0.5,0.45); |
| 361 | background-image: radial-gradient(farthest-side, $_dot_color 96%, transparentize($_dot_color,1 )); |
| 362 | background-size: 6px 6px, 6px 6px; |
| 363 | background-repeat: no-repeat; |
| 364 | |
| 365 | @if $variant == 'light' { background-position: right 3px, right 4px; } |
| 366 | |
| 367 | @else { background-position: right 3px, right 2px; } |
| 368 | |
| 369 | &:backdrop { background-size: 6px 6px, 0 0;} |
| 370 | |
| 371 | &:dir(rtl) { |
| 372 | @if $variant == 'light' { background-position: left 3px, left 4px; } |
| 373 | |
| 374 | @else { background-position: left 3px, left 2px; } |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | /* oldstyle toolbar buttons */ |
| 379 | |
| 380 | .toolbar > button, |
| 381 | .toolbar > :not(.linked) > button, |
| 382 | .toolbar :not(.linked) > menubutton > button, |
| 383 | .toolbar :not(.linked) > scalebutton > button, |
| 384 | .toolbar :not(.linked) > dropdown > button, |
| 385 | .toolbar :not(.linked) > colorbutton > button, |
| 386 | .toolbar :not(.linked) > fontbutton > button, |
| 387 | .toolbar :not(.linked) > appchooserbutton > button, |
| 388 | .toolbar :not(.linked) > combobox > box > button { |
| 389 | margin: 1px; |
| 390 | |
| 391 | @include button(undecorated); |
| 392 | |
| 393 | &:hover, |
| 394 | &:active, |
| 395 | &:checked { @include button(hover, $c:lighten($bg_color, 10%)); } |
| 396 | |
| 397 | &:disabled { |
| 398 | opacity: 0.5; |
| 399 | } |
| 400 | } |
| 401 | |
| 402 | %linked_middle { |
| 403 | border: 1px solid $borders_color; |
| 404 | border-radius: 0; |
| 405 | border-right-style: none; |
| 406 | box-shadow: none; |
| 407 | &:disabled { |
| 408 | @include button(insensitive, $base_color, $text_color); |
| 409 | color: $insensitive_fg_color; |
| 410 | } |
| 411 | } |
| 412 | |
| 413 | %linked { |
| 414 | @extend %linked_middle; |
| 415 | |
| 416 | &:first-child { |
| 417 | border-top-left-radius: 6px; |
| 418 | border-bottom-left-radius: 6px; |
| 419 | } |
| 420 | |
| 421 | &:last-child { |
| 422 | border-top-right-radius: 6px; |
| 423 | border-bottom-right-radius: 6px; |
| 424 | border-right-style: solid; |
| 425 | } |
| 426 | |
| 427 | &:only-child { |
| 428 | border-radius: 6px; |
| 429 | border-style: solid; |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | %linked_vertical_middle { |
| 434 | border-style: solid solid none solid; |
| 435 | border-radius: 0; |
| 436 | } |
| 437 | |
| 438 | %linked_vertical{ |
| 439 | @extend %linked_vertical_middle; |
| 440 | |
| 441 | &:first-child { |
| 442 | border-top-left-radius: 6px; |
| 443 | border-top-right-radius: 6px; |
| 444 | } |
| 445 | |
| 446 | &:last-child { |
| 447 | border-bottom-left-radius: 6px; |
| 448 | border-bottom-right-radius: 6px; |
| 449 | border-style: solid; |
| 450 | } |
| 451 | |
| 452 | &:only-child { |
| 453 | border-radius: 6px; |
| 454 | border-style: solid; |
| 455 | } |
| 456 | } |
| 457 | |
| 458 | %undecorated_button { |
| 459 | background-color: transparent; |
| 460 | background-image: none; |
| 461 | border-color: transparent; |
| 462 | box-shadow: inset 0 1px transparentize(white,1), |
| 463 | 0 1px transparentize(white, 1); |
| 464 | text-shadow: none; |
| 465 | -gtk-icon-shadow: none; |
| 466 | } |
| 467 | |
| 468 | /* menu buttons */ |
| 469 | modelbutton.flat, |
| 470 | .menuitem.button.flat { |
| 471 | min-height: 26px; |
| 472 | padding-left: 5px; |
| 473 | padding-right: 5px; |
| 474 | border-radius: 6px; |
| 475 | outline-offset: -2px; |
| 476 | |
| 477 | @extend %undecorated_button; |
| 478 | |
| 479 | &:hover { background-color: $popover_hover_color; } |
| 480 | |
| 481 | &:selected { @extend %selected_items; } |
| 482 | |
| 483 | &:backdrop, |
| 484 | &:backdrop:hover { @extend %undecorated_button; } |
| 485 | |
| 486 | // FIXME: remove the following when the checks/radios rewrite lands |
| 487 | check:last-child, |
| 488 | radio:last-child { margin-left: 8px; } |
| 489 | |
| 490 | check:first-child, |
| 491 | radio:first-child { margin-right: 8px; } |
| 492 | } |
| 493 | |
| 494 | modelbutton.flat arrow { |
| 495 | background: none; |
| 496 | |
| 497 | &:hover { background: none; } |
| 498 | |
| 499 | &.left { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); } |
| 500 | |
| 501 | &.right { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); } |
| 502 | } |
| 503 | |
| 504 | button.color { |
| 505 | padding: 4px; |
| 506 | |
| 507 | colorswatch:only-child { |
| 508 | &, overlay { border-radius: 0; } |
| 509 | |
| 510 | @if $variant == 'light' { |
| 511 | box-shadow: none; |
| 512 | |
| 513 | &:disabled, |
| 514 | &:backdrop { box-shadow: none; } |
| 515 | } |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | notebook, list, .view, popover { |
| 520 | button { |
| 521 | box-shadow: none; |
| 522 | &:backdrop { |
| 523 | box-shadow: none; |
| 524 | } |
| 525 | } |
| 526 | .linked > button { |
| 527 | box-shadow: none; |
| 528 | } |
| 529 | } |
| 530 | |
| 531 | // Gnome 48 toggle groups (screens config) |
| 532 | toggle-group{ |
| 533 | padding: 3px; |
| 534 | toggle{ |
| 535 | &:checked { |
| 536 | background-color: $selected_bg_color; |
| 537 | &, label { color: $selected_fg_color; } |
| 538 | } |
| 539 | padding: 0 4px; |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | /* |
| 544 | * Gnome 48 accent color buttons |
| 545 | * Gnome papers - buttons in context menu |
| 546 | */ |
| 547 | |
| 548 | button.accent-button, button.color-button { |
| 549 | &, &:backdrop { |
| 550 | min-height: 24px; |
| 551 | min-width: 24px; |
| 552 | padding: 3px; |
| 553 | border-radius: 100%; |
| 554 | background: var(--accent-bg-color); |
| 555 | outline: none; |
| 556 | background-clip: content-box; |
| 557 | box-shadow: none; |
| 558 | border: none; |
| 559 | } |
| 560 | |
| 561 | &:hover { |
| 562 | box-shadow: 0 0 0 3px darken($base_color, 5%); |
| 563 | background-color: var(--accent-bg-color); |
| 564 | } |
| 565 | |
| 566 | &:checked { |
| 567 | &, &:backdrop { |
| 568 | box-shadow: 0 0 0 3px var(--accent-bg-color); |
| 569 | background-color: var(--accent-bg-color); |
| 570 | } |
| 571 | } |
| 572 | } |