Skip to content

Instantly share code, notes, and snippets.

@mikearmstrong001
Last active February 4, 2023 10:09
Show Gist options
  • Save mikearmstrong001/18e9a926476401aa1e1a to your computer and use it in GitHub Desktop.
Save mikearmstrong001/18e9a926476401aa1e1a to your computer and use it in GitHub Desktop.
// How I'm handling css-layout with ImGui
// Doesn't really scale for windows in windows but this isn't a problem I'm trying to solve
struct LayoutItem
{
const char *text;
ImVec2 p, d;
OnClickedFunc onClicked;
ImIcon icon;
};
struct LayoutContext
{
std::vector< css_node > nodes;
};
static bool LayoutIsDirty(void *context) {
(void)context; // remove unused warning
return true;
}
static css_dim_t LayoutMeasure(void *context, float /*width*/) {
ImVec2 ts = ImGui::CalcTextSize( (char*)context );
ImVec2 pad = ImGui::GetStyle().FramePadding;
css_dim_t dim;
dim.dimensions[CSS_WIDTH] = ts.x + pad.x*2.f;
dim.dimensions[CSS_HEIGHT] = ts.y + pad.y*2.f;
return dim;
}
css_node *LayoutGetChild( void *ctx, int idx )
{
LayoutContext *context = (LayoutContext*)ctx;
if ( idx < 0 || idx >= (int)context->nodes.size() )
return NULL;
return &context->nodes[idx];
}
void CSSLayoutButtons( const LayoutItem *items[], ImVec2 fixedDims, ImVec2 base, ImVec2 mn, ImVec2 mx )
{
ImVec2 pad = ImGui::GetStyle().FramePadding;
LayoutContext context;
for( int idx=0; items[idx].text; idx++ )
{
context.nodes.push_back( css_node() );
css_node &n = context.nodes.back();
memset( &n, 0, sizeof(n) );
init_css_node( &n );
n.context = (void*)text[idx];
n.is_dirty = LayoutIsDirty;
if ( fixedDims.x > 0.f && fixedDims.y > 0.f )
{
n.layout.dimensions[0] = fixedDims.x + pad.x * 4.f;
n.layout.dimensions[1] = fixedDims.y + pad.y * 4.f;
}
n.measure = LayoutMeasure;
n.style.flex_direction = CSS_FLEX_DIRECTION_ROW;
n.style.flex_wrap = CSS_WRAP;
}
css_node root;
memset( &root, 0, sizeof(root) );
init_css_node( &root );
root.context = &context;
root.get_child = LayoutGetChild;
root.children_count = context.nodes.size();
root.is_dirty = LayoutIsDirty;
root.style.dimensions[CSS_WIDTH] = mx.x - mn.x;
root.style.flex_direction = CSS_FLEX_DIRECTION_ROW;
root.style.flex_wrap = CSS_WRAP;
layoutNode( &root, mx.x - mn.x );
for( int idx=0; items[idx].text; idx++ )
{
items[idx].p = ImVec2(context.nodes[i].layout.position[0]+base.x+mn.x+pad.x*2.f,context.nodes[i].layout.position[1]+base.y+mn.y+pad.y*2.f);
items[idx].d = ImVec2(context.nodes[i].layout.dimensions[0]-pad.x*4.f,context.nodes[i].layout.dimensions[1]-pad.y*4.f);
}
}
CSSLayoutButtons( buttons, ImVec2(32.f,32.f), ImGui::GetWindowPos(), ImGui::GetWindowContentRegionMin(), ImGui::GetWindowContentRegionMax() );
for( int idx=0; buttons[idx].text; idx++ )
{
if ( ImGui::ImageButtonLayout(buttons[idx].text, buttons[idx].p, buttons[idx].d, buttons[idx].icon ) )
{
buttons[idx].onClicked( ... )
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment