Windows 98 style

This commit is contained in:
Jake Coxon 2020-07-20 20:54:35 +01:00
parent e223bd8177
commit 1945f456f1
7 changed files with 336 additions and 1 deletions

BIN
MS Sans Serif Bold.ttf Normal file

Binary file not shown.

BIN
MS Sans Serif.ttf Normal file

Binary file not shown.

View File

@ -13,6 +13,8 @@
#pragma once
#define WIN98
//---- Define assertion handler. Defaults to calling assert().
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)

111
imgui.cpp
View File

@ -2664,8 +2664,12 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border,
const float border_size = g.Style.FrameBorderSize;
if (border && border_size > 0.0f)
{
#ifdef WIN98
WinAddRect(p_min, p_max, true);
#else
window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
#endif
}
}
@ -5165,11 +5169,57 @@ static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& visibility
window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max);
}
void ImGui::WinAddRect(const ImVec2& min, const ImVec2& max, bool inset)
{
ImU32 top_left = IM_COL32(255,255,255,255);
ImU32 bottom_right = IM_COL32(0,0,0,255);
ImU32 top_left_inner = IM_COL32(223,223,223,255);
ImU32 bottom_right_inner = IM_COL32(128,128,128,255);
if (inset) {
ImU32 tmp = top_left; top_left = bottom_right; bottom_right = tmp;
tmp = top_left_inner; top_left_inner = bottom_right_inner; bottom_right_inner = tmp;
}
// ImU32 fill_col = IM_COL32(192,192,192,255);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 a = min + ImVec2(0.5f, 0.5f);
ImVec2 b = max - ImVec2(0.5f, 0.5f);
draw_list->PathLineTo(ImVec2(a.x, b.y));
draw_list->PathLineTo(a);
draw_list->PathLineTo(ImVec2(b.x, a.y));
draw_list->PathStroke(top_left, false, 1.0f);
draw_list->PathLineTo(ImVec2(a.x, b.y));
draw_list->PathLineTo(b);
draw_list->PathLineTo(ImVec2(b.x, a.y));
draw_list->PathStroke(bottom_right, false, 1.0f);
draw_list->PathLineTo(ImVec2(a.x, b.y) + ImVec2(1, -1));
draw_list->PathLineTo(a + ImVec2(1, 1));
draw_list->PathLineTo(ImVec2(b.x, a.y) + ImVec2(-1, 1));
draw_list->PathStroke(top_left_inner, false, 1.0f);
draw_list->PathLineTo(ImVec2(a.x, b.y) + ImVec2(1, -1));
draw_list->PathLineTo(b + ImVec2(-1, -1));
draw_list->PathLineTo(ImVec2(b.x, a.y) + ImVec2(-1, 1));
draw_list->PathStroke(bottom_right_inner, false, 1.0f);
}
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
float rounding = window->WindowRounding;
float border_size = window->WindowBorderSize;
#ifdef WIN98 // window borders
if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
WinAddRect(window->Pos, window->Pos + window->Size, false);
#else
if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
@ -5187,6 +5237,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
float y = window->Pos.y + window->TitleBarHeight() - 1;
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), GetColorU32(ImGuiCol_Border), g.Style.FrameBorderSize);
}
#endif
}
// Draw background and borders
@ -5294,6 +5345,11 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
float pad_l = style.FramePadding.x;
float pad_r = style.FramePadding.x;
float button_sz = g.FontSize;
#ifdef WIN98 // draw title bar
button_sz = 16.0f;
// pad_l = 0.0f;
pad_r = 0.0f;
#endif
ImVec2 close_button_pos;
ImVec2 collapse_button_pos;
if (has_close_button)
@ -5312,6 +5368,38 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
pad_l += button_sz;
}
#ifdef WIN98 // windows style title bar
close_button_pos += ImVec2(0.0f, 2.0f);
collapse_button_pos += ImVec2(0.0f, 2.0f);
ImU32 col_left = IM_COL32(128,128,128,255);
ImU32 col_right = IM_COL32(181,181,181,255);
bool focused = IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
if (focused) {
// Windows98 colors are (0,0,128), (16,132,208)
// This code generates the secondary color from the primary while
// keeping the original windows colors
col_left = GetColorU32(ImGuiCol_TitleBgActive);
ImVec4 secondary = GetStyleColorVec4(ImGuiCol_TitleBgActive);
ImVec4 secondary_hsv;
ColorConvertRGBtoHSV(secondary.x, secondary.y, secondary.z, secondary_hsv.x, secondary_hsv.y, secondary_hsv.z);
secondary_hsv.x -= 0.1f;
if (secondary_hsv.x < 0.0f) secondary_hsv.x += 1.0f;
secondary_hsv.y *= 0.92f;
secondary_hsv.z *= 1.625f;
ColorConvertHSVtoRGB(secondary_hsv.x, secondary_hsv.y, secondary_hsv.z, secondary.x, secondary.y, secondary.z);
col_right = ColorConvertFloat4ToU32(secondary);
}
window->DrawList->AddRectFilledMultiColor(title_bar_rect.Min, title_bar_rect.Max, col_left, col_right, col_right, col_left);
#endif
// Collapse button (submitting first so it gets priority when choosing a navigation init fallback)
if (has_collapse_button)
if (CollapseButton(window->GetID("#COLLAPSE"), collapse_button_pos))
@ -5346,6 +5434,14 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
pad_r = ImMax(pad_r, pad_extend * centerness);
}
#ifdef WIN98 // windows title font
if (focused) PushStyleColor(ImGuiCol_Text, IM_COL32(255,255,255,255));
else PushStyleColor(ImGuiCol_Text, IM_COL32(192,192,192,255));
ImGuiIO& io = ImGui::GetIO();
ImFont* font = io.Fonts->Fonts[1]; // Assume the icon font is here. pretty bad
PushFont(font);
#endif
ImRect layout_r(title_bar_rect.Min.x + pad_l, title_bar_rect.Min.y, title_bar_rect.Max.x - pad_r, title_bar_rect.Max.y);
ImRect clip_r(layout_r.Min.x, layout_r.Min.y, layout_r.Max.x + g.Style.ItemInnerSpacing.x, layout_r.Max.y);
//if (g.IO.KeyCtrl) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
@ -5356,6 +5452,11 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
ImVec2 off = ImVec2(0.0f, IM_FLOOR(-g.FontSize * 0.25f));
RenderTextClipped(marker_pos + off, layout_r.Max + off, UNSAVED_DOCUMENT_MARKER, NULL, NULL, ImVec2(0, style.WindowTitleAlign.y), &clip_r);
}
#ifdef WIN98
PopFont();
PopStyleColor();
#endif
}
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
@ -5937,8 +6038,16 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
// Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar))
if (!(flags & ImGuiWindowFlags_NoTitleBar)) {
#ifdef WIN98 // title bar sizing
ImRect inset_title_rect = title_bar_rect;
inset_title_rect.Min += ImVec2(2.0f, 2.0f);
inset_title_rect.Max -= ImVec2(2.0f, 0.0f);
RenderWindowTitleBarContents(window, inset_title_rect, name, p_open);
#else
RenderWindowTitleBarContents(window, title_bar_rect, name, p_open);
#endif
}
// Pressing CTRL+C while holding on a window copy its content to the clipboard
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.

