mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Remove old UI framework
This commit is contained in:
parent
9fa4e65fb6
commit
7979b6378e
@ -109,10 +109,8 @@ void ScreenManager::render() {
|
||||
iter--;
|
||||
iter--;
|
||||
Layer backback = *iter;
|
||||
UIDisableBegin();
|
||||
// Also shift to the right somehow...
|
||||
backback.screen->render();
|
||||
UIDisableEnd();
|
||||
stack_.back().screen->render();
|
||||
break;
|
||||
}
|
||||
|
@ -16,70 +16,10 @@
|
||||
DrawBuffer ui_draw2d;
|
||||
DrawBuffer ui_draw2d_front;
|
||||
|
||||
// This one, though, is OK.
|
||||
UIState uistate;
|
||||
UIState savedUistate;
|
||||
|
||||
// Theme.
|
||||
static const Atlas *themeAtlas;
|
||||
static UITheme theme;
|
||||
|
||||
void UIInit(const Atlas *atlas, const UITheme &ui_theme) {
|
||||
ui_draw2d.SetAtlas(atlas);
|
||||
ui_draw2d_front.SetAtlas(atlas);
|
||||
themeAtlas = atlas;
|
||||
theme = ui_theme;
|
||||
memset(&uistate, 0, sizeof(uistate));
|
||||
}
|
||||
|
||||
void UIDisableBegin()
|
||||
{
|
||||
savedUistate = uistate;
|
||||
memset(&uistate, 0, sizeof(uistate));
|
||||
}
|
||||
|
||||
void UIDisableEnd()
|
||||
{
|
||||
uistate = savedUistate;
|
||||
}
|
||||
|
||||
void UIUpdateMouse(int i, float x, float y, bool down) {
|
||||
if (down && !uistate.mousedown[i]) {
|
||||
uistate.mousepressed[i] = 1;
|
||||
uistate.mouseStartX[i] = x;
|
||||
uistate.mouseStartY[i] = y;
|
||||
} else {
|
||||
uistate.mousepressed[i] = 0;
|
||||
}
|
||||
uistate.mousex[i] = x;
|
||||
uistate.mousey[i] = y;
|
||||
uistate.mousedown[i] = down;
|
||||
|
||||
if (uistate.mousedown[i])
|
||||
uistate.mouseframesdown[i]++;
|
||||
else
|
||||
uistate.mouseframesdown[i] = 0;
|
||||
}
|
||||
|
||||
void UIReset() {
|
||||
memset(&uistate, 0, sizeof(uistate));
|
||||
}
|
||||
|
||||
bool UIRegionHit(int i, int x, int y, int w, int h, int margin) {
|
||||
// Input handling
|
||||
if (uistate.mousex[i] < x - margin ||
|
||||
uistate.mousey[i] < y - margin ||
|
||||
uistate.mousex[i] >= x + w + margin ||
|
||||
uistate.mousey[i] >= y + h + margin) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void UIBegin(Thin3DShaderSet *shaderSet) {
|
||||
for (int i = 0; i < MAX_POINTERS; i++)
|
||||
uistate.hotitem[i] = 0;
|
||||
ui_draw2d.Begin(shaderSet);
|
||||
ui_draw2d_front.Begin(shaderSet);
|
||||
}
|
||||
@ -90,520 +30,10 @@ void UIFlush() {
|
||||
}
|
||||
|
||||
void UIEnd() {
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
if (uistate.mousedown[i] == 0) {
|
||||
uistate.activeitem[i] = 0;
|
||||
} else {
|
||||
if (uistate.activeitem[i] == 0) {
|
||||
uistate.activeitem[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ui_draw2d.End();
|
||||
ui_draw2d_front.End();
|
||||
|
||||
if (uistate.ui_tick > 0)
|
||||
uistate.ui_tick--;
|
||||
ui_draw2d.Flush();
|
||||
ui_draw2d_front.Flush();
|
||||
}
|
||||
|
||||
void UIText(int x, int y, const char *text, uint32_t color, float scale, int align) {
|
||||
UIText(theme.uiFont, x, y, text, color, scale, align);
|
||||
}
|
||||
|
||||
void UIText(int font, int x, int y, const char *text, uint32_t color, float scale, int align) {
|
||||
ui_draw2d.SetFontScale(scale, scale);
|
||||
ui_draw2d.DrawTextShadow(font, text, x, y, color, align);
|
||||
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale, int align)
|
||||
{
|
||||
ui_draw2d.SetFontScale(scale, scale);
|
||||
float w, h;
|
||||
ui_draw2d.MeasureText(font, text, &w, &h);
|
||||
float x, y;
|
||||
layout.GetPos(&w, &h, &x, &y);
|
||||
UIText(font, x, y, text, color, scale, 0);
|
||||
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align) {
|
||||
if (h == 0.0f)
|
||||
h = themeAtlas->images[theme.buttonImage].h;
|
||||
|
||||
float x, y;
|
||||
layout.GetPos(&w, &h, &x, &y);
|
||||
|
||||
if (button_align & ALIGN_HCENTER) x -= w / 2;
|
||||
if (button_align & ALIGN_VCENTER) y -= h / 2;
|
||||
if (button_align & ALIGN_RIGHT) x -= w;
|
||||
if (button_align & ALIGN_BOTTOM) y -= h;
|
||||
|
||||
int txOffset = 0;
|
||||
|
||||
int clicked = 0;
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
// Check whether the button should be hot, use a generous margin for touch ease
|
||||
if (UIRegionHit(i, x, y, w, h, 8)) {
|
||||
uistate.hotitem[i] = id;
|
||||
if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) {
|
||||
uistate.activeitem[i] = id;
|
||||
}
|
||||
}
|
||||
|
||||
if (uistate.hotitem[i] == id) {
|
||||
if (uistate.activeitem[i] == id) {
|
||||
// Button is both 'hot' and 'active'
|
||||
txOffset = 2;
|
||||
} else {
|
||||
// Button is merely 'hot'
|
||||
}
|
||||
} else {
|
||||
// button is not hot, but it may be active
|
||||
}
|
||||
|
||||
// If button is hot and active, but mouse button is not
|
||||
// down, the user must have clicked the button.
|
||||
if (uistate.mousedown[i] == 0 &&
|
||||
uistate.hotitem[i] == id &&
|
||||
uistate.activeitem[i] == id) {
|
||||
clicked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Render button
|
||||
|
||||
if (h == themeAtlas->images[theme.buttonImage].h)
|
||||
ui_draw2d.DrawImage2GridH((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w);
|
||||
else
|
||||
ui_draw2d.DrawImage4Grid((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w, y + h);
|
||||
ui_draw2d.DrawTextShadow(theme.uiFont, text, x + w/2, y + h/2 + txOffset, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER);
|
||||
|
||||
uistate.lastwidget = id;
|
||||
return clicked;
|
||||
}
|
||||
|
||||
int UIImageButton(int id, const LayoutManager &layout, float w, int image, int button_align) {
|
||||
float h = 64;
|
||||
float x, y;
|
||||
layout.GetPos(&w, &h, &x, &y);
|
||||
|
||||
if (button_align & ALIGN_HCENTER) x -= w / 2;
|
||||
if (button_align & ALIGN_VCENTER) y -= h / 2;
|
||||
if (button_align & ALIGN_RIGHT) x -= w;
|
||||
if (button_align & ALIGN_BOTTOMRIGHT) y -= h;
|
||||
|
||||
int txOffset = 0;
|
||||
int clicked = 0;
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
// Check whether the button should be hot, use a generous margin for touch ease
|
||||
if (UIRegionHit(i, x, y, w, h, 8)) {
|
||||
uistate.hotitem[i] = id;
|
||||
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
|
||||
uistate.activeitem[i] = id;
|
||||
}
|
||||
|
||||
if (uistate.hotitem[i] == id) {
|
||||
if (uistate.activeitem[i] == id) {
|
||||
// Button is both 'hot' and 'active'
|
||||
txOffset = 2;
|
||||
} else {
|
||||
// Button is merely 'hot'
|
||||
}
|
||||
} else {
|
||||
// button is not hot, but it may be active
|
||||
}
|
||||
|
||||
// If button is hot and active, but mouse button is not
|
||||
// down, the user must have clicked the button.
|
||||
if (uistate.mousedown[i] == 0 &&
|
||||
uistate.hotitem[i] == id &&
|
||||
uistate.activeitem[i] == id) {
|
||||
clicked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Render button
|
||||
|
||||
ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w);
|
||||
ui_draw2d.DrawImage(image, x + w/2, y + h/2 + txOffset, 1.0f, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER);
|
||||
|
||||
uistate.lastwidget = id;
|
||||
return clicked;
|
||||
}
|
||||
|
||||
int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow) // uses current UI atlas for fetching images.
|
||||
{
|
||||
float x, y;
|
||||
layout.GetPos(&w, &h, &x, &y);
|
||||
|
||||
if (button_align & ALIGN_HCENTER) x -= w / 2;
|
||||
if (button_align & ALIGN_VCENTER) y -= h / 2;
|
||||
if (button_align & ALIGN_RIGHT) x -= w;
|
||||
if (button_align & ALIGN_BOTTOMRIGHT) y -= h;
|
||||
|
||||
int txOffset = 0;
|
||||
int clicked = 0;
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
// Check whether the button should be hot, use a generous margin for touch ease
|
||||
if (UIRegionHit(i, x, y, w, h, 8)) {
|
||||
uistate.hotitem[i] = id;
|
||||
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
|
||||
uistate.activeitem[i] = id;
|
||||
}
|
||||
|
||||
if (uistate.hotitem[i] == id) {
|
||||
if (uistate.activeitem[i] == id) {
|
||||
// Button is both 'hot' and 'active'
|
||||
txOffset = 2;
|
||||
} else {
|
||||
// Button is merely 'hot'
|
||||
}
|
||||
} else {
|
||||
// button is not hot, but it may be active
|
||||
}
|
||||
|
||||
// If button is hot and active, but mouse button is not
|
||||
// down, the user must have clicked the button.
|
||||
if (uistate.mousedown[i] == 0 &&
|
||||
uistate.hotitem[i] == id &&
|
||||
uistate.activeitem[i] == id) {
|
||||
clicked = 1;
|
||||
}
|
||||
}
|
||||
if (texture) {
|
||||
float tw = texture->Width();
|
||||
float th = texture->Height();
|
||||
|
||||
// Adjust position so we don't stretch the image vertically or horizontally.
|
||||
// TODO: Add a param to specify fit? The below assumes it's never too wide.
|
||||
float nw = h * tw / th;
|
||||
x += (w - nw) / 2.0f;
|
||||
w = nw;
|
||||
}
|
||||
|
||||
// Render button
|
||||
int dropsize = 10;
|
||||
if (drop_shadow && texture)
|
||||
{
|
||||
if (txOffset) {
|
||||
dropsize = 3;
|
||||
y += txOffset * 2;
|
||||
}
|
||||
ui_draw2d.DrawImage4Grid(drop_shadow, x - dropsize, y, x+w + dropsize, y+h+dropsize*1.5,
|
||||
blackAlpha(0.5f), 1.0f);
|
||||
ui_draw2d.Flush(true);
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texture->Bind(0);
|
||||
} else {
|
||||
ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w, color);
|
||||
ui_draw2d.Flush();
|
||||
|
||||
Texture::Unbind();
|
||||
}
|
||||
ui_draw2d.DrawTexRect(x, y, x+w, y+h, 0, 0, 1, 1, color);
|
||||
|
||||
ui_draw2d.Flush();
|
||||
ctx->RebindTexture();
|
||||
|
||||
uistate.lastwidget = id;
|
||||
return clicked;
|
||||
}
|
||||
|
||||
int UICheckBox(int id, int x, int y, const char *text, int align, bool *value) {
|
||||
#ifdef _WIN32
|
||||
const int h = 32;
|
||||
#else
|
||||
const int h = 48;
|
||||
#endif
|
||||
float tw, th;
|
||||
ui_draw2d.MeasureText(theme.uiFont, text, &tw, &th);
|
||||
int w = themeAtlas->images[theme.checkOn].w + UI_SPACE + tw;
|
||||
if (align & ALIGN_HCENTER) x -= w / 2;
|
||||
if (align & ALIGN_VCENTER) y -= h / 2;
|
||||
if (align & ALIGN_RIGHT) x -= w;
|
||||
if (align & ALIGN_BOTTOMRIGHT) y -= h;
|
||||
|
||||
int txOffset = 0;
|
||||
int clicked = 0;
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
|
||||
// Check whether the button should be hot
|
||||
if (UIRegionHit(i, x, y, w, h, 8)) {
|
||||
uistate.hotitem[i] = id;
|
||||
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
|
||||
uistate.activeitem[i] = id;
|
||||
}
|
||||
|
||||
// Render button
|
||||
|
||||
if (uistate.hotitem[i] == id) {
|
||||
if (uistate.activeitem[i] == id) {
|
||||
// Button is both 'hot' and 'active'
|
||||
txOffset = 2;
|
||||
} else {
|
||||
// Button is merely 'hot'
|
||||
}
|
||||
} else {
|
||||
// button is not hot, but it may be active
|
||||
}
|
||||
// If button is hot and active, but mouse button is not
|
||||
// down, the user must have clicked the button.
|
||||
if (uistate.mousedown[i] == 0 &&
|
||||
uistate.hotitem[i] == id &&
|
||||
uistate.activeitem[i] == id) {
|
||||
*value = !(*value);
|
||||
clicked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ui_draw2d.DrawImage((*value) ? theme.checkOn : theme.checkOff, x, y+h/2, 1.0f, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
ui_draw2d.DrawTextShadow(theme.uiFont, text, x + themeAtlas->images[theme.checkOn].w + UI_SPACE, y + txOffset + h/2, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
|
||||
|
||||
uistate.lastwidget = id;
|
||||
return clicked;
|
||||
}
|
||||
|
||||
void StringVectorListAdapter::drawItem(int item, int x, int y, int w, int h, bool selected) const
|
||||
{
|
||||
ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w);
|
||||
ui_draw2d.DrawTextShadow(theme.uiFont, (*items_)[item].c_str(), x + UI_SPACE , y, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
}
|
||||
|
||||
UIList::UIList()
|
||||
: scrollY(0.0f), startDragY(0.0f), dragFinger(-1), selected(-1) {
|
||||
movedDistanceX = 0.0f;
|
||||
movedDistanceY = 0.0f;
|
||||
scrolling = false;
|
||||
inertiaY = 0.0f;
|
||||
}
|
||||
|
||||
void UIList::pointerDown(int pointer, float x, float y) {
|
||||
// Instantly halt on pointerDown if inertia-scrolling
|
||||
scrolling = false;
|
||||
inertiaY = 0.0f;
|
||||
|
||||
startScrollY = scrollY;
|
||||
startDragY = y;
|
||||
movedDistanceX = 0.0f;
|
||||
movedDistanceY = 0.0f;
|
||||
}
|
||||
|
||||
const int holdFramesClick = 3;
|
||||
const int holdFramesScroll = 10;
|
||||
|
||||
void UIList::pointerMove(int pointer, float x, float y, bool inside) {
|
||||
float deltaX = x - lastX;
|
||||
float deltaY = y - lastY;
|
||||
movedDistanceY += fabsf(deltaY);
|
||||
movedDistanceX += fabsf(deltaX);
|
||||
|
||||
if (inertiaY <= 0.0f && deltaY > 0.0f) {
|
||||
inertiaY = -deltaY;
|
||||
} else if (inertiaY >= 0.0f && deltaY < 0.0f) {
|
||||
inertiaY = -deltaY;
|
||||
} else {
|
||||
inertiaY = 0.8 * inertiaY + 0.2 * -deltaY;
|
||||
}
|
||||
|
||||
const int deadzone = 30 * holdFramesScroll;
|
||||
if (inside && movedDistanceY * uistate.mouseframesdown[0] > deadzone && !scrolling) {
|
||||
scrolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UIList::pointerUp(int pointer, float x, float y, bool inside) {
|
||||
// printf("PointerUp %f %f\n", x, y);
|
||||
}
|
||||
|
||||
int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) {
|
||||
int clicked = 0;
|
||||
|
||||
// Pointer and focus handling
|
||||
|
||||
// UIList only cares about the first pointer for simplicity.
|
||||
// Probably not much need to scroll one of these while dragging something
|
||||
// else.
|
||||
|
||||
// TODO: Abstract this stuff out into EmulatePointerEvents
|
||||
for (int i = 0; i < 1; i++) {
|
||||
// Check for hover
|
||||
bool isInside = false;
|
||||
if (UIRegionHit(i, x, y, w, h, 0)) {
|
||||
isInside = true;
|
||||
uistate.hotitem[i] = id;
|
||||
if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) {
|
||||
// Mousedown
|
||||
uistate.activeitem[i] = id;
|
||||
pointerDown(i, uistate.mousex[i], uistate.mousey[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (uistate.activeitem[i] == id) {
|
||||
// NOTE: won't work with multiple pointers
|
||||
if (uistate.mousex[i] != lastX || uistate.mousey[i] != lastY) {
|
||||
pointerMove(i, uistate.mousex[i], uistate.mousey[i], isInside);
|
||||
}
|
||||
}
|
||||
|
||||
// If button is hot and active, but mouse button is not
|
||||
// down, the user must have clicked a list item (unless after the last item).
|
||||
if (uistate.mousedown[i] == 0 &&
|
||||
uistate.activeitem[i] == id &&
|
||||
selected != -1) {
|
||||
if (uistate.hotitem[i] == id) {
|
||||
clicked = 1;
|
||||
}
|
||||
pointerUp(i, uistate.mousex[i], uistate.mousey[i], isInside);
|
||||
}
|
||||
}
|
||||
|
||||
int itemHeight = adapter->itemHeight(0);
|
||||
int numItems = (int)adapter->getCount();
|
||||
|
||||
// Cap total inertia
|
||||
if (inertiaY > 20) inertiaY = 20;
|
||||
if (inertiaY < -20) inertiaY = -20;
|
||||
|
||||
if (!uistate.mousedown[0]) {
|
||||
// Let it slide if the pointer is not down
|
||||
scrollY += inertiaY;
|
||||
} else if (scrolling /* && mouseY > y && mouseY < y + h*/ ) {
|
||||
// Pointer is down so stick to it
|
||||
scrollY = startScrollY - (uistate.mousey[0] - startDragY);
|
||||
}
|
||||
|
||||
// Inertia gradually trails off
|
||||
inertiaY *= 0.92f;
|
||||
if (scrolling && fabsf(inertiaY) < 0.001f)
|
||||
scrolling = false;
|
||||
|
||||
// Cap top and bottom softly.
|
||||
float maxScrollY = numItems * itemHeight - h;
|
||||
if (maxScrollY < 0.0f) maxScrollY = 0.0f;
|
||||
if (scrollY > maxScrollY) {
|
||||
scrollY -= 0.4f * (scrollY - maxScrollY);
|
||||
} else if (scrollY < 0.0f) {
|
||||
scrollY += 0.4f * -scrollY;
|
||||
}
|
||||
|
||||
lastX = uistate.mousex[0];
|
||||
lastY = uistate.mousey[0];
|
||||
uistate.lastwidget = id;
|
||||
|
||||
// Drawing and item hittesting
|
||||
|
||||
// render items
|
||||
for (int i = 0; i < numItems; i++) {
|
||||
int item_y = y + i * itemHeight - scrollY;
|
||||
|
||||
if (item_y >= y - itemHeight && item_y <= y + h) {
|
||||
for (int k = 0; k < 1; k++) { // MAX_POINTERS if we add back multitouch
|
||||
if (uistate.mousedown[k] &&
|
||||
uistate.mouseframesdown[k] >= holdFramesClick &&
|
||||
adapter->itemEnabled(i) &&
|
||||
!scrolling &&
|
||||
selected == -1 &&
|
||||
UIRegionHit(k, x, item_y, w, itemHeight, 0)) {
|
||||
selected = i;
|
||||
} else if (scrolling) {
|
||||
selected = -1;
|
||||
}
|
||||
}
|
||||
adapter->drawItem(i, x, item_y, w, itemHeight, i == selected);
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent scroll-clicks from registering
|
||||
if (selected == -1) clicked = 0;
|
||||
// Otherwise, no clicky.
|
||||
return clicked;
|
||||
}
|
||||
|
||||
/*
|
||||
struct SlideItem {
|
||||
const char *text;
|
||||
int image;
|
||||
uint32_t bgColor;
|
||||
};
|
||||
|
||||
struct SlideState
|
||||
{
|
||||
float scroll;
|
||||
|
||||
};
|
||||
|
||||
void UISlideChoice(int id, int y, const SlideItem *items, int numItems, SlideState *state)
|
||||
|
||||
}*/
|
||||
|
||||
// TODO
|
||||
int UIHSlider(int id, int x, int y, int w, int max, int *value) {
|
||||
// Calculate mouse cursor's relative y offset
|
||||
int xpos = ((256 - 16) * *value) / max;
|
||||
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
// Check for hotness
|
||||
if (UIRegionHit(i, x+8, y+8, 16, 255, 0)) {
|
||||
uistate.hotitem[i] = id;
|
||||
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
|
||||
uistate.activeitem[i] = id;
|
||||
}
|
||||
|
||||
// Update widget value
|
||||
if (uistate.activeitem[i] == id) {
|
||||
int mousepos = uistate.mousey[i] - (y + 8);
|
||||
if (mousepos < 0) mousepos = 0;
|
||||
if (mousepos > 255) mousepos = 255;
|
||||
int v = (mousepos * max) / 255;
|
||||
if (v != *value) {
|
||||
*value = v;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Render the scrollbar
|
||||
ui_draw2d.Rect(x, y, 32, 256+16, 0x777777);
|
||||
|
||||
ui_draw2d.Rect(x+8+xpos, y+8, 16, 16, 0xffffff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO
|
||||
int UIVSlider(int id, int x, int y, int h, int max, int *value) {
|
||||
// Calculate mouse cursor's relative y offset
|
||||
int ypos = ((256 - 16) * *value) / max;
|
||||
|
||||
// Check for hotness
|
||||
if (UIRegionHit(x+8, y+8, 16, 255, 0)) {
|
||||
uistate.hotitem = id;
|
||||
if (uistate.activeitem == 0 && uistate.mousedown)
|
||||
uistate.activeitem = id;
|
||||
}
|
||||
// Update widget value
|
||||
if (uistate.activeitem == id) {
|
||||
int mousepos = uistate.mousey - (y + 8);
|
||||
if (mousepos < 0) mousepos = 0;
|
||||
if (mousepos > 255) mousepos = 255;
|
||||
int v = (mousepos * max) / 255;
|
||||
if (v != *value) {
|
||||
*value = v;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Render the scrollbar
|
||||
ui_draw2d.Rect(x, y, 32, 256+16, 0x777777);
|
||||
|
||||
ui_draw2d.Rect(x+8, y+8 + ypos, 16, 16, 0xffffff);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
@ -29,135 +29,8 @@
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "input/input_state.h"
|
||||
|
||||
class Texture;
|
||||
class UIContext;
|
||||
|
||||
class LayoutManager {
|
||||
public:
|
||||
virtual void GetPos(float *w, float *h, float *x, float *y) const = 0;
|
||||
};
|
||||
|
||||
class Pos : public LayoutManager {
|
||||
public:
|
||||
Pos(float x, float y) : x_(x), y_(y) {}
|
||||
virtual void GetPos(float *w, float *h, float *x, float *y) const {
|
||||
*x = x_;
|
||||
*y = y_;
|
||||
}
|
||||
private:
|
||||
float x_;
|
||||
float y_;
|
||||
};
|
||||
|
||||
class HLinear : public LayoutManager {
|
||||
public:
|
||||
HLinear(float x, float y, float spacing = 2.0f) : x_(x), y_(y), spacing_(spacing) {}
|
||||
virtual void GetPos(float *w, float *h, float *x, float *y) const {
|
||||
*x = x_;
|
||||
*y = y_;
|
||||
x_ += *w + spacing_;
|
||||
}
|
||||
void Space(float x) {
|
||||
x_ += x;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable float x_;
|
||||
float y_;
|
||||
float spacing_;
|
||||
};
|
||||
|
||||
class VLinear : public LayoutManager {
|
||||
public:
|
||||
VLinear(float x, float y, float spacing = 2.0f) : x_(x), y_(y), spacing_(spacing) {}
|
||||
virtual void GetPos(float *w, float *h, float *x, float *y) const {
|
||||
*x = x_;
|
||||
*y = y_;
|
||||
y_ += *h + spacing_;
|
||||
}
|
||||
|
||||
private:
|
||||
float x_;
|
||||
mutable float y_;
|
||||
float spacing_;
|
||||
};
|
||||
|
||||
class HGrid : public LayoutManager {
|
||||
public:
|
||||
HGrid(float x, float y, float xMax, float xSpacing = 2.0f, float ySpacing = 2.0f)
|
||||
: x_(x), y_(y), xInit_(x), xMax_(xMax), xSpacing_(xSpacing), ySpacing_(ySpacing) {}
|
||||
virtual void GetPos(float *w, float *h, float *x, float *y) const {
|
||||
*x = x_;
|
||||
*y = y_;
|
||||
x_ += *w + xSpacing_;
|
||||
if (x_ >= xMax_) {
|
||||
x_ = xInit_;
|
||||
y_ += *h + ySpacing_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable float x_;
|
||||
mutable float y_;
|
||||
float xInit_;
|
||||
float xMax_;
|
||||
float xSpacing_;
|
||||
float ySpacing_;
|
||||
};
|
||||
|
||||
class VGrid : public LayoutManager {
|
||||
public:
|
||||
VGrid(float x, float y, float yMax, float xSpacing = 2.0f, float ySpacing = 2.0f)
|
||||
: x_(x), y_(y), yInit_(y), yMax_(yMax), xSpacing_(xSpacing), ySpacing_(ySpacing) {}
|
||||
virtual void GetPos(float *w, float *h, float *x, float *y) const {
|
||||
*x = x_;
|
||||
*y = y_;
|
||||
y_ += *h + ySpacing_;
|
||||
if (y_ + *h >= yMax_) {
|
||||
x_ += *w + xSpacing_;
|
||||
y_ = yInit_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable float x_;
|
||||
mutable float y_;
|
||||
float yInit_;
|
||||
float yMax_;
|
||||
float xSpacing_;
|
||||
float ySpacing_;
|
||||
};
|
||||
|
||||
// "Mouse" out of habit, applies just as well to touch events.
|
||||
// TODO: Change to "pointer"
|
||||
// This struct is zeroed on init, so should be valid at that state.
|
||||
// Never inherit from this.
|
||||
struct UIState {
|
||||
int mousex[MAX_POINTERS];
|
||||
int mousey[MAX_POINTERS];
|
||||
bool mousedown[MAX_POINTERS];
|
||||
bool mousepressed[MAX_POINTERS];
|
||||
short mouseframesdown[MAX_POINTERS];
|
||||
|
||||
int mouseStartX[MAX_POINTERS];
|
||||
int mouseStartY[MAX_POINTERS];
|
||||
|
||||
int hotitem[MAX_POINTERS];
|
||||
int activeitem[MAX_POINTERS];
|
||||
|
||||
// keyboard focus, not currently used
|
||||
int kbdwidget;
|
||||
int lastwidget;
|
||||
|
||||
int ui_tick;
|
||||
|
||||
// deprecated: tempfloat
|
||||
float tempfloat;
|
||||
};
|
||||
|
||||
// This needs to be extern so that additional UI controls can be developed outside this file.
|
||||
extern UIState uistate;
|
||||
|
||||
struct Atlas;
|
||||
|
||||
// This is the drawbuffer used for UI. Remember to flush it at the end of the frame.
|
||||
@ -165,41 +38,7 @@ struct Atlas;
|
||||
extern DrawBuffer ui_draw2d;
|
||||
extern DrawBuffer ui_draw2d_front; // for things that need to be on top of the rest
|
||||
|
||||
struct UITheme {
|
||||
int uiFont;
|
||||
int uiFontSmall;
|
||||
int uiFontSmaller;
|
||||
int buttonImage;
|
||||
int buttonSelected;
|
||||
int checkOn;
|
||||
int checkOff;
|
||||
};
|
||||
|
||||
// The atlas needs to stick around, the theme is copied.
|
||||
void UIInit(const Atlas *atlas, const UITheme &theme);
|
||||
|
||||
// Between these, UI components won't see pointer events.
|
||||
void UIDisableBegin();
|
||||
void UIDisableEnd();
|
||||
|
||||
// Just lets you retrieve the theme that was passed into UIInit, for your own controls for example.
|
||||
UITheme &UIGetTheme();
|
||||
|
||||
// TODO: These don't really belong here.
|
||||
const int UI_SPACE = 32;
|
||||
const int SMALL_BUTTON_WIDTH = 128;
|
||||
const int LARGE_BUTTON_WIDTH = 192;
|
||||
const int BUTTON_HEIGHT = 72;
|
||||
|
||||
struct SlideItem {
|
||||
const char *text;
|
||||
int image;
|
||||
uint32_t bgColor;
|
||||
};
|
||||
|
||||
struct UISlideState {
|
||||
float scroll;
|
||||
};
|
||||
|
||||
// Implement this interface to style your lists
|
||||
class UIListAdapter {
|
||||
@ -221,9 +60,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// Utility functions, useful when implementing your own controls
|
||||
bool UIRegionHit(int pointerId, int x, int y, int w, int h, int margin);
|
||||
|
||||
// Call at start of frame
|
||||
void UIBegin(Thin3DShaderSet *shaderSet);
|
||||
|
||||
@ -232,69 +68,3 @@ void UIBegin(Thin3DShaderSet *shaderSet);
|
||||
void UIEnd();
|
||||
void UIFlush();
|
||||
|
||||
void UIUpdateMouse(int i, float x, float y, bool down);
|
||||
|
||||
// Call when you switch screens
|
||||
void UIReset();
|
||||
|
||||
// Returns 1 if clicked
|
||||
int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align);
|
||||
int UIImageButton(int id, const LayoutManager &layout, float w, int image_id, int button_align); // uses current UI atlas for fetching images.
|
||||
int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow=0); // uses current UI atlas for fetching images.
|
||||
// Returns 1 if clicked, puts the value in *value (where it also gets the current state).
|
||||
int UICheckBox(int id, int x, int y, const char *text, int align, bool *value);
|
||||
|
||||
// Vertical slider. Not yet working.
|
||||
// int UIVSlider(int id, int x, int y, int h, int max, int *value);
|
||||
|
||||
// Horizontal slider. Not yet working.
|
||||
int UIHSlider(int id, int x, int y, int w, int max, int *value);
|
||||
|
||||
// Draws static text, that does not participate in any focusing scheme etc, it just is.
|
||||
void UIText(int font, int x, int y, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT);
|
||||
void UIText(int x, int y, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT);
|
||||
void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT);
|
||||
|
||||
// Slide choice, like the Angry Birds level selector. Not yet working.
|
||||
void UISlideChoice(int id, int y, const SlideItem *items, int numItems, UISlideState *state);
|
||||
|
||||
|
||||
class UIList {
|
||||
public:
|
||||
UIList();
|
||||
|
||||
bool scrolling;
|
||||
int activePointer;
|
||||
float startScrollY;
|
||||
float scrollY;
|
||||
float lastX;
|
||||
float lastY;
|
||||
float startDragY;
|
||||
float movedDistanceX;
|
||||
float movedDistanceY;
|
||||
float inertiaY;
|
||||
|
||||
int dragFinger;
|
||||
int selected;
|
||||
// List view.
|
||||
// return -1 = no selection
|
||||
int Do(int id, int x, int y, int w, int h, UIListAdapter *adapter);
|
||||
|
||||
// Call this when the content has changed, to reset scroll position etc.
|
||||
void contentChanged() {
|
||||
scrollY = 0.0f;
|
||||
inertiaY = 0.0f;
|
||||
}
|
||||
|
||||
void scrollRelative(float delta) {
|
||||
scrollY += delta;
|
||||
}
|
||||
private:
|
||||
// TODO: Migrate to using these directly.
|
||||
void pointerDown(int pointer, float x, float y);
|
||||
void pointerUp(int pointer, float x, float y, bool inside);
|
||||
void pointerMove(int pointer, float x, float y, bool inside);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UIList);
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "input/input_state.h"
|
||||
#include "input/keycodes.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "gfx/texture.h"
|
||||
#include "gfx/texture_atlas.h"
|
||||
#include "util/text/utf8.h"
|
||||
#include "ui/ui.h"
|
||||
@ -573,28 +572,6 @@ void ImageView::Draw(UIContext &dc) {
|
||||
dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT);
|
||||
}
|
||||
|
||||
void TextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
|
||||
// TODO: involve sizemode
|
||||
if (texture_) {
|
||||
w = (float)texture_->Width();
|
||||
h = (float)texture_->Height();
|
||||
} else {
|
||||
w = 16;
|
||||
h = 16;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureView::Draw(UIContext &dc) {
|
||||
// TODO: involve sizemode
|
||||
if (texture_) {
|
||||
dc.Flush();
|
||||
texture_->Bind(0);
|
||||
dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_);
|
||||
dc.Flush();
|
||||
dc.RebindTexture();
|
||||
}
|
||||
}
|
||||
|
||||
void Thin3DTextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
|
||||
// TODO: involve sizemode
|
||||
if (texture_) {
|
||||
|
@ -741,25 +741,6 @@ private:
|
||||
ImageSizeMode sizeMode_;
|
||||
};
|
||||
|
||||
// TextureView takes a texture that is assumed to be alive during the lifetime
|
||||
// of the view.
|
||||
class TextureView : public InertView {
|
||||
public:
|
||||
TextureView(Texture *texture, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0)
|
||||
: InertView(layoutParams), texture_(texture), sizeMode_(sizeMode) {}
|
||||
|
||||
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
|
||||
void Draw(UIContext &dc) override;
|
||||
|
||||
void SetTexture(Texture *texture) { texture_ = texture; }
|
||||
void SetColor(uint32_t color) { color_ = color; }
|
||||
|
||||
private:
|
||||
Texture *texture_;
|
||||
uint32_t color_;
|
||||
ImageSizeMode sizeMode_;
|
||||
};
|
||||
|
||||
// TextureView takes a texture that is assumed to be alive during the lifetime
|
||||
// of the view.
|
||||
class Thin3DTextureView : public InertView {
|
||||
|
Loading…
Reference in New Issue
Block a user