1 module creator.widgets.label;
2 import bindbc.imgui;
3 import creator.widgets.dummy;
4 import creator.core.font;
5 
6 /**
7     Render text
8 */
9 void incText(string text) {
10     igTextUnformatted(text.ptr, text.ptr+text.length);
11 }
12 
13 /**
14     Render text colored
15 */
16 void incTextColored(ImVec4 color, string text) {
17     igPushStyleColor(ImGuiCol.Text, color);
18         igTextUnformatted(text.ptr, text.ptr+text.length);
19     igPopStyleColor();
20 }
21 
22 /**
23     Render disabled text
24 */
25 void incTextDisabled(string text) {
26     igPushStyleColor(ImGuiCol.Text, igGetStyle().Colors[ImGuiCol.TextDisabled]);
27         igTextUnformatted(text.ptr, text.ptr+text.length);
28     igPopStyleColor();
29 }
30 
31 /**
32     Renders text with a slight dropshadow
33 */
34 void incTextShadowed(string text) {
35     
36     ImVec2 origin;
37     igGetCursorPos(&origin);
38     
39     // Shadow
40     igSetCursorPos(ImVec2(origin.x+1, origin.y+1));
41     incTextColored(ImVec4(0.25, 0.25, 0.25, 0.5), text);
42 
43     // Version String
44     igSetCursorPos(origin);
45     incText(text);
46 }
47 
48 /**
49     Renders text with a slight border
50 */
51 void incTextBordered(string text, ImVec4 borderColor = ImVec4(0, 0, 0, 1)) {
52     
53     ImVec2 origin;
54     igGetCursorPos(&origin);
55     
56     // Shadow
57     igSetCursorPos(ImVec2(origin.x+1, origin.y));
58     incTextColored(borderColor, text);
59     igSetCursorPos(ImVec2(origin.x-1, origin.y));
60     incTextColored(borderColor, text);
61     igSetCursorPos(ImVec2(origin.x, origin.y+1));
62     incTextColored(borderColor, text);
63     igSetCursorPos(ImVec2(origin.x, origin.y-1));
64     incTextColored(borderColor, text);
65 
66     // Version String
67     igSetCursorPos(origin);
68     incText(text);
69 }
70 
71 /**
72     Render wrapped
73 */
74 void incTextWrapped(string text) {
75     igPushTextWrapPos(0f);
76         igTextUnformatted(text.ptr, text.ptr+text.length);
77     igPopTextWrapPos();
78 }
79 
80 bool incTextLinkWithIcon(string icon, string text) {
81     incText(icon);
82     igSameLine(0, 4);
83     return incTextLink(text);
84 }
85 
86 bool incTextLink(string text, ImVec4 hoverColor = ImVec4(0.313, 0.521, 0.737, 1), ImVec4 clickedColor = ImVec4(0.132, 0.335, 0.523, 1), ImVec4 baseColor = ImVec4(0.186, 0.457, 0.708, 1)) {
87     ImGuiWindow* window = igGetCurrentWindow();
88     if (window.SkipItems) return false;
89     
90     enum TEXT_LINK_CLICKED_ID = "LinkClicked";
91     ImVec2 cursorPos;
92     igGetCursorPos(&cursorPos);
93     bool clicked, hovered, held;
94 
95     igNewLine();
96 
97     igPushID(text.ptr, text.ptr+text.length);
98         ImGuiStorage* storage = igGetStateStorage();
99         bool linkClicked = ImGuiStorage_GetBool(
100             storage, 
101             igGetID(TEXT_LINK_CLICKED_ID.ptr, TEXT_LINK_CLICKED_ID.ptr+TEXT_LINK_CLICKED_ID.length), 
102             false
103         );
104 
105         ImVec2 size = incMeasureString(text);
106 
107         igSetItemAllowOverlap();
108         // Create bounding box for clickable area
109         ImGuiID id = igGetID(text.ptr, text.ptr+text.length);
110         ImRect bb = ImRect(window.DC.CursorPos, ImVec2(window.DC.CursorPos.x+size.x, window.DC.CursorPos.y+size.y));
111         igItemSize(bb);
112         clicked = igButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlagsI.AllowItemOverlap);
113         
114         if (!igItemAdd(bb, id)) {
115             igPopID();
116             return false;
117         }
118 
119         if (clicked) {
120              ImGuiStorage_SetBool(
121                 storage, 
122                 igGetID(TEXT_LINK_CLICKED_ID.ptr, TEXT_LINK_CLICKED_ID.ptr+TEXT_LINK_CLICKED_ID.length), 
123                 true
124             );
125         }
126 
127         // Seperate hover for cursor
128         if (hovered) {
129             igSetMouseCursor(ImGuiMouseCursor.Hand);
130         }
131 
132         igSetCursorPos(cursorPos);
133         if (!held && hovered) {
134             incTextColored(hoverColor, text);
135             incAddUnderline(hoverColor);
136         } else if ((held && hovered) || linkClicked) {
137             incTextColored(clickedColor, text);
138             incAddUnderline(clickedColor);
139         } else {
140             incTextColored(baseColor, text);
141             incAddUnderline(baseColor);
142         }
143     igPopID();
144 
145     return clicked;
146 }
147 
148 private {
149     void incAddUnderline(ImVec4 color) {
150         ImVec2 min, max;
151         igGetItemRectMin(&min);
152         igGetItemRectMax(&max);
153         min.y = max.y;
154         ImDrawList_AddLine(igGetWindowDrawList(), min, max, igGetColorU32_Vec4(color), 1.0f);
155     }
156 }