From aad92bad89d8a8205b04c1c78171f1e4472475b6 Mon Sep 17 00:00:00 2001
From: Aylong <69762909+AyIong@users.noreply.github.com>
Date: Tue, 3 Dec 2024 14:10:25 +0200
Subject: [PATCH] Remove blue buttons from loadout (#832)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## About The Pull Request
Это максимум который я сделаю
Делать ТГУИ на ТГ **МАКСИМАЛЬНО** неприятно, всё сука лагает, всё блять
разбросано как говно по туалету
Я блять ненавижу то что ТГшеры сделали с ТГУИ
![image](https://github.com/user-attachments/assets/0fafe0bc-85cc-4fa8-8593-bfeea1fd2c79)
---
.../tgui/bandastation/ImageButton.scss | 276 ++++++++++++++++++
.../tgui/bandastation/ImageButton.tsx | 245 ++++++++++++++++
.../tgui/bandastation/ItemDisplay220.tsx | 86 ++++++
.../PreferencesMenu/loadout/ItemDisplay.tsx | 21 +-
.../PreferencesMenu/loadout/base.ts | 2 +-
5 files changed, 616 insertions(+), 14 deletions(-)
create mode 100644 tgui/packages/tgui/bandastation/ImageButton.scss
create mode 100644 tgui/packages/tgui/bandastation/ImageButton.tsx
create mode 100644 tgui/packages/tgui/bandastation/ItemDisplay220.tsx
diff --git a/tgui/packages/tgui/bandastation/ImageButton.scss b/tgui/packages/tgui/bandastation/ImageButton.scss
new file mode 100644
index 0000000000000..cddf4d48c1e15
--- /dev/null
+++ b/tgui/packages/tgui/bandastation/ImageButton.scss
@@ -0,0 +1,276 @@
+/**
+ * Copyright (c) 2024 Aylong (https://github.com/AyIong)
+ * SPDX-License-Identifier: MIT
+ */
+@use '~tgui/styles/base.scss';
+@use '~tgui/styles/colors.scss';
+@use '../styles/functions.scss' as *;
+
+$color-default: colors.bg(base.$color-bg-section) !default;
+$color-disabled: hsl(0, 55%, 25%) !default;
+$color-selected: colors.bg(colors.$green) !default;
+$bg-map: colors.$bg-map !default;
+
+@function round-color($color, $opacity: null) {
+ $r: round(red($color));
+ $g: round(green($color));
+ $b: round(blue($color));
+ @if $opacity != null {
+ @return rgba($r, $g, $b, $opacity);
+ }
+ @return rgb($r, $g, $b);
+}
+
+@mixin button-style(
+ $color,
+ $border-color: round-color(lighten($color, 50%), 0.2),
+ $border-width: 1px 0 0 0,
+ $opacity: 0.2,
+ $hoverable: true,
+ $transition-duration: 0.2s
+) {
+ $text-color: if(luminance($color) > 0.3, black, white);
+ background-color: round-color($color, $opacity);
+ color: $text-color;
+ border: solid $border-color;
+ border-width: $border-width;
+ transition:
+ background-color $transition-duration,
+ border-color $transition-duration;
+
+ @if $hoverable {
+ &:hover {
+ background-color: round-color(lighten($color, 50%), $opacity);
+ }
+ }
+}
+
+@each $color-name, $color-value in $bg-map {
+ .color__#{$color-name} {
+ @include button-style($color-value, $border-width: 1px);
+ }
+
+ .contentColor__#{$color-name} {
+ @include button-style(
+ $color-value,
+ $border-color: lighten($color-value, 25%),
+ $opacity: 1,
+ $hoverable: false
+ );
+ }
+
+ .buttonsContainerColor__#{$color-name} {
+ @include button-style(
+ $color-value,
+ $border-width: 1px 1px 1px 0,
+ $opacity: 0.33,
+ $hoverable: false,
+ $transition-duration: 0
+ );
+ }
+}
+
+.color__default {
+ @include button-style(lighten($color-default, 85%), $border-width: 1px);
+}
+
+.disabled {
+ background-color: rgba($color-disabled, 0.25) !important;
+ border-color: rgba($color-disabled, 0.25) !important;
+}
+
+.selected {
+ @include button-style(
+ $color-selected,
+ $border-color: rgba($color-selected, 0.25),
+ $border-width: 1px
+ );
+}
+
+.contentColor__default {
+ @include button-style(
+ lighten($color-default, 80%),
+ $border-color: lighten($color-default, 100%),
+ $opacity: 1,
+ $hoverable: false
+ );
+}
+
+.contentDisabled {
+ background-color: $color-disabled !important;
+ border-top: 1px solid lighten($color-disabled, 25%) !important;
+}
+
+.contentSelected {
+ @include button-style(
+ $color-selected,
+ $border-color: lighten($color-selected, 25%),
+ $opacity: 1,
+ $hoverable: false
+ );
+}
+
+.buttonsContainerColor__default {
+ @include button-style(
+ lighten($color-default, 85%),
+ $border-width: 1px 1px 1px 0,
+ $hoverable: false,
+ $transition-duration: 0
+ );
+}
+
+.ImageButton {
+ display: inline-table;
+ position: relative;
+ text-align: center;
+ margin: 0.25em;
+ user-select: none;
+ -ms-user-select: none;
+
+ .noAction {
+ pointer-events: none;
+ }
+
+ .container {
+ display: flex;
+ flex-direction: column;
+ border-radius: 0.33em;
+ }
+
+ .image {
+ position: relative;
+ align-self: center;
+ pointer-events: none;
+ overflow: hidden;
+ line-height: 0;
+ padding: 0.25em;
+ border-radius: 0.33em;
+ }
+
+ .buttonsContainer {
+ display: flex;
+ position: absolute;
+ overflow: hidden;
+ left: 1px;
+ bottom: 1.8em;
+ max-width: 100%;
+ z-index: 1;
+
+ &.buttonsAltContainer {
+ overflow: visible;
+ flex-direction: column;
+ pointer-events: none;
+ top: 1px;
+ bottom: inherit !important;
+ }
+
+ &.buttonsEmpty {
+ bottom: 1px;
+ }
+
+ & > * {
+ /* I know !important is bad, but here's no other way */
+ margin: 0 !important;
+ padding: 0 0.2em !important;
+ border-radius: 0 !important;
+ }
+ }
+
+ .content {
+ -ms-user-select: none;
+ user-select: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ padding: 0.25em 0.5em;
+ margin: -1px;
+ border-radius: 0 0 0.33em 0.33em;
+ z-index: 2;
+ }
+}
+
+.fluid {
+ display: flex;
+ flex-direction: row;
+ position: relative;
+ text-align: center;
+ margin: 0 0 0.5em 0;
+ user-select: none;
+ -ms-user-select: none;
+
+ &:last-of-type {
+ margin-bottom: 0;
+ }
+
+ .info {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ flex: 1;
+ }
+
+ .title {
+ font-weight: bold;
+ padding: 0.5em;
+
+ &.divider {
+ margin: 0 0.5em;
+ border-bottom: base.em(2px) solid rgba(255, 255, 255, 0.1);
+ }
+ }
+
+ .contentFluid {
+ padding: 0.5em;
+ color: white;
+ }
+
+ .container {
+ flex-direction: row;
+ flex: 1;
+
+ &.hasButtons {
+ border-radius: 0.33em 0 0 0.33em;
+ border-width: 1px 0 1px 1px;
+ }
+ }
+
+ .image {
+ padding: 0;
+ }
+
+ .buttonsContainer {
+ position: relative;
+ left: inherit;
+ bottom: inherit;
+ border-radius: 0 0.33em 0.33em 0;
+
+ &.buttonsEmpty {
+ bottom: inherit;
+ }
+
+ &.buttonsAltContainer {
+ overflow: hidden;
+ pointer-events: auto;
+ top: inherit;
+
+ & > * {
+ border-top: 1px solid rgba(255, 255, 255, 0.075);
+
+ &:first-child {
+ border-top: 0;
+ }
+ }
+ }
+
+ & > * {
+ display: inline-flex;
+ flex-direction: column;
+ justify-content: center;
+ text-align: center;
+ white-space: pre-wrap;
+ line-height: base.em(14px);
+ height: 100%;
+ border-left: 1px solid rgba(255, 255, 255, 0.075);
+ }
+ }
+}
diff --git a/tgui/packages/tgui/bandastation/ImageButton.tsx b/tgui/packages/tgui/bandastation/ImageButton.tsx
new file mode 100644
index 0000000000000..785b98ed0d267
--- /dev/null
+++ b/tgui/packages/tgui/bandastation/ImageButton.tsx
@@ -0,0 +1,245 @@
+/**
+ * @file
+ * @copyright 2024 Aylong (https://github.com/AyIong)
+ * @license MIT
+ */
+
+import './ImageButton.scss';
+
+import { Placement } from '@popperjs/core';
+import { BooleanLike, classes } from 'common/react';
+import { ReactNode } from 'react';
+
+import { BoxProps, computeBoxProps } from '../components/Box';
+import { DmIcon } from '../components/DmIcon';
+import { Icon } from '../components/Icon';
+import { Image } from '../components/Image';
+import { Stack } from '../components/Stack';
+import { Tooltip } from '../components/Tooltip';
+
+type Props = Partial<{
+ /** Asset cache. Example: `asset={`assetname32x32, ${thing.key}`}` */
+ asset: string[];
+ /** Classic way to put images. Example: `base64={thing.image}` */
+ base64: string;
+ /**
+ * Special container for buttons.
+ * You can put any other component here.
+ * Has some special stylings!
+ * Example: `buttons={}`
+ */
+ buttons: ReactNode;
+ /**
+ * Same as buttons, but. Have disabled pointer-events on content inside if non-fluid.
+ * Fluid version have humburger layout.
+ */
+ buttonsAlt: ReactNode;
+ /** Content under image. Or on the right if fluid. */
+ children: ReactNode;
+ /** Applies a CSS class to the element. */
+ className: string;
+ /** Color of the button. See [Button](#button) but without `transparent`. */
+ color: string;
+ /** Makes button disabled and dark red if true. Also disables onClick. */
+ disabled: BooleanLike;
+ /** Optional. Adds a "stub" when loading DmIcon. */
+ dmFallback: ReactNode;
+ /** Parameter `icon` of component `DmIcon`. */
+ dmIcon: string | null;
+ /** Parameter `icon_state` of component `DmIcon`. */
+ dmIconState: string | null;
+ /** Parameter `direction` of component `DmIcon`. */
+ dmDirection: any;
+ /**
+ * Changes the layout of the button, making it fill the entire horizontally available space.
+ * Allows the use of `title`
+ */
+ fluid: boolean;
+ /** Parameter responsible for the size of the image, component and standard "stubs". */
+ imageSize: number;
+ /** Prop `src` of . Example: `imageSrc={resolveAsset(thing.image}` */
+ imageSrc: string;
+ /** Called when button is clicked with LMB. */
+ onClick: (e: any) => void;
+ /** Called when button is clicked with RMB. */
+ onRightClick: (e: any) => void;
+ /** Makes button selected and green if true. */
+ selected: BooleanLike;
+ /** Requires `fluid` for work. Bold text with divider betwen content. */
+ title: string;
+ /** A fancy, boxy tooltip, which appears when hovering over the button */
+ tooltip: ReactNode;
+ /** Position of the tooltip. See [`Popper`](#Popper) for valid options. */
+ tooltipPosition: Placement;
+}> &
+ BoxProps;
+
+export const ImageButton = (props: Props) => {
+ const {
+ asset,
+ base64,
+ buttons,
+ buttonsAlt,
+ children,
+ className,
+ color,
+ disabled,
+ dmFallback,
+ dmDirection,
+ dmIcon,
+ dmIconState,
+ fluid,
+ imageSize = 64,
+ imageSrc,
+ onClick,
+ onRightClick,
+ selected,
+ title,
+ tooltip,
+ tooltipPosition,
+ ...rest
+ } = props;
+
+ const getFallback = (iconName: string, iconSpin: boolean) => {
+ return (
+