User Interface
We follow the standard ribbon interface for UI. Further, supporting all indian scheduled languages is must. This will als enable us to support international languages in future. Please refer below actual code files for user interface design specifications. We have baseline strings say N numbers in English. Each string can have a corresponding language translation or if the language translation is empty string, than the corresponding english text shall be followed. All translations are stored in UserInterface-Text.h file.
Supporting all Indian languages is mostly a data organization + text shaping problem, not a rendering problem. Renderer will just draw glyphs; the system around it decides which string to show.
Translation Document
1// Copyright (c) 2026-Present : Ram Shanker: All rights reserved.
2#pragma once
3
4enum class UILanguage : uint8_t
5{
6 English = 0,
7
8 // 22 Indian scheduled languages
9 Hindi,
10 Bengali,
11 Telugu,
12 Marathi,
13 Tamil,
14 Urdu,
15 Gujarati,
16 Kannada,
17 Malayalam,
18 Odia,
19 Punjabi,
20 Assamese,
21 Maithili,
22 Santali,
23 Kashmiri,
24 Nepali,
25 Sindhi,
26 Konkani,
27 Manipuri,
28 Bodo,
29 Dogri,
30 Sanskrit,
31
32 // Major global engineering languages
33 ChineseSimplified,
34 ChineseTraditional,
35 Japanese, // Covers all of Katakana , Kanji and Hiragana symbols within same fonts.
36 Korean,
37 German,
38 French,
39 Spanish,
40 Portuguese,
41 Russian,
42 Italian,
43 Turkish,
44 Polish,
45 Dutch,
46 Swedish,
47 Czech,
48 Hungarian,
49 Ukrainian,
50 Vietnamese,
51 Thai,
52 Indonesian,
53 Arabic,
54 Persian, // Farsi - Iran engineering market
55 Filipino,// Tagalog
56
57 COUNT
58};
59
60/*
61ChatGPT analysis of population coverage by above 46 languages:
62
63| Metric | Result |
64| ------------------------------ | ---------- |
65| World population coverage | **90–94%** |
66| Engineering workforce coverage | **97–99%** |
67| India coverage | **~99%** |
68| Europe coverage | **~95%** |
69| Americas coverage | **~95%** |
70
71All these 46 languages translate to 13 unique scripts. Unicode handles all of the well.
72
73| Script | Languages |
74| ------------- | ------------------------------------- |
75| Latin | English, German, French, Spanish, etc |
76| Devanagari | Hindi, Marathi, Nepali etc |
77| Bengali | Bengali, Assamese |
78| Gurmukhi | Punjabi |
79| Gujarati | Gujarati |
80| Odia | Odia |
81| Tamil | Tamil |
82| Telugu | Telugu |
83| Kannada | Kannada |
84| Malayalam | Malayalam |
85| Arabic script | Urdu, Arabic, Persian, Kashmiri |
86| Chinese Han | Chinese + Japanese Kanji |
87| Japanese kana | Hiragana/Katakana |
88| Hangul | Korean |
89| Thai | Thai |
90
91Professional CAD software language coverage (As per ChatGPT).
92| Software | Languages |
93| ---------- | --------- |
94| AutoCAD | ~15 |
95| SolidWorks | ~13 |
96| Fusion360 | ~10 |
97| CATIA | ~8 |
98All softwares listed below are copy right of respective software companies.
99
100HENCE OUR LANGUAGE LIST IS FROZEN ! ;)
101
102Estimated size overhead of bundling all the fonts:
103
104| Font | Typical Size |
105| ---------------------------- | ------------ |
106| Noto Sans (Latin + extended) | ~2 MB |
107| Noto Sans Devanagari | ~1.5 MB |
108| Noto Sans Bengali | ~1.3 MB |
109| Noto Sans Gurmukhi | ~0.9 MB |
110| Noto Sans Gujarati | ~1.0 MB |
111| Noto Sans Oriya (Odia) | ~1.1 MB |
112| Noto Sans Tamil | ~0.9 MB |
113| Noto Sans Telugu | ~1.2 MB |
114| Noto Sans Kannada | ~1.2 MB |
115| Noto Sans Malayalam | ~1.4 MB |
116| Noto Sans Arabic | ~1.2 MB |
117| Noto Sans Thai | ~0.7 MB |
118
119Subtotal (non-CJK): ≈ 14–15 MB
120
121| Font | Approx Size |
122| -------------------------------------- | ----------- |
123| Noto Sans CJK SC (Simplified Chinese) | ~16–18 MB |
124| Noto Sans CJK TC (Traditional Chinese) | ~16–18 MB |
125| Noto Sans CJK JP (Japanese) | ~16–18 MB |
126| Noto Sans CJK KR (Korean) | ~16–18 MB |
127
128CJK 3 variants (SC + JP + KR): ≈ 48–54 MB
129
130Total: ≈ 65 MB , ~60% Compression expected in Installer. ≈ 40 MB. Acceptable.
131
132Runtime: Entire font files will not be loaded at runtime.
133They will be loaded on demand to minimize memory footprint.
134
135*/User Interface Design Document and Implementation!
1// Copyright (c) 2026-Present : Ram Shanker: All rights reserved.
2#pragma once
3
4#define WIN32_LEAN_AND_MEAN
5#include <windows.h> // MUST be before d3d12.h
6#include <d3d12.h>
7#include <d3dx12.h>
8#include <dxgi1_6.h>
9#include <wrl.h>
10#include <vector>
11#include <unordered_map>
12#include <iostream>
13#include <atomic>
14
15#include "ConstantsApplication.h"
16#include "UserInterface.h" // It also includes "UserInterface-TextTranslations.h"
17
18// Do not #include "विश्वकर्मा.h" otherwise it will lead to circular dependency error. Declare this struct exist.
19struct SingleUIWindow; // Add this forward declaration:
20
21using Microsoft::WRL::ComPtr;
22
23struct DX12ResourcesUI { // GPU resources
24 ComPtr<ID3D12Resource> uiAtlasTexture; // 1024×1024 or 2048×2048 RGBA (or R8 for alpha-only)
25 ComPtr<ID3D12Resource> uiVertexBuffer; // Dynamic upload buffer for vertices
26 ComPtr<ID3D12Resource> uiIndexBuffer; // Dynamic upload buffer for indices
27
28 UINT8* pVertexDataBegin = nullptr; // Mapped pointer for immediate writing
29 UINT8* pIndexDataBegin = nullptr;
30 UINT8* pOrthoDataBegin = nullptr;
31
32 ID3D12Resource* iconAtlas; // Required ?
33 ComPtr<ID3D12PipelineState> uiPSO;
34 ComPtr<ID3D12RootSignature> uiRootSignature;
35 ComPtr<ID3D12Resource> uiOrthoConstantBuffer;
36
37 uint32_t maxVertices = 65536;
38 uint32_t maxIndices = 65536 * 3;
39};
40
41struct UIDrawContext { // Draw context
42 UIVertex* vertexPtr;
43 uint16_t* indexPtr;
44 uint32_t vertexCount, indexCount;
45};
46
47// DirectX12 Immediate Mode UI System (Phase 4A). Tab Bar Rendering Only
48// External interfaces of User Interface sub module of the code.
49void InitUIResources( DX12ResourcesUI& uiRes, ID3D12Device* device);
50void CleanupUIResources( DX12ResourcesUI& uiRes);
51
52void PushRect( UIDrawContext& ctx, float x, float y, float w, float h, uint32_t color, DX12ResourcesUI& uiRes);
53void RenderUIOverlay( SingleUIWindow& window, ID3D12GraphicsCommandList* cmdList,
54 DX12ResourcesUI& uiRes, float monitorDPI, const UIInput& input);
1// Copyright (c) 2026-Present : Ram Shanker: All rights reserved.
2
3#include "UserInterface-DirectX12.h"
4#include <d3dcompiler.h>
5#include <MemoryManagerGPU-DirectX12.h>
6#include "विश्वकर्मा.h"
7extern शंकर gpu;
8extern std::atomic<uint16_t*> publishedTabIndexes;
9extern std::atomic<uint16_t> publishedTabCount;
10std::atomic<uint32_t> actionWriteIndex;
11// Shader compilation helper
12static void CompileShader( const char* code, const char* entry, const char* target, UINT flags,
13 ComPtr<ID3DBlob>& outBlob) {
14
15 ComPtr<ID3DBlob> errorBlob;
16 HRESULT hr = D3DCompile( code, strlen(code), nullptr, nullptr, nullptr, entry, target, flags, 0,
17 &outBlob, &errorBlob);
18 if (FAILED(hr)) {
19 if (errorBlob) { std::cerr << (char*)errorBlob->GetBufferPointer() << std::endl; }
20 ThrowIfFailed(hr);
21 }
22}
23
24void InitUIResources( DX12ResourcesUI& uiRes, ID3D12Device* device) {
25 // Root signature
26 CD3DX12_ROOT_PARAMETER1 rootParams[1];
27 rootParams[0].InitAsConstantBufferView(0,0, D3D12_ROOT_DESCRIPTOR_FLAG_NONE, D3D12_SHADER_VISIBILITY_VERTEX);
28 CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootDesc;
29 rootDesc.Init_1_1( _countof(rootParams), rootParams, 0, nullptr,
30 D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
31
32 ComPtr<ID3DBlob> signature;
33 ComPtr<ID3DBlob> error;
34
35 D3DX12SerializeVersionedRootSignature( &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_1, &signature, &error);
36 ThrowIfFailed( device->CreateRootSignature( 0, signature->GetBufferPointer(), signature->GetBufferSize(),
37 IID_PPV_ARGS(&uiRes.uiRootSignature)));
38
39 // Shaders
40
41#if defined(_DEBUG)
42 UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
43#else
44 UINT compileFlags = 0;
45#endif
46
47 static const char* vsCode = R"(
48cbuffer OrthoConstantBuffer : register(b0) {
49 float4x4 ortho;
50};
51
52struct VSInput {
53 float2 position : POSITION;
54 float2 uv : TEXCOORD0;
55 uint color : COLOR0;
56};
57
58struct PSInput {
59 float4 position : SV_POSITION;
60 float2 uv : TEXCOORD0;
61 uint color : COLOR0;
62};
63
64PSInput VSMain(VSInput input) {
65 PSInput output;
66 float4 pos = float4(input.position,0,1);
67 output.position = mul(pos,ortho);
68 output.uv = input.uv;
69 output.color = input.color;
70 return output;
71}
72)";
73
74 static const char* psCode = R"(
75struct PSInput {
76 float4 position : SV_POSITION;
77 float2 uv : TEXCOORD0;
78 uint color : COLOR0;
79};
80
81float4 PSMain(PSInput input) : SV_TARGET {
82 float r = ((input.color >> 0) & 0xFF) / 255.0;
83 float g = ((input.color >> 8) & 0xFF) / 255.0;
84 float b = ((input.color >> 16) & 0xFF) / 255.0;
85 float a = ((input.color >> 24) & 0xFF) / 255.0;
86 return float4(r,g,b,a);
87}
88)";
89
90 ComPtr<ID3DBlob> vsBlob;
91 ComPtr<ID3DBlob> psBlob;
92 CompileShader(vsCode, "VSMain", "vs_5_0", compileFlags, vsBlob);
93 CompileShader(psCode, "PSMain", "ps_5_0", compileFlags, psBlob);
94 // Input layout
95
96 D3D12_INPUT_ELEMENT_DESC layout[] = {
97 { "POSITION",0,DXGI_FORMAT_R32G32_FLOAT,0,0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,0 },
98 { "TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,0 },
99 { "COLOR",0,DXGI_FORMAT_R32_UINT,0,16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,0 }
100 };
101
102 // PSO
103 D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
104 psoDesc.InputLayout = { layout,_countof(layout) };
105 psoDesc.pRootSignature = uiRes.uiRootSignature.Get();
106 psoDesc.VS = CD3DX12_SHADER_BYTECODE(vsBlob.Get());
107 psoDesc.PS = CD3DX12_SHADER_BYTECODE(psBlob.Get());
108 psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
109 psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
110 psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
111 psoDesc.BlendState.RenderTarget[0].BlendEnable = TRUE;
112 psoDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
113 psoDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
114 psoDesc.DepthStencilState.DepthEnable = FALSE;
115 psoDesc.SampleMask = UINT_MAX;
116 psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
117 psoDesc.NumRenderTargets = 1;
118 psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
119 psoDesc.SampleDesc.Count = 1;
120
121 ThrowIfFailed( device->CreateGraphicsPipelineState( &psoDesc, IID_PPV_ARGS(&uiRes.uiPSO)));
122
123 // Vertex buffer
124 auto uploadHeap = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
125
126 auto vbDesc = CD3DX12_RESOURCE_DESC::Buffer( uiRes.maxVertices * sizeof(UIVertex));
127 ThrowIfFailed( device->CreateCommittedResource( &uploadHeap, D3D12_HEAP_FLAG_NONE, &vbDesc,
128 D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uiRes.uiVertexBuffer)));
129
130 auto ibDesc = CD3DX12_RESOURCE_DESC::Buffer( uiRes.maxIndices * sizeof(uint16_t));
131 ThrowIfFailed( device->CreateCommittedResource( &uploadHeap, D3D12_HEAP_FLAG_NONE, &ibDesc,
132 D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uiRes.uiIndexBuffer)));
133
134 auto cbDesc = CD3DX12_RESOURCE_DESC::Buffer(256);
135 ThrowIfFailed( device->CreateCommittedResource( &uploadHeap, D3D12_HEAP_FLAG_NONE, &cbDesc,
136 D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uiRes.uiOrthoConstantBuffer)));
137
138 CD3DX12_RANGE readRange(0, 0);
139 uiRes.uiVertexBuffer->Map( 0, &readRange, reinterpret_cast<void**>(&uiRes.pVertexDataBegin));
140 uiRes.uiIndexBuffer->Map( 0, &readRange, reinterpret_cast<void**>(&uiRes.pIndexDataBegin));
141 uiRes.uiOrthoConstantBuffer->Map( 0, &readRange, reinterpret_cast<void**>(&uiRes.pOrthoDataBegin));
142 std::wcout << L"UI Resources Initialized (Phase 4A)\n";
143}
144
145// Cleanup
146void CleanupUIResources(DX12ResourcesUI& uiRes) {
147 if (uiRes.uiVertexBuffer) uiRes.uiVertexBuffer->Unmap(0, nullptr);
148 if (uiRes.uiIndexBuffer) uiRes.uiIndexBuffer->Unmap(0, nullptr);
149 if (uiRes.uiOrthoConstantBuffer) uiRes.uiOrthoConstantBuffer->Unmap(0, nullptr);
150
151 uiRes = {};
152}
153
154// PushRect
155void PushRect( UIDrawContext& ctx, float x, float y, float w, float h,
156 uint32_t color, DX12ResourcesUI& uiRes) {
157 if (ctx.vertexCount + 4 > uiRes.maxVertices) return;
158 if (ctx.indexCount + 6 > uiRes.maxIndices) return;
159
160 uint16_t base = ctx.vertexCount;
161
162 ctx.vertexPtr[0] = { x,y,0,0,color };
163 ctx.vertexPtr[1] = { x + w,y,0,0,color };
164 ctx.vertexPtr[2] = { x + w,y + h,0,0,color };
165 ctx.vertexPtr[3] = { x,y + h,0,0,color };
166
167 ctx.indexPtr[0] = base + 0;
168 ctx.indexPtr[1] = base + 1;
169 ctx.indexPtr[2] = base + 2;
170 ctx.indexPtr[3] = base + 0;
171 ctx.indexPtr[4] = base + 2;
172 ctx.indexPtr[5] = base + 3;
173
174 ctx.vertexPtr += 4;
175 ctx.indexPtr += 6;
176 ctx.vertexCount += 4;
177 ctx.indexCount += 6;
178}
179
180// Returns true if clicked this frame
181bool PushInteractiveRect(UIDrawContext& ctx, float x, float y, float w, float h, uint32_t baseColor,
182 uint32_t id, const UIInput& input, DX12ResourcesUI& uiRes, bool enabled = true) {
183 uint32_t color = baseColor;
184
185 bool hovered = enabled && (input.mouseX >= x && input.mouseX < x + w &&
186 input.mouseY >= y && input.mouseY < y + h);
187
188 if (hovered) color = 0xFF555555; // hover tint (TODO: theme-aware)
189 if (hovered && input.leftButtonDown) color = 0xFF333333; // pressed tint
190 if (!enabled) color = 0xFF1E1E1E; // If disabled, force a darker/grayer base color
191
192 PushRect(ctx, x, y, w, h, color, uiRes);
193
194 if (!enabled) return false;// Disabled controls do NOT respond to clicks
195 if (hovered && input.leftButtonPressedThisFrame) {
196 return true;
197 }
198 return false;
199}
200
201// Convenience for tabs (fixed width for now)
202bool PushTab(UIDrawContext& ctx, float x, float w, float h, uint16_t tabID, bool isActive,
203 const UIInput& input, DX12ResourcesUI& uiRes) {
204
205 uint32_t color = isActive ? COLOR_UI_TAB_ACTIVE : COLOR_UI_TAB_INACTIVE;
206 uint32_t actionID = 0x10000000u | tabID; // high bit = tab family
207
208 if (PushInteractiveRect(ctx, x, 0, w, h, color, actionID, input, uiRes)) {
209 // Optional immediate feedback (UI thread)
210 // window.activeTabIndex = tabID; // you can still do it here if you want instant visual
211 return true;
212 }
213 return false;
214}
215
216// This function renders the list of tabs, all top menu buttons (with dropdowns if required),
217// side favourite / frequent buttons bars, right side property window, bottom status bar.
218// This is also responsible for all relevant DirectX12 configurations required for rendering User Interface.
219void RenderUIOverlay(SingleUIWindow& window, ID3D12GraphicsCommandList* cmd, DX12ResourcesUI& uiRes,
220 float monitorDPI, const UIInput& input) {
221
222 if (!cmd) return; //Defensive check.
223
224 cmd->SetPipelineState(uiRes.uiPSO.Get());
225 cmd->SetGraphicsRootSignature(uiRes.uiRootSignature.Get());
226
227 float W = (float)window.dx.WindowWidth;
228 float H = (float)window.dx.WindowHeight;
229 float* ortho = (float*)uiRes.pOrthoDataBegin;
230
231 ortho[0] = 2 / W; ortho[1] = 0; ortho[2] = 0; ortho[3] = -1;
232 ortho[4] = 0; ortho[5] = -2 / H; ortho[6] = 0; ortho[7] = 1;
233 ortho[8] = 0; ortho[9] = 0; ortho[10] = 1; ortho[11] = 0;
234 ortho[12] = 0; ortho[13] = 0; ortho[14] = 0; ortho[15] = 1;
235
236 cmd->SetGraphicsRootConstantBufferView( 0, uiRes.uiOrthoConstantBuffer->GetGPUVirtualAddress());
237
238 UIDrawContext ctx;
239 ctx.vertexPtr = reinterpret_cast<UIVertex*>(uiRes.pVertexDataBegin);
240 ctx.indexPtr = reinterpret_cast<uint16_t*>(uiRes.pIndexDataBegin);
241 ctx.vertexCount = 0;
242 ctx.indexCount = 0;
243 float pixelsPerMM = monitorDPI / 25.4f;
244 float buttonWidthPx = UI_BUTTON_WIDTH_MM * pixelsPerMM;
245 float tabBarHeight = UI_TAB_BAR_HEIGHT_MM * pixelsPerMM;
246 float ribbonY = tabBarHeight + UI_DIVIDER_WIDTH_PX; // ← only one declaration
247
248 // ENGINEERING / PROJECT TABs
249 float tabWidth = 120.0f;
250 float currentX = 0.0f;
251
252 uint16_t tabCount = publishedTabCount.load(std::memory_order_acquire);
253 uint16_t* tabList = publishedTabIndexes.load(std::memory_order_acquire);
254
255 for (uint16_t i = 0; i < tabCount; i++) {
256 uint16_t tabID = tabList[i];
257 bool active = (window.activeTabIndex == tabID);
258 if (PushTab(ctx, currentX, tabWidth, tabBarHeight, tabID, active, input, uiRes)) {
259 window.activeTabIndex = tabID; // instant visual feedback
260 }
261 currentX += tabWidth;
262 }
263
264 // TOP BUTTONS (ACTION GROUP BAR)
265 currentX = 20.0f; // reset X for action groups
266
267 const float buttonBaseHeight = 32.0f;
268 const float buttonGap = 4.0f;
269 const float subGroupGap = 18.0f;
270 const float groupGap = 28.0f;
271
272 uint32_t currentActionGroupIndex = 0xFFFFFFFF;
273 uint32_t currentSubGroupID = 0xFFFFFFFF;
274
275 float groupLabelY = ribbonY;
276 float subGroupLabelY = ribbonY + 18.0f;
277
278 for (size_t i = 0; i < TotalUIControls; ++i) {
279 const auto& ctrl = AllUIControls[i];
280
281 if (ctrl.actionGrpupIndex != currentActionGroupIndex) { // Action Group change
282 if (currentActionGroupIndex != 0xFFFFFFFF) currentX += groupGap;
283 currentActionGroupIndex = ctrl.actionGrpupIndex;
284 currentSubGroupID = 0xFFFFFFFF;
285
286 PushRect(ctx, currentX, groupLabelY, 6, 48, 0xFF555555, uiRes); // group separator
287 currentX += 12.0f;
288 }
289
290 if (ctrl.actionSubGroupID != currentSubGroupID) { // Sub-Group change
291 if (currentSubGroupID != 0xFFFFFFFF) {currentX += subGroupGap;}
292 currentSubGroupID = ctrl.actionSubGroupID;
293
294 PushRect(ctx, currentX, subGroupLabelY, 110, 16, 0xFF2D2D30, uiRes); // sub-group label bar
295 currentX += 8.0f;
296 }
297
298 // Button geometry (vertical stacking support)
299 float btnWidth = (ctrl.defaultWidthPX > 0)
300 ? ctrl.defaultWidthPX * pixelsPerMM / 25.4f // interpret as mm
301 : buttonWidthPx;
302 float btnHeight = buttonBaseHeight * ctrl.noOfVerticalSlots;
303 float btnY = ribbonY + 38.0f;
304
305 if (ctrl.noOfVerticalSlots > 1) {btnY += ctrl.verticalSlotNo * buttonBaseHeight;}
306 uint32_t baseColor = ctrl.isEnabled ? 0xFF2D2D30 : 0xFF1E1E1E;// Render
307
308 if (ctrl.type == 1 || ctrl.type == 2) { // Button or Dropdown trigger
309 bool clicked = PushInteractiveRect(ctx, currentX, btnY, btnWidth, btnHeight,
310 baseColor, (uint32_t)ctrl.action, input, uiRes, ctrl.isEnabled);
311
312 if (clicked && ctrl.isEnabled) {
313 PushUIAction((uint32_t)ctrl.action);
314 if (ctrl.zIndex == 1) { // Dropdown trigger
315 window.activeDropdownAction = ctrl.action;
316 }
317 }
318
319 if (!ctrl.isEnabled) { // Gray-out overlay for disabled controls
320 PushRect(ctx, currentX, btnY, btnWidth, btnHeight, 0xAA333333, uiRes);
321 }
322 }
323 else if (ctrl.type == 3) {
324 // Future textbox
325 PushRect(ctx, currentX, btnY, btnWidth, btnHeight, 0xFF1E1E1E, uiRes);
326 }
327 else {
328 // Plain label
329 PushRect(ctx, currentX, btnY, btnWidth, btnHeight, 0xFF2D2D30, uiRes);
330 }
331
332 currentX += btnWidth + buttonGap;
333 }
334
335 currentX += 30.0f;// Final padding
336
337 // ACTIVE DROPDOWN (placeholder)
338 if (window.activeDropdownAction != UIAction::INVALID) {
339 float dropX = 400.0f; // TODO: track real button X for proper positioning
340 float dropY = ribbonY + 80.0f;
341 PushRect(ctx, dropX, dropY, 160, 220, 0xFF1E1E1E, uiRes);
342 window.activeDropdownAction = UIAction::INVALID; // immediate-mode auto-close
343 }
344
345 // DRAW ALL UI GEOMETRY
346 if (ctx.indexCount == 0) return;
347
348 D3D12_VERTEX_BUFFER_VIEW vbv{};
349 vbv.BufferLocation = uiRes.uiVertexBuffer->GetGPUVirtualAddress();
350 vbv.SizeInBytes = ctx.vertexCount * sizeof(UIVertex);
351 vbv.StrideInBytes = sizeof(UIVertex);
352
353 D3D12_INDEX_BUFFER_VIEW ibv{};
354 ibv.BufferLocation = uiRes.uiIndexBuffer->GetGPUVirtualAddress();
355 ibv.SizeInBytes = ctx.indexCount * sizeof(uint16_t);
356 ibv.Format = DXGI_FORMAT_R16_UINT;
357
358 cmd->IASetVertexBuffers(0, 1, &vbv);
359 cmd->IASetIndexBuffer(&ibv);
360 cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
361 cmd->DrawIndexedInstanced(ctx.indexCount, 1, 0, 0, 0);
362}Miscellaneous philosophy:
Renderer must support these scripts:
| Script | Languages |
|---|---|
| Latin | English, German, French, Spanish, Portuguese, Polish, Dutch, Swedish, Italian |
| Cyrillic | Russian, Ukrainian |
| CJK | Chinese, Japanese |
| Hangul | Korean |
| Arabic | Urdu |
| Indic | Hindi, Bengali, Telugu, Tamil, etc |
| Thai | Thai |
| Vietnamese | Latin + diacritics |
Recommended Font Families: NotoSans-Regular NotoSansCJK-Regular NotoSansDevanagari NotoSansTamil NotoSansTelugu NotoSansThai NotoSansArabic NotoSansHebrew