Some UI code cleanup. Another variant of ease curve function. RebindTexture.

This commit is contained in:
Henrik Rydgard committed 2012-11-22 18:41:04 +01:00
1 parent 16e3d67063
commit 8677fac72c
14 files changed
+193 -102

No files matched your search

+1
View File
@@ -150,6 +150,7 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeApp_init
g_dpi_scale = 240.0f / (float)g_dpi;
pixel_xres = xxres;
pixel_yres = yyres;
pixel_in_dps = (float)pixel_xres / (float)dp_xres;
NativeGetAppInfo(&app_name, &app_nice_name, &landscape);
+5 -7
View File
@@ -135,11 +135,6 @@ extern void mixaudio(void *userdata, Uint8 *stream, int len) {
#undef main
#endif
int main(int argc, char *argv[]) {
/* // Xoom/Nexus 7 resolution. Other common tablet resolutions: 1024x600 , 1366x768
dp_xres = 1280;
dp_yres = 800;
*/
std::string app_name;
std::string app_name_nice;
@@ -156,7 +151,8 @@ int main(int argc, char *argv[]) {
bool landscape;
NativeGetAppInfo(&app_name, &app_name_nice, &landscape);
tablet = false;
if (landscape) {
if (tablet) {
pixel_xres = 1280 * zoom;
@@ -250,12 +246,14 @@ int main(int argc, char *argv[]) {
float density = 1.0f;
dp_xres = (float)pixel_xres * density / zoom;
dp_yres = (float)pixel_yres * density / zoom;
pixel_in_dps = (float)pixel_xres / dp_xres;
NativeInitGraphics();
float dp_xscale = (float)dp_xres / pixel_xres;
float dp_yscale = (float)dp_yres / pixel_yres;
printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
@@ -350,8 +348,8 @@ int main(int argc, char *argv[]) {
NativeShutdownGraphics();
SDL_PauseAudio(1);
NativeShutdown();
SDL_CloseAudio();
NativeShutdown();
SDL_Quit();
net::Shutdown();
exit(0);
+2 -1
View File
@@ -7,4 +7,5 @@ int pixel_xres;
int pixel_yres;
int g_dpi;
float g_dpi_scale;
float g_dpi_scale;
float pixel_in_dps;
+2 -1
View File
@@ -9,4 +9,5 @@ extern int pixel_xres;
extern int pixel_yres;
extern int g_dpi;
extern float g_dpi_scale;
extern float g_dpi_scale;
extern float pixel_in_dps;
+7 -4
View File
@@ -233,15 +233,15 @@ void DrawBuffer::DrawTexRect(float x1, float y1, float x2, float y2, float u1, f
void DrawBuffer::DrawImage4Grid(int atlas_image, float x1, float y1, float x2, float y2, Color color, float corner_scale) {
const AtlasImage &image = atlas->images[atlas_image];
float um = (image.u2 - image.u1) * 0.5f;
float vm = (image.v2 - image.v1) * 0.5f;
float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2;
float um = (u2 + u1) * 0.5f;
float vm = (v2 + v1) * 0.5f;
float iw2 = (image.w * 0.5f) * corner_scale;
float ih2 = (image.h * 0.5f) * corner_scale;
float xa = x1 + iw2;
float xb = x2 - iw2;
float ya = y1 + ih2;
float yb = y2 - ih2;
float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2;
// Top row
DrawTexRect(x1, y1, xa, ya, u1, v1, um, vm, color);
DrawTexRect(xa, y1, xb, ya, um, v1, um, vm, color);
@@ -358,8 +358,11 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co
void DrawBuffer::EnableBlend(bool enable) {
if (enable)
{
glEnable(GL_BLEND);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
glDisable(GL_BLEND);
}
+8 -7
View File
@@ -4,6 +4,7 @@
#include "base/basictypes.h"
#include "base/color.h"
#include "base/display.h"
struct Atlas;
@@ -54,16 +55,16 @@ public:
void Flush(const GLSLProgram *program, bool set_blend_state=true);
void Rect(float x, float y, float w, float h, uint32 color, int align = ALIGN_TOPLEFT);
void hLine(float x1, float y, float x2, uint32 color) { Rect(x1, y, x2 - x1, 1, color); }
void vLine(float x, float y1, float y2, uint32 color) { Rect(x, y1, 1, y2 - y1, color); }
void vLineAlpha50(float x, float y1, float y2, uint32 color) { Rect(x, y1, 1, y2 - y1, (color | 0xFF000000) & 0x7F000000); }
void hLine(float x1, float y, float x2, uint32 color) { Rect(x1, y, x2 - x1, pixel_in_dps, color); }
void vLine(float x, float y1, float y2, uint32 color) { Rect(x, y1, pixel_in_dps, y2 - y1, color); }
void vLineAlpha50(float x, float y1, float y2, uint32 color) { Rect(x, y1, pixel_in_dps, y2 - y1, (color | 0xFF000000) & 0x7F000000); }
void RectOutline(float x, float y, float w, float h, uint32 color, int align = ALIGN_TOPLEFT) {
hLine(x, y, x + w + 1, color);
hLine(x, y + h, x + w + 1, color);
hLine(x, y, x + w + pixel_in_dps, color);
hLine(x, y + h, x + w + pixel_in_dps, color);
vLine(x, y, y + h + 1, color);
vLine(x + w, y, y + h + 1, color);
vLine(x, y, y + h + pixel_in_dps, color);
vLine(x + w, y, y + h + pixel_in_dps, color);
}
void RectVGradient(float x, float y, float w, float h, uint32 colorTop, uint32 colorBottom);
+7
View File
@@ -36,6 +36,13 @@ float ease(float val) {
return ((-cosf(val * PI)) + 1.0f) * 0.5;
}
float ease(int t, int fadeLength)
{
if (t < 0) return 0.0f;
if (t >= fadeLength) return 1.0f;
return ease((float)t / (float)fadeLength);
}
float sawtooth(int t, int period) {
return (t % period) * (1.0f / (period - 1));
}
+1
View File
@@ -12,6 +12,7 @@ float linearOut(int t, int fadeInLength);
// smooth operator [0, 1] -> [0, 1]
float ease(float val);
float ease(int t, int fadeLength);
// need a bouncy ease
+95 -65
View File
@@ -1,27 +1,22 @@
#include "base/logging.h"
#include "input/input_state.h"
#include "ui/screen.h"
#include "ui/ui.h"
Screen::Screen(bool isUiScreen) : screenManager_(0), isUiScreen_(isUiScreen) { }
Screen::~Screen() { }
ScreenManager::ScreenManager() {
currentScreen_ = 0;
nextScreen_ = 0;
uiContext_ = 0;
dialogFinished_ = 0;
}
ScreenManager::~ScreenManager() {
delete currentScreen_;
shutdown();
}
void ScreenManager::switchScreen(Screen *screen) {
if (dialog_.size())
{
WLOG("Switching screens - dropping the whole dialog stack");
while (dialog_.size())
pop();
}
// Note that if a dialog is found, this will be a silent background switch that
// will only become apparent if the dialog is closed. The previous screen will stick around
// until that switch.
@@ -29,113 +24,148 @@ void ScreenManager::switchScreen(Screen *screen) {
if (nextScreen_ != 0) {
FLOG("WTF? Already had a nextScreen_");
}
if (screen != currentScreen_) {
if (stack_.empty() || screen != stack_.back().screen) {
nextScreen_ = screen;
nextScreen_->setScreenManager(this);
}
}
void ScreenManager::update(InputState &input) {
if (dialog_.size()) {
dialog_.back()->update(input);
return;
}
if (nextScreen_) {
ILOG("Screen switch!");
Screen *temp = currentScreen_;
currentScreen_ = nextScreen_;
delete temp;
temp = 0;
nextScreen_ = 0;
ILOG("Screen switch! Top of the stack switches.");
switchToNext();
}
if (currentScreen_) {
currentScreen_->update(input);
if (stack_.size()) {
stack_.back().screen->update(input);
}
}
void ScreenManager::switchToNext()
{
Layer temp = {0, 0};
if (!stack_.empty())
{
temp = stack_.back();
stack_.pop_back();
}
Layer newLayer = {nextScreen_, 0};
stack_.push_back(newLayer);
delete temp.screen;
nextScreen_ = 0;
}
void ScreenManager::touch(int pointer, float x, float y, double time, TouchEvent event)
{
if (dialog_.size()) {
dialog_.back()->touch(pointer, x, y, time, event);
if (stack_.size()) {
stack_.back().screen->touch(pointer, x, y, time, event);
return;
}
if (currentScreen_)
{
currentScreen_->touch(pointer, x, y, time, event);
}
}
void ScreenManager::render() {
if (dialog_.size()) {
dialog_.back()->render();
return;
}
if (currentScreen_) {
currentScreen_->render();
}
else {
if (stack_.size()) {
switch (stack_.back().flags)
{
case LAYER_SIDEMENU:
if (stack_.size() == 1)
{
ELOG("Can't have sidemenu over nothing");
break;
}
else
{
auto iter = stack_.end();
iter--;
iter--;
Layer backback = *iter;
UIDisableBegin();
// Also shift to the right somehow...
backback.screen->render();
UIDisableEnd();
stack_.back().screen->render();
break;
}
default:
stack_.back().screen->render();
break;
}
} else {
ELOG("No current screen!");
}
processFinishDialog();
}
void ScreenManager::deviceLost()
{
if (currentScreen_)
currentScreen_->deviceLost();
if (stack_.size())
stack_.back().screen->deviceLost();
// Dialogs too? Nah, they should only use the standard UI texture anyway.
// TODO: Change this when it becomes necessary.
}
Screen *ScreenManager::topScreen() {
if (dialog_.size())
return dialog_.back();
if (stack_.size())
return stack_.back().screen;
else
return currentScreen_;
return 0;
}
void ScreenManager::shutdown() {
if (nextScreen_) {
delete nextScreen_;
nextScreen_ = 0;
}
if (currentScreen_) {
delete currentScreen_;
currentScreen_ = 0;
for (auto x = stack_.begin(); x != stack_.end(); x++)
{
delete x->screen;
}
stack_.clear();
delete nextScreen_;
}
void ScreenManager::push(Screen *screen) {
void ScreenManager::push(Screen *screen, int layerFlags) {
if (nextScreen_ && stack_.empty()) {
// we're during init, this is OK
switchToNext();
}
screen->setScreenManager(this);
dialog_.push_back(screen);
Layer layer = {screen, layerFlags};
stack_.push_back(layer);
}
void ScreenManager::pop() {
if (dialog_.size()) {
delete dialog_.back();
dialog_.pop_back();
if (stack_.size()) {
delete stack_.back().screen;
stack_.pop_back();
} else {
ELOG("Can't push when no dialog is shown");
ELOG("Can't pop when stack empty");
}
}
void ScreenManager::finishDialog(const Screen *dialog, DialogResult result)
{
if (!dialog_.size()) {
ELOG("Must be in a dialog to finishDialog");
return;
}
Screen *dlg = dialog_.back();
if (dialog != dialog_.back())
if (dialog != stack_.back().screen)
{
ELOG("Wrong dialog being finished!");
return;
}
if (dialog_.size()) {
dialog_.pop_back();
if (!stack_.size()) {
ELOG("Must be in a dialog to finishDialog");
return;
}
Screen *caller = topScreen();
caller->dialogFinished(dialog, result);
delete dialog;
dialogFinished_ = dialog;
dialogResult_ = result;
}
void ScreenManager::processFinishDialog()
{
if (dialogFinished_)
{
if (stack_.size()) {
stack_.pop_back();
}
Screen *caller = topScreen();
caller->dialogFinished(dialogFinished_, dialogResult_);
delete dialogFinished_;
dialogFinished_ = 0;
}
}
+9 -5
View File
@@ -44,6 +44,8 @@ public:
ScreenManager *screenManager() { return screenManager_; }
void setScreenManager(ScreenManager *sm) { screenManager_ = sm; }
virtual void *dialogData() { return 0; }
private:
ScreenManager *screenManager_;
bool isUiScreen_;
@@ -76,7 +78,7 @@ public:
void shutdown();
// Push a dialog box in front. Currently 1-level only.
void push(Screen *screen);
void push(Screen *screen, int layerFlags = 0);
// Pops the dialog away.
void finishDialog(const Screen *dialog, DialogResult result = DR_OK);
@@ -86,14 +88,16 @@ public:
private:
void pop();
void switchToNext();
void processFinishDialog();
Screen *topScreen();
// Base screen. These don't "stack" and you can move in any order between them.
Screen *currentScreen_;
Screen *nextScreen_;
UIContext *uiContext_;
const Screen *dialogFinished_;
DialogResult dialogResult_;
struct Layer {
Screen *screen;
int flags; // From LAYER_ enum above
@@ -101,5 +105,5 @@ private:
// Dialog stack. These are shown "on top" of base screens and the Android back button works as expected.
// Used for options, in-game menus and other things you expect to be able to back out from onto something.
std::list<Screen *> dialog_;
std::list<Layer> stack_;
};
+9 -5
View File
@@ -286,7 +286,7 @@ void UIList::pointerDown(int pointer, float x, float y) {
const int holdFrames = 6;
void UIList::pointerMove(int pointer, float x, float y) {
void UIList::pointerMove(int pointer, float x, float y, bool inside) {
float deltaY = y - lastY;
movedDistanceY += fabsf(deltaY);
@@ -298,7 +298,7 @@ void UIList::pointerMove(int pointer, float x, float y) {
inertiaY = 0.8 * inertiaY + 0.2 * -deltaY;
}
if (movedDistanceY > 15 && !scrolling && uistate.mouseframesdown[0] > holdFrames) {
if (inside && movedDistanceY > 10 && !scrolling && uistate.mouseframesdown[0] > holdFrames) {
scrolling = true;
}
}
@@ -319,7 +319,9 @@ int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) {
// 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
@@ -331,7 +333,7 @@ int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) {
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]);
pointerMove(i, uistate.mousex[i], uistate.mousey[i], isInside);
}
}
@@ -343,7 +345,7 @@ int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) {
if (uistate.hotitem[i] == id) {
clicked = 1;
}
pointerUp(i, uistate.mousex[i], uistate.mousey[i], uistate.hotitem[i] == id);
pointerUp(i, uistate.mousex[i], uistate.mousey[i], isInside);
}
}
@@ -358,13 +360,15 @@ int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) {
if (!uistate.mousedown[0]) {
// Let it slide if the pointer is not down
scrollY += inertiaY;
} else if (scrolling && mouseY > y && mouseY < y + h) {
} 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;
+1 -1
View File
@@ -237,7 +237,7 @@ 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);
void pointerMove(int pointer, float x, float y, bool inside);
DISALLOW_COPY_AND_ASSIGN(UIList);
};
+40 -5
View File
@@ -23,19 +23,54 @@ void UIContext::Begin()
uidrawbufferTop_->Begin();*/
}
void UIContext::End()
void UIContext::RebindTexture()
{
if (uitexture_)
uitexture_->Bind(0);
}
void UIContext::Flush()
{
UIEnd();
if (uidrawbuffer_)
{
uidrawbuffer_->End();
if (uishader_)
if (uishader_) {
glsl_bind(uishader_);
uidrawbuffer_->Flush(uishader_);
}
}
if (uidrawbufferTop_)
{
uidrawbuffer_->End();
if (uishader_)
uidrawbufferTop_->End();
if (uishader_) {
glsl_bind(uishader_);
uidrawbufferTop_->Flush(uishader_);
}
}
}
void UIContext::FlushNoTex()
{
if (uidrawbuffer_)
{
uidrawbuffer_->End();
if (uishadernotex_) {
glsl_bind(uishadernotex_);
uidrawbuffer_->Flush(uishadernotex_);
}
}
if (uidrawbufferTop_)
{
uidrawbufferTop_->End();
if (uishadernotex_) {
glsl_bind(uishadernotex_);
uidrawbufferTop_->Flush(uishadernotex_);
}
}
}
void UIContext::End()
{
UIEnd();
Flush();
}
+6 -1
View File
@@ -11,19 +11,24 @@ class UIContext {
public:
UIContext() : uishader_(0), uitexture_(0), uidrawbuffer_(0), uidrawbufferTop_(0) {}
void Init(const GLSLProgram *uishader, Texture *uitexture, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop) {
void Init(const GLSLProgram *uishader, const GLSLProgram *uishadernotex, Texture *uitexture, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop) {
uishader_ = uishader;
uishadernotex_ = uishadernotex;
uitexture_ = uitexture;
uidrawbuffer_ = uidrawbuffer;
uidrawbufferTop_ = uidrawbufferTop;
}
void Begin();
void Flush();
void FlushNoTex();
void End();
void RebindTexture();
private:
// TODO: Collect these into a UIContext
const GLSLProgram *uishader_;
const GLSLProgram *uishadernotex_;
Texture *uitexture_;
DrawBuffer *uidrawbuffer_;
DrawBuffer *uidrawbufferTop_;