Working on keyboard control of GUI.
This commit is contained in:
parent
458329408f
commit
cd8da88df7
5 changed files with 358 additions and 2 deletions
|
|
@ -121,7 +121,7 @@ void widgetOnKey(WindowT *win, int32_t key, int32_t mod) {
|
||||||
while (top > 0) {
|
while (top > 0) {
|
||||||
WidgetT *w = stack[--top];
|
WidgetT *w = stack[--top];
|
||||||
|
|
||||||
if (w->focused && (w->type == WidgetTextInputE || w->type == WidgetComboBoxE || w->type == WidgetDropdownE || w->type == WidgetAnsiTermE || w->type == WidgetTreeViewE)) {
|
if (w->focused && (w->type == WidgetTextInputE || w->type == WidgetComboBoxE || w->type == WidgetDropdownE || w->type == WidgetAnsiTermE || w->type == WidgetTreeViewE || w->type == WidgetListBoxE)) {
|
||||||
focus = w;
|
focus = w;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -150,6 +150,12 @@ void widgetOnKey(WindowT *win, int32_t key, int32_t mod) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle list box keyboard navigation
|
||||||
|
if (focus->type == WidgetListBoxE) {
|
||||||
|
widgetListBoxOnKey(focus, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle dropdown keyboard navigation
|
// Handle dropdown keyboard navigation
|
||||||
if (focus->type == WidgetDropdownE) {
|
if (focus->type == WidgetDropdownE) {
|
||||||
if (focus->as.dropdown.open) {
|
if (focus->as.dropdown.open) {
|
||||||
|
|
@ -672,6 +678,10 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) {
|
||||||
widgetCanvasOnMouse(hit, vx, vy);
|
widgetCanvasOnMouse(hit, vx, vy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hit->type == WidgetListBoxE && hit->enabled) {
|
||||||
|
widgetListBoxOnMouse(hit, root, vx, vy);
|
||||||
|
}
|
||||||
|
|
||||||
if (hit->type == WidgetDropdownE && hit->enabled) {
|
if (hit->type == WidgetDropdownE && hit->enabled) {
|
||||||
if (hit != closedPopup) {
|
if (hit != closedPopup) {
|
||||||
widgetDropdownOnMouse(hit);
|
widgetDropdownOnMouse(hit);
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ void widgetDropdownPaintPopup(WidgetT *w, DisplayT *d, const BlitOpsT *ops, cons
|
||||||
void widgetFramePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
void widgetFramePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
void widgetImagePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
void widgetImagePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
void widgetLabelPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
void widgetLabelPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
|
void widgetListBoxPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
void widgetProgressBarPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
void widgetProgressBarPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
void widgetRadioPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
void widgetRadioPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
void widgetSeparatorPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
void widgetSeparatorPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
|
||||||
|
|
@ -136,6 +137,7 @@ void widgetComboBoxCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
void widgetDropdownCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
void widgetDropdownCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
void widgetImageCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
void widgetImageCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
void widgetLabelCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
void widgetLabelCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
|
void widgetListBoxCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
void widgetProgressBarCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
void widgetProgressBarCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
void widgetRadioCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
void widgetRadioCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
void widgetSliderCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
void widgetSliderCalcMinSize(WidgetT *w, const BitmapFontT *font);
|
||||||
|
|
@ -164,6 +166,8 @@ void widgetCheckboxOnMouse(WidgetT *hit);
|
||||||
void widgetComboBoxOnMouse(WidgetT *hit, WidgetT *root, int32_t vx);
|
void widgetComboBoxOnMouse(WidgetT *hit, WidgetT *root, int32_t vx);
|
||||||
void widgetDropdownOnMouse(WidgetT *hit);
|
void widgetDropdownOnMouse(WidgetT *hit);
|
||||||
void widgetImageOnMouse(WidgetT *hit);
|
void widgetImageOnMouse(WidgetT *hit);
|
||||||
|
void widgetListBoxOnKey(WidgetT *w, int32_t key);
|
||||||
|
void widgetListBoxOnMouse(WidgetT *hit, WidgetT *root, int32_t vx, int32_t vy);
|
||||||
void widgetRadioOnMouse(WidgetT *hit);
|
void widgetRadioOnMouse(WidgetT *hit);
|
||||||
void widgetSliderOnMouse(WidgetT *hit, int32_t vx, int32_t vy);
|
void widgetSliderOnMouse(WidgetT *hit, int32_t vx, int32_t vy);
|
||||||
void widgetTabControlOnMouse(WidgetT *hit, WidgetT *root, int32_t vx, int32_t vy);
|
void widgetTabControlOnMouse(WidgetT *hit, WidgetT *root, int32_t vx, int32_t vy);
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,9 @@ void widgetCalcMinSizeTree(WidgetT *w, const BitmapFontT *font) {
|
||||||
case WidgetImageE:
|
case WidgetImageE:
|
||||||
widgetImageCalcMinSize(w, font);
|
widgetImageCalcMinSize(w, font);
|
||||||
break;
|
break;
|
||||||
|
case WidgetListBoxE:
|
||||||
|
widgetListBoxCalcMinSize(w, font);
|
||||||
|
break;
|
||||||
case WidgetImageButtonE:
|
case WidgetImageButtonE:
|
||||||
widgetImageButtonCalcMinSize(w, font);
|
widgetImageButtonCalcMinSize(w, font);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,43 @@
|
||||||
|
|
||||||
#include "widgetInternal.h"
|
#include "widgetInternal.h"
|
||||||
|
|
||||||
|
#define LISTBOX_BORDER 2
|
||||||
|
#define LISTBOX_PAD 2
|
||||||
|
#define LISTBOX_MIN_ROWS 4
|
||||||
|
#define LISTBOX_SB_W 14
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Prototypes
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
static void listBoxScrollbarThumb(int32_t trackLen, int32_t totalItems, int32_t visibleItems, int32_t scrollPos, int32_t *thumbPos, int32_t *thumbSize);
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// listBoxScrollbarThumb
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
static void listBoxScrollbarThumb(int32_t trackLen, int32_t totalItems, int32_t visibleItems, int32_t scrollPos, int32_t *thumbPos, int32_t *thumbSize) {
|
||||||
|
*thumbSize = (trackLen * visibleItems) / totalItems;
|
||||||
|
|
||||||
|
if (*thumbSize < LISTBOX_SB_W) {
|
||||||
|
*thumbSize = LISTBOX_SB_W;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*thumbSize > trackLen) {
|
||||||
|
*thumbSize = trackLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t maxScroll = totalItems - visibleItems;
|
||||||
|
|
||||||
|
if (maxScroll > 0) {
|
||||||
|
*thumbPos = ((trackLen - *thumbSize) * scrollPos) / maxScroll;
|
||||||
|
} else {
|
||||||
|
*thumbPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// wgtListBox
|
// wgtListBox
|
||||||
|
|
@ -44,7 +81,11 @@ void wgtListBoxSetItems(WidgetT *w, const char **items, int32_t count) {
|
||||||
w->as.listBox.itemCount = count;
|
w->as.listBox.itemCount = count;
|
||||||
|
|
||||||
if (w->as.listBox.selectedIdx >= count) {
|
if (w->as.listBox.selectedIdx >= count) {
|
||||||
w->as.listBox.selectedIdx = -1;
|
w->as.listBox.selectedIdx = count > 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->as.listBox.selectedIdx < 0 && count > 0) {
|
||||||
|
w->as.listBox.selectedIdx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,3 +101,297 @@ void wgtListBoxSetSelected(WidgetT *w, int32_t idx) {
|
||||||
|
|
||||||
w->as.listBox.selectedIdx = idx;
|
w->as.listBox.selectedIdx = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// widgetListBoxCalcMinSize
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
void widgetListBoxCalcMinSize(WidgetT *w, const BitmapFontT *font) {
|
||||||
|
int32_t maxItemW = font->charWidth * 8;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < w->as.listBox.itemCount; i++) {
|
||||||
|
int32_t iw = (int32_t)strlen(w->as.listBox.items[i]) * font->charWidth;
|
||||||
|
|
||||||
|
if (iw > maxItemW) {
|
||||||
|
maxItemW = iw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w->calcMinW = maxItemW + LISTBOX_PAD * 2 + LISTBOX_BORDER * 2 + LISTBOX_SB_W;
|
||||||
|
w->calcMinH = LISTBOX_MIN_ROWS * font->charHeight + LISTBOX_BORDER * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// widgetListBoxOnKey
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
void widgetListBoxOnKey(WidgetT *w, int32_t key) {
|
||||||
|
if (!w || w->type != WidgetListBoxE || w->as.listBox.itemCount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t sel = w->as.listBox.selectedIdx;
|
||||||
|
|
||||||
|
if (key == (0x50 | 0x100)) {
|
||||||
|
// Down arrow
|
||||||
|
if (sel < w->as.listBox.itemCount - 1) {
|
||||||
|
w->as.listBox.selectedIdx = sel + 1;
|
||||||
|
} else if (sel < 0) {
|
||||||
|
w->as.listBox.selectedIdx = 0;
|
||||||
|
}
|
||||||
|
} else if (key == (0x48 | 0x100)) {
|
||||||
|
// Up arrow
|
||||||
|
if (sel > 0) {
|
||||||
|
w->as.listBox.selectedIdx = sel - 1;
|
||||||
|
} else if (sel < 0) {
|
||||||
|
w->as.listBox.selectedIdx = 0;
|
||||||
|
}
|
||||||
|
} else if (key == (0x47 | 0x100)) {
|
||||||
|
// Home
|
||||||
|
w->as.listBox.selectedIdx = 0;
|
||||||
|
} else if (key == (0x4F | 0x100)) {
|
||||||
|
// End
|
||||||
|
w->as.listBox.selectedIdx = w->as.listBox.itemCount - 1;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll to keep selection visible
|
||||||
|
if (w->as.listBox.selectedIdx >= 0) {
|
||||||
|
AppContextT *ctx = (AppContextT *)w->window->widgetRoot->userData;
|
||||||
|
const BitmapFontT *font = &ctx->font;
|
||||||
|
int32_t innerH = w->h - LISTBOX_BORDER * 2;
|
||||||
|
int32_t visibleRows = innerH / font->charHeight;
|
||||||
|
|
||||||
|
if (w->as.listBox.selectedIdx < w->as.listBox.scrollPos) {
|
||||||
|
w->as.listBox.scrollPos = w->as.listBox.selectedIdx;
|
||||||
|
} else if (w->as.listBox.selectedIdx >= w->as.listBox.scrollPos + visibleRows) {
|
||||||
|
w->as.listBox.scrollPos = w->as.listBox.selectedIdx - visibleRows + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->onChange) {
|
||||||
|
w->onChange(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
wgtInvalidate(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// widgetListBoxOnMouse
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
void widgetListBoxOnMouse(WidgetT *hit, WidgetT *root, int32_t vx, int32_t vy) {
|
||||||
|
AppContextT *ctx = (AppContextT *)root->userData;
|
||||||
|
const BitmapFontT *font = &ctx->font;
|
||||||
|
|
||||||
|
int32_t innerH = hit->h - LISTBOX_BORDER * 2;
|
||||||
|
int32_t visibleRows = innerH / font->charHeight;
|
||||||
|
bool needSb = (hit->as.listBox.itemCount > visibleRows);
|
||||||
|
|
||||||
|
// Clamp scroll
|
||||||
|
int32_t maxScroll = hit->as.listBox.itemCount - visibleRows;
|
||||||
|
|
||||||
|
if (maxScroll < 0) {
|
||||||
|
maxScroll = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit->as.listBox.scrollPos > maxScroll) {
|
||||||
|
hit->as.listBox.scrollPos = maxScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit->as.listBox.scrollPos < 0) {
|
||||||
|
hit->as.listBox.scrollPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if click is on the scrollbar
|
||||||
|
if (needSb) {
|
||||||
|
int32_t sbX = hit->x + hit->w - LISTBOX_BORDER - LISTBOX_SB_W;
|
||||||
|
|
||||||
|
if (vx >= sbX) {
|
||||||
|
int32_t sbY = hit->y + LISTBOX_BORDER;
|
||||||
|
int32_t sbH = innerH;
|
||||||
|
int32_t relY = vy - sbY;
|
||||||
|
int32_t trackLen = sbH - LISTBOX_SB_W * 2;
|
||||||
|
|
||||||
|
if (relY < LISTBOX_SB_W) {
|
||||||
|
// Up arrow
|
||||||
|
if (hit->as.listBox.scrollPos > 0) {
|
||||||
|
hit->as.listBox.scrollPos--;
|
||||||
|
}
|
||||||
|
} else if (relY >= sbH - LISTBOX_SB_W) {
|
||||||
|
// Down arrow
|
||||||
|
if (hit->as.listBox.scrollPos < maxScroll) {
|
||||||
|
hit->as.listBox.scrollPos++;
|
||||||
|
}
|
||||||
|
} else if (trackLen > 0) {
|
||||||
|
// Track — page up/down
|
||||||
|
int32_t thumbPos;
|
||||||
|
int32_t thumbSize;
|
||||||
|
listBoxScrollbarThumb(trackLen, hit->as.listBox.itemCount, visibleRows, hit->as.listBox.scrollPos, &thumbPos, &thumbSize);
|
||||||
|
|
||||||
|
int32_t trackRelY = relY - LISTBOX_SB_W;
|
||||||
|
|
||||||
|
if (trackRelY < thumbPos) {
|
||||||
|
hit->as.listBox.scrollPos -= visibleRows;
|
||||||
|
|
||||||
|
if (hit->as.listBox.scrollPos < 0) {
|
||||||
|
hit->as.listBox.scrollPos = 0;
|
||||||
|
}
|
||||||
|
} else if (trackRelY >= thumbPos + thumbSize) {
|
||||||
|
hit->as.listBox.scrollPos += visibleRows;
|
||||||
|
|
||||||
|
if (hit->as.listBox.scrollPos > maxScroll) {
|
||||||
|
hit->as.listBox.scrollPos = maxScroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hit->focused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Click on item area
|
||||||
|
int32_t innerY = hit->y + LISTBOX_BORDER;
|
||||||
|
int32_t relY = vy - innerY;
|
||||||
|
|
||||||
|
if (relY < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t clickedRow = relY / font->charHeight;
|
||||||
|
int32_t idx = hit->as.listBox.scrollPos + clickedRow;
|
||||||
|
|
||||||
|
if (idx >= 0 && idx < hit->as.listBox.itemCount) {
|
||||||
|
hit->as.listBox.selectedIdx = idx;
|
||||||
|
hit->focused = true;
|
||||||
|
|
||||||
|
if (hit->onChange) {
|
||||||
|
hit->onChange(hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// widgetListBoxPaint
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
void widgetListBoxPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) {
|
||||||
|
uint32_t fg = w->fgColor ? w->fgColor : colors->contentFg;
|
||||||
|
uint32_t bg = w->bgColor ? w->bgColor : colors->contentBg;
|
||||||
|
|
||||||
|
int32_t innerH = w->h - LISTBOX_BORDER * 2;
|
||||||
|
int32_t visibleRows = innerH / font->charHeight;
|
||||||
|
bool needSb = (w->as.listBox.itemCount > visibleRows);
|
||||||
|
int32_t contentW = w->w - LISTBOX_BORDER * 2;
|
||||||
|
|
||||||
|
if (needSb) {
|
||||||
|
contentW -= LISTBOX_SB_W;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sunken border
|
||||||
|
BevelStyleT bevel;
|
||||||
|
bevel.highlight = colors->windowShadow;
|
||||||
|
bevel.shadow = colors->windowHighlight;
|
||||||
|
bevel.face = bg;
|
||||||
|
bevel.width = 2;
|
||||||
|
drawBevel(d, ops, w->x, w->y, w->w, w->h, &bevel);
|
||||||
|
|
||||||
|
// Clamp scroll position
|
||||||
|
int32_t maxScroll = w->as.listBox.itemCount - visibleRows;
|
||||||
|
|
||||||
|
if (maxScroll < 0) {
|
||||||
|
maxScroll = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->as.listBox.scrollPos > maxScroll) {
|
||||||
|
w->as.listBox.scrollPos = maxScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->as.listBox.scrollPos < 0) {
|
||||||
|
w->as.listBox.scrollPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw items
|
||||||
|
int32_t innerX = w->x + LISTBOX_BORDER + LISTBOX_PAD;
|
||||||
|
int32_t innerY = w->y + LISTBOX_BORDER;
|
||||||
|
int32_t scrollPos = w->as.listBox.scrollPos;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < visibleRows && (scrollPos + i) < w->as.listBox.itemCount; i++) {
|
||||||
|
int32_t idx = scrollPos + i;
|
||||||
|
int32_t iy = innerY + i * font->charHeight;
|
||||||
|
uint32_t ifg = fg;
|
||||||
|
uint32_t ibg = bg;
|
||||||
|
|
||||||
|
if (idx == w->as.listBox.selectedIdx) {
|
||||||
|
ifg = colors->menuHighlightFg;
|
||||||
|
ibg = colors->menuHighlightBg;
|
||||||
|
rectFill(d, ops, w->x + LISTBOX_BORDER, iy, contentW, font->charHeight, ibg);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawText(d, ops, font, innerX, iy, w->as.listBox.items[idx], ifg, ibg, idx == w->as.listBox.selectedIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw scrollbar
|
||||||
|
if (needSb) {
|
||||||
|
int32_t sbX = w->x + w->w - LISTBOX_BORDER - LISTBOX_SB_W;
|
||||||
|
int32_t sbY = w->y + LISTBOX_BORDER;
|
||||||
|
int32_t sbH = innerH;
|
||||||
|
|
||||||
|
// Trough
|
||||||
|
BevelStyleT troughBevel;
|
||||||
|
troughBevel.highlight = colors->windowShadow;
|
||||||
|
troughBevel.shadow = colors->windowHighlight;
|
||||||
|
troughBevel.face = colors->scrollbarTrough;
|
||||||
|
troughBevel.width = 1;
|
||||||
|
drawBevel(d, ops, sbX, sbY, LISTBOX_SB_W, sbH, &troughBevel);
|
||||||
|
|
||||||
|
// Up arrow button
|
||||||
|
BevelStyleT btnBevel;
|
||||||
|
btnBevel.highlight = colors->windowHighlight;
|
||||||
|
btnBevel.shadow = colors->windowShadow;
|
||||||
|
btnBevel.face = colors->windowFace;
|
||||||
|
btnBevel.width = 1;
|
||||||
|
drawBevel(d, ops, sbX, sbY, LISTBOX_SB_W, LISTBOX_SB_W, &btnBevel);
|
||||||
|
|
||||||
|
// Up arrow triangle
|
||||||
|
{
|
||||||
|
int32_t cx = sbX + LISTBOX_SB_W / 2;
|
||||||
|
int32_t cy = sbY + LISTBOX_SB_W / 2;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 4; i++) {
|
||||||
|
drawHLine(d, ops, cx - i, cy - 2 + i, 1 + i * 2, colors->contentFg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Down arrow button
|
||||||
|
int32_t downY = sbY + sbH - LISTBOX_SB_W;
|
||||||
|
drawBevel(d, ops, sbX, downY, LISTBOX_SB_W, LISTBOX_SB_W, &btnBevel);
|
||||||
|
|
||||||
|
// Down arrow triangle
|
||||||
|
{
|
||||||
|
int32_t cx = sbX + LISTBOX_SB_W / 2;
|
||||||
|
int32_t cy = downY + LISTBOX_SB_W / 2;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 4; i++) {
|
||||||
|
drawHLine(d, ops, cx - i, cy + 2 - i, 1 + i * 2, colors->contentFg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumb
|
||||||
|
int32_t trackLen = sbH - LISTBOX_SB_W * 2;
|
||||||
|
|
||||||
|
if (trackLen > 0) {
|
||||||
|
int32_t thumbPos;
|
||||||
|
int32_t thumbSize;
|
||||||
|
listBoxScrollbarThumb(trackLen, w->as.listBox.itemCount, visibleRows, w->as.listBox.scrollPos, &thumbPos, &thumbSize);
|
||||||
|
|
||||||
|
drawBevel(d, ops, sbX, sbY + LISTBOX_SB_W + thumbPos, LISTBOX_SB_W, thumbSize, &btnBevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ void widgetPaintOne(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFo
|
||||||
widgetComboBoxPaint(w, d, ops, font, colors);
|
widgetComboBoxPaint(w, d, ops, font, colors);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WidgetListBoxE:
|
||||||
|
widgetListBoxPaint(w, d, ops, font, colors);
|
||||||
|
break;
|
||||||
|
|
||||||
case WidgetProgressBarE:
|
case WidgetProgressBarE:
|
||||||
widgetProgressBarPaint(w, d, ops, font, colors);
|
widgetProgressBarPaint(w, d, ops, font, colors);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue