UI and drawing (rotate image)

This commit is contained in:
Henrik Rydgard 2012-04-11 17:07:28 +02:00
parent 888b973bf3
commit 2e6adc2463
4 changed files with 69 additions and 10 deletions

View File

@ -145,6 +145,53 @@ void DrawBuffer::DrawImageStretch(int atlas_image, float x1, float y1, float x2,
V(x1, y2, color, image.u1, image.v2);
}
inline void rot(float *v, float angle, float xc,float yc)
{
v[0]-=xc;
v[1]-=yc;
float ca=cosf(angle),sa=sinf(angle);
float t0 = v[0] * ca + v[1] * -sa;
float t1 = v[0] * sa + v[1] * ca;
v[0] = t0 + xc;
v[1] = t1 + yc;
}
void DrawBuffer::DrawImageRotated(int atlas_image, float x, float y, float scale, float angle, Color color) {
const AtlasImage &image = atlas->images[atlas_image];
float w = (float)image.w * scale;
float h = (float)image.h * scale;
float x1 = x - w / 2;
float x2 = x + w / 2;
float y1 = y - h / 2;
float y2 = y + h / 2;
float v[6][2] = {
{x1, y1},
{x2, y1},
{x2, y2},
{x1, y1},
{x2, y2},
{x1, y2},
};
const float uv[6][2] = {
{image.u1, image.v1},
{image.u2, image.v1},
{image.u2, image.v2},
{image.u1, image.v1},
{image.u2, image.v2},
{image.u1, image.v2},
};
for (int i = 0; i < 6; i++) {
rot(v[i], angle, x, y);
V(v[i][0], v[i][1], 0, color, uv[i][0], uv[i][1]);
}
}
// TODO: add arc support
void DrawBuffer::Circle(float xc, float yc, float radius, float thickness, int segments, float startAngle, uint32 color, float u_mul) {
float angleDelta = PI * 2 / segments;

View File

@ -72,6 +72,7 @@ class DrawBuffer {
void MeasureImage(int atlas_image, float *w, float *h);
void DrawImage(int atlas_image, float x, float y, float scale, Color color = COLOR(0xFFFFFF), int align = ALIGN_TOPLEFT);
void DrawImageStretch(int atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF));
void DrawImageRotated(int atlas_image, float x, float y, float scale, float angle, Color color = COLOR(0xFFFFFF)); // Always centers
void DrawTexRect(float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, Color color);
// Results in 18 triangles. Kind of expensive for a button.
void DrawImage4Grid(int atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF), float corner_scale = 1.0);

View File

@ -27,17 +27,19 @@ void UIInit(const Atlas *atlas, int uiFont, int buttonImage, int checkOn, int ch
}
void UIUpdateMouse(float x, float y, int buttons) {
if ((buttons & 1) && !uistate.mousedown)
{
if ((buttons & 1) && !uistate.mousedown) {
uistate.mousepressed = 1;
uistate.mouseStartX = x;
uistate.mouseStartY = y;
} else {
uistate.mousepressed = 0;
}
uistate.mousex = x;
uistate.mousey = y;
uistate.mousedown = buttons;
uistate.mousedown = buttons & 1;
}
bool regionhit(int x, int y, int w, int h, int margin) {
bool UIRegionHit(int x, int y, int w, int h, int margin) {
if (uistate.mousex < x - margin ||
uistate.mousey < y - margin ||
uistate.mousex >= x + w + margin ||
@ -81,7 +83,7 @@ int UIButton(int id, int x, int y, int w, const char *text, int button_align) {
if (button_align & ALIGN_BOTTOMRIGHT) y -= h;
// Check whether the button should be hot, use a generous margin for touch ease
if (regionhit(x, y, w, h, 8)) {
if (UIRegionHit(x, y, w, h, 8)) {
uistate.hotitem = id;
if (uistate.activeitem == 0 && uistate.mousedown)
uistate.activeitem = id;
@ -127,7 +129,7 @@ int UICheckBox(int id, int x, int y, const char *text, int align, bool *value) {
if (align & ALIGN_BOTTOMRIGHT) y -= h;
// Check whether the button should be hot
if (regionhit(x, y, w, h, 8)) {
if (UIRegionHit(x, y, w, h, 8)) {
uistate.hotitem = id;
if (uistate.activeitem == 0 && uistate.mousedown)
uistate.activeitem = id;
@ -174,7 +176,7 @@ int UIList(int id, int x, int y, int w, int h, UIListAdapter *adapter, UIListSta
const int item_h = 64;
// Check whether the button should be hot
if (regionhit(x, y, w, h, 0)) {
if (UIRegionHit(x, y, w, h, 0)) {
uistate.hotitem = id;
if (uistate.activeitem == 0 && uistate.mousedown)
uistate.activeitem = id;
@ -185,7 +187,7 @@ int UIList(int id, int x, int y, int w, int h, UIListAdapter *adapter, UIListSta
int numItems = adapter->getCount();
for (int i = 0; i < numItems; i++) {
int item_y = y + i * itemHeight - state->scrollY;
if (uistate.mousedown && adapter->itemEnabled(i) && item_y >= y - itemHeight && item_y <= y + h && regionhit(x, item_y, w, h, 0)) {
if (uistate.mousedown && adapter->itemEnabled(i) && item_y >= y - itemHeight && item_y <= y + h && UIRegionHit(x, item_y, w, h, 0)) {
// ultra fast touch response
state->selected = i;
}
@ -232,7 +234,7 @@ int UIHSlider(int id, int x, int y, int w, int max, int *value) {
int xpos = ((256 - 16) * *value) / max;
// Check for hotness
if (regionhit(x+8, y+8, 16, 255, 0)) {
if (UIRegionHit(x+8, y+8, 16, 255, 0)) {
uistate.hotitem = id;
if (uistate.activeitem == 0 && uistate.mousedown)
uistate.activeitem = id;
@ -267,7 +269,7 @@ int UIVSlider(int id, int x, int y, int h, int max, int *value) {
int ypos = ((256 - 16) * *value) / max;
// Check for hotness
if (regionhit(x+8, y+8, 16, 255, 0)) {
if (UIRegionHit(x+8, y+8, 16, 255, 0)) {
uistate.hotitem = id;
if (uistate.activeitem == 0 && uistate.mousedown)
uistate.activeitem = id;

View File

@ -27,6 +27,7 @@ struct UIState {
int mousex;
int mousey;
int mousedown;
int mousepressed;
int mouseStartX;
int mouseStartY;
@ -42,6 +43,10 @@ struct UIState {
// keyboard focus, not currently used
int kbdwidget;
int lastwidget;
// Used by controls that need to keep track of the initial value for drags, for example.
// Should probably be indexed by finger - would be neat to be able to move two knobs at the same time.
float tempfloat;
};
// This needs to be extern so that additional UI controls can be developed outside this file.
@ -96,6 +101,10 @@ struct UIListState {
int selected;
};
// Utility functions, useful when implementing your own controls
bool UIRegionHit(int x, int y, int w, int h, int margin);
// Call at start of frame
void UIBegin();