Mission Vishwakarma Download Roadmap Pricing

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