#include "osgui_win.inl"
#include "oscontrol_win.inl"
#include "ospanel_win.inl"
#include "../osprogress.h"
#include <core/heap.h>
#include <sewer/cassert.h>
#if !defined(__WINDOWS__)
#error This file is only for Windows
#endif
#include <sewer/nowarn.hxx>
#include <Commctrl.h>
#include <sewer/warn.hxx>
struct _osprogress_t
{
OSControl control;
real32_t last_position;
};
static const uint16_t i_MAX_RANGE = 32768;
OSProgress *osprogress_create(const uint32_t flags)
{
OSProgress *progress = NULL;
DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS;
cassert_unref(progress_get_type(flags) == ekPROGRESS_HORZ, flags);
progress = heap_new(OSProgress);
progress->control.type = ekGUI_TYPE_PROGRESS;
progress->last_position = 0.f;
_oscontrol_init(cast(progress, OSControl), PARAM(dwExStyle, 0), dwStyle, PROGRESS_CLASS, 0, 0, NULL, kDEFAULT_PARENT_WINDOW);
SendMessage(progress->control.hwnd, PBM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG(0, i_MAX_RANGE));
return progress;
}
void osprogress_destroy(OSProgress **progress)
{
cassert_no_null(progress);
cassert_no_null(*progress);
_oscontrol_destroy(&(*progress)->control);
heap_delete(progress, OSProgress);
}
void osprogress_position(OSProgress *progress, const real32_t position)
{
DWORD dwStyle = 0;
cassert_no_null(progress);
dwStyle = GetWindowLong(progress->control.hwnd, GWL_STYLE);
if (position < 0.f)
{
BOOL current_running = progress->last_position < -1.f;
BOOL running = FALSE;
if ((dwStyle & PBS_MARQUEE) != PBS_MARQUEE)
{
dwStyle |= PBS_MARQUEE;
SetWindowLong(progress->control.hwnd, GWL_STYLE, dwStyle);
}
if (position < -1.f)
running = TRUE;
if (running != current_running)
SendMessage(progress->control.hwnd, PBM_SETMARQUEE, (WPARAM)running, (LPARAM)0);
}
else
{
DWORD pos = 0;
cassert(position <= 1.f);
if ((dwStyle & PBS_MARQUEE) == PBS_MARQUEE)
{
dwStyle &= ~PBS_MARQUEE;
SetWindowLong(progress->control.hwnd, GWL_STYLE, dwStyle);
}
pos = (DWORD)(position * (real32_t)i_MAX_RANGE);
SendMessage(progress->control.hwnd, PBM_SETPOS, (WPARAM)pos, (LPARAM)0);
}
progress->last_position = position;
}
real32_t osprogress_thickness(const OSProgress *progress, const gui_size_t size)
{
unref(progress);
switch (size)
{
case ekGUI_SIZE_REGULAR:
case ekGUI_SIZE_SMALL:
return 15.f;
case ekGUI_SIZE_MINI:
return 10.f;
cassert_default();
}
return 0.f;
}
void osprogress_attach(OSProgress *progress, OSPanel *panel)
{
_ospanel_attach_control(panel, cast(progress, OSControl));
}
void osprogress_detach(OSProgress *progress, OSPanel *panel)
{
_ospanel_detach_control(panel, cast(progress, OSControl));
}
void osprogress_visible(OSProgress *progress, const bool_t visible)
{
_oscontrol_set_visible(cast(progress, OSControl), visible);
}
void osprogress_enabled(OSProgress *progress, const bool_t enabled)
{
_oscontrol_set_enabled(cast(progress, OSControl), enabled);
}
void osprogress_size(const OSProgress *progress, real32_t *width, real32_t *height)
{
_oscontrol_get_size(cast_const(progress, OSControl), width, height);
}
void osprogress_origin(const OSProgress *progress, real32_t *x, real32_t *y)
{
_oscontrol_get_origin(cast_const(progress, OSControl), x, y);
}
void osprogress_frame(OSProgress *progress, const real32_t x, const real32_t y, const real32_t width, const real32_t height)
{
_oscontrol_set_frame(cast(progress, OSControl), x, y, width, height);
}