1 module rpui.widgets.button.transforms_system; 2 3 import std.container.array; 4 import std.math; 5 6 import rpui.events; 7 import rpui.widgets.button.widget; 8 import rpui.render.components_factory; 9 import rpui.render.components; 10 import rpui.render.transforms; 11 import rpui.theme; 12 import rpui.widgets.button.render_system; 13 import rpui.math; 14 import rpui.primitives; 15 import rpui.widget; 16 17 struct RenderTransforms { 18 HorizontalChainTransforms background; 19 HorizontalChainTransforms focusGlow; 20 UiTextTransforms captionText; 21 Array!QuadTransforms icons; 22 } 23 24 final class ButtonTransformsSystem : TransformsSystem { 25 private RenderTransforms* transforms; 26 private Button widget; 27 private Theme theme; 28 private RenderData* renderData; 29 30 this(Button widget, RenderData* renderData, RenderTransforms* transforms) { 31 this.widget = widget; 32 this.theme = widget.view.theme; 33 this.renderData = renderData; 34 this.transforms = transforms; 35 } 36 37 override void onProgress(in ProgressEvent event) { 38 updateBackground(); 39 updateText(); 40 updateIcons(); 41 } 42 43 private void updateBackground() { 44 transforms.background = updateHorizontalChainTransforms( 45 renderData.background.widths, 46 widget.view.cameraView, 47 widget.absolutePosition, 48 widget.size, 49 widget.partDraws 50 ); 51 52 if (widget.focusable && widget.isFocused) { 53 transforms.focusGlow = updateHorizontalChainTransforms( 54 renderData.background.widths, 55 widget.view.cameraView, 56 widget.absolutePosition + widget.measure.focusOffsets, 57 widget.size + vec2(widget.measure.focusResize), 58 widget.partDraws 59 ); 60 } 61 } 62 63 private void updateText() { 64 if (widget.caption == "") { 65 widget.measure.textWidth = 0; 66 return; 67 } 68 69 const textBoxSize = widget.size - vec2(widget.measure.iconsAreaSize, 0); 70 auto textPosition = vec2(widget.measure.iconsAreaSize, 0) + widget.absolutePosition; 71 72 if (widget.textAlign == Align.left) { 73 textPosition.x += widget.measure.textLeftMargin; 74 } 75 else if (widget.textAlign == Align.right) { 76 textPosition.x -= widget.measure.textRightMargin; 77 } 78 79 if (widget.partDraws == Widget.PartDraws.left || widget.partDraws == Widget.PartDraws.right) { 80 textPosition.x -= 1; 81 } 82 83 with (renderData.captionText.attrs[widget.state]) { 84 caption = widget.caption; 85 textAlign = widget.textAlign; 86 textVerticalAlign = widget.textVerticalAlign; 87 } 88 89 transforms.captionText = updateUiTextTransforms( 90 &renderData.captionText.render, 91 &theme.regularFont, 92 transforms.captionText, 93 renderData.captionText.attrs[widget.state], 94 widget.view.cameraView, 95 textPosition, 96 textBoxSize 97 ); 98 99 widget.measure.textWidth = transforms.captionText.size.x; 100 } 101 102 private void updateIcons() { 103 with (widget) { 104 measure.iconsAreaSize = 0; 105 106 const iconSize = view.resources.icons.getIconsConfig(iconsGroup).size; 107 const iconVerticalOffset = round((size.y - iconSize.y) / 2.0f); 108 float iconLastOffset = 0; 109 int counter = 0; 110 111 for (int i = 0; i < widget.icons.length; ++i) { 112 const iconOffset = iconLastOffset; 113 114 iconLastOffset = iconOffset + iconSize.x + measure.iconGaps; 115 counter++; 116 const offset = measure.iconOffsets + vec2(iconOffset, iconVerticalOffset); 117 118 const transform = updateQuadTransforms( 119 view.cameraView, 120 absolutePosition + offset, 121 iconSize 122 ); 123 transforms.icons[i] = transform; 124 } 125 126 if (icons.length > 0) { 127 measure.iconsAreaSize += iconLastOffset - measure.iconGaps * 2; 128 } 129 } 130 } 131 }