View File

@ -776,6 +776,11 @@ namespace ImGui
IMGUI_API void* MemAlloc(size_t size);
IMGUI_API void MemFree(void* ptr);
// Windows98 functions
IMGUI_API void WinAddRect(const ImVec2& min, const ImVec2& max, bool inset);
IMGUI_API void StyleWin98(ImGuiStyle* dst = NULL);
} // namespace ImGui
//-----------------------------------------------------------------------------

View File

@ -174,6 +174,12 @@ using namespace IMGUI_STB_NAMESPACE;
void ImGui::StyleColorsDark(ImGuiStyle* dst)
{
#ifdef WIN98
// These colors don't make sense with win98 so just call this anyway
// also means I don't have to change all the examples
StyleWin98(dst);
return;
#endif
ImGuiStyle* style = dst ? dst : &ImGui::GetStyle();
ImVec4* colors = style->Colors;
@ -229,6 +235,12 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
void ImGui::StyleColorsClassic(ImGuiStyle* dst)
{
#ifdef WIN98
// These colors don't make sense with win98 so just call this anyway
// also means I don't have to change all the examples
StyleWin98(dst);
return;
#endif
ImGuiStyle* style = dst ? dst : &ImGui::GetStyle();
ImVec4* colors = style->Colors;
@ -285,6 +297,13 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
// Those light colors are better suited with a thicker font than the default one + FrameBorder
void ImGui::StyleColorsLight(ImGuiStyle* dst)
{
#ifdef WIN98
// These colors don't make sense with win98 so just call this anyway
// also means I don't have to change all the examples
StyleWin98(dst);
return;
#endif
ImGuiStyle* style = dst ? dst : &ImGui::GetStyle();
ImVec4* colors = style->Colors;
@ -338,6 +357,128 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
}
// Windows style config
#ifdef WIN98
void ImGui::StyleWin98(ImGuiStyle* dst)
{
ImGuiStyle* style = dst ? dst : &ImGui::GetStyle();
style->FrameBorderSize = 1.0f;
style->FramePadding = ImVec2(4.0f, 4.0f);
style->WindowMenuButtonPosition = ImGuiDir_Right;
style->ScrollbarSize = 16.0f;
ImVec4* colors = style->Colors;
colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.00f, 0.00f, 0.50f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f);
colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImVec4(0.76f, 0.80f, 0.84f, 0.95f);
colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_TabActive] = ImVec4(0.60f, 0.73f, 0.88f, 0.95f);
colors[ImGuiCol_TabUnfocused] = ImVec4(0.92f, 0.92f, 0.94f, 0.95f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.74f, 0.82f, 0.91f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
if (dst != NULL) return;
// Fonts + Icons
ImGuiIO& io = ImGui::GetIO();
for (int i = 0; i < io.Fonts->ConfigData.size(); i++) {
if (strcmp(io.Fonts->ConfigData[i].Name, "MS Sans Serif")) {
return;
}
}
ImFont *font = io.Fonts->AddFontFromFileTTF("../../MS Sans Serif.ttf", 12.0f, NULL, io.Fonts->GetGlyphRangesDefault());
io.Fonts->AddFontFromFileTTF("../../MS Sans Serif Bold.ttf", 12.0f, NULL, io.Fonts->GetGlyphRangesDefault());
// Run-length encoding of some icons
// In retrorespect I should have used an icon map like FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS
unsigned char minimize[] = {86,6,6,6,0};
unsigned char close[] = {14,2,4,2,5,2,2,2,7,4,9,2,9,4,7,2,2,2,5,2,4,2,0};
unsigned char *run_length[] = {minimize, close};
int rect_ids[IM_ARRAYSIZE(run_length)];
for (int i = 0; i < IM_ARRAYSIZE(run_length); i++) {
rect_ids[i] = io.Fonts->AddCustomRectFontGlyph(font, 214 + i, 12, 9, 13+1);
}
io.Fonts->Build();
unsigned char* tex_pixels = NULL;
int tex_width, tex_height;
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height);
for (int i = 0; i < IM_ARRAYSIZE(run_length); i++) {
int rect_id = rect_ids[i];
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
bool black = false;
unsigned char* run = run_length[i];
int run_size = 0;
for (int y = 0; y < rect->Height; y++)
{
ImU32* p = (ImU32*)tex_pixels + (rect->Y + y) * tex_width + (rect->X);
for (int x = rect->Width; x > 0; x--) {
if (black) *p = IM_COL32(255, 0, 0, 255);
p ++;
run_size ++;
if (run_size == *run) {
run_size = 0;
run ++;
black = !black;
if (*run == 0) goto done;
}
}
}
done:;
}
}
}
#endif
//-----------------------------------------------------------------------------
// ImDrawList
//-----------------------------------------------------------------------------

View File

@ -668,9 +668,19 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
// Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
#ifdef WIN98
const ImU32 fill_col = GetColorU32(ImGuiCol_WindowBg);
window->DrawList->AddRectFilled(bb.Min, bb.Max, fill_col, 0.0f);
WinAddRect(bb.Min, bb.Max, (held && hovered));
PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
PopStyleColor();
#else
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
#endif
// Automatically close popups
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
@ -762,9 +772,13 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
#ifdef WIN98 // close button size
const ImRect bb(pos, pos + ImVec2(16.0f, 14.0f));
#else
// We intentionally allow interaction when clipped so that a mechanical Alt,Right,Validate sequence close a window.
// (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible).
const ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f);
#endif
bool is_clipped = !ItemAdd(bb, id);
bool hovered, held;
@ -775,14 +789,25 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size)
// Render
ImU32 col = GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered);
ImVec2 center = bb.GetCenter();
#ifdef WIN98 // close button
const ImU32 fill_col = GetColorU32(ImGuiCol_WindowBg);
window->DrawList->AddRectFilled(bb.Min, bb.Max, fill_col, 0.0f);
WinAddRect(bb.Min, bb.Max, hovered && held);
#else
if (hovered)
window->DrawList->AddCircleFilled(center, ImMax(2.0f, g.FontSize * 0.5f + 1.0f), col, 12);
#endif
float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f;
ImU32 cross_col = GetColorU32(ImGuiCol_Text);
center -= ImVec2(0.5f, 0.5f);
#ifdef WIN98 // close button icon
RenderText(bb.Min + ImVec2(2.0f, 2.0f), "\u00D7");
#else
window->DrawList->AddLine(center + ImVec2(+cross_extent, +cross_extent), center + ImVec2(-cross_extent, -cross_extent), cross_col, 1.0f);
window->DrawList->AddLine(center + ImVec2(+cross_extent, -cross_extent), center + ImVec2(-cross_extent, +cross_extent), cross_col, 1.0f);
#endif
return pressed;
}
@ -792,7 +817,11 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
#ifdef WIN98 // collapse button size
ImRect bb(pos, pos + ImVec2(16.0f, 14.0f));
#else
ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f);
#endif
ItemAdd(bb, id);
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None);
@ -801,9 +830,19 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
ImU32 text_col = GetColorU32(ImGuiCol_Text);
ImVec2 center = bb.GetCenter();
#ifdef WIN98 // collapse button
const ImU32 fill_col = GetColorU32(ImGuiCol_WindowBg);
window->DrawList->AddRectFilled(bb.Min, bb.Max, fill_col, 0.0f);
WinAddRect(bb.Min, bb.Max, hovered && held);
// collapse icon
RenderText(bb.Min + ImVec2(2.0f, 2.0f), "\u00D6");
#else
if (hovered || held)
window->DrawList->AddCircleFilled(center/*+ ImVec2(0.0f, -0.5f)*/, g.FontSize * 0.5f + 1.0f, bg_col, 12);
RenderArrow(window->DrawList, bb.Min + g.Style.FramePadding, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
#endif
// Switch to moving the window after mouse is moved beyond the initial drag threshold
if (IsItemActive() && IsMouseDragging(0))
@ -888,8 +927,19 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
const ImGuiStyle& style = g.Style;
const bool allow_interaction = (alpha >= 1.0f);
#ifdef WIN98
ImRect bb = bb_frame;
float button_size = (axis == ImGuiAxis_X) ? bb.GetHeight() : bb.GetWidth();
ImVec2 button_size_rect(button_size, button_size);
ImVec2 main_axis((axis == ImGuiAxis_X) ? 1.0f : 0.0f, (axis == ImGuiAxis_X) ? 0.0f : 1.0f);
ImVec2 main_axis_button_size = main_axis * button_size;
bb.Expand(main_axis * -button_size);
#else
ImRect bb = bb_frame;
bb.Expand(ImVec2(-ImClamp(IM_FLOOR((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_FLOOR((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f)));
#endif
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight();
@ -944,6 +994,33 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
}
// Render
#ifdef WIN98 // scrollbar
ImRect grab_rect;
if (axis == ImGuiAxis_X) {
grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y);
} else {
grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels);
}
WinAddRect(grab_rect.Min, grab_rect.Max, false);
{
const ImGuiID up_id = window->GetID("##scrollup");
ImRect button_bounds(bb_frame.Min, bb_frame.Min + button_size_rect);
bool held_up = false;
bool hovered_up = false;
bool pressed_up = ButtonBehavior(button_bounds, up_id, &hovered_up, &held_up, 0);
WinAddRect(button_bounds.Min, button_bounds.Max, (held_up && hovered_up));
}
{
const ImGuiID down_id = window->GetID("##scrolldown");
ImVec2 pos = bb_frame.Min + main_axis * (((axis == ImGuiAxis_X) ? bb_frame.GetWidth() : bb_frame.GetHeight()) - button_size);
ImRect button_bounds(pos, pos + button_size_rect);
bool held_down = false;
bool hovered_down = false;
bool pressed_down = ButtonBehavior(button_bounds, down_id, &hovered_down, &held_down, 0);
WinAddRect(button_bounds.Min, button_bounds.Max, (held_down && hovered_down));
}
#else
const ImU32 bg_col = GetColorU32(ImGuiCol_ScrollbarBg);
const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha);
window->DrawList->AddRectFilled(bb_frame.Min, bb_frame.Max, bg_col, window->WindowRounding, rounding_corners);
@ -953,6 +1030,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
else
grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels);
window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding);
#endif
return held;
}