Fix line-endings in ui/screen.

This commit is contained in:
Unknown W. Brackets 2015-09-06 12:29:23 -07:00
parent f279c2a3c2
commit dbfc5385c3
2 changed files with 376 additions and 376 deletions

View file

@ -1,230 +1,230 @@
#include "base/logging.h"
#include "input/input_state.h"
#include "ui/screen.h"
#include "ui/ui.h"
#include "ui/view.h"
ScreenManager::ScreenManager() {
nextScreen_ = 0;
uiContext_ = 0;
dialogFinished_ = 0;
}
ScreenManager::~ScreenManager() {
shutdown();
}
void ScreenManager::switchScreen(Screen *screen) {
if (screen == nextScreen_) {
ELOG("Already switching to this screen");
return;
}
// 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.
// TODO: is this still true?
if (nextScreen_ != 0) {
FLOG("Already had a nextScreen_");
}
if (screen == 0) {
WLOG("Swiching to a zero screen, this can't be good");
}
if (stack_.empty() || screen != stack_.back().screen) {
nextScreen_ = screen;
nextScreen_->setScreenManager(this);
}
}
void ScreenManager::update(InputState &input) {
if (nextScreen_) {
switchToNext();
}
if (stack_.size()) {
stack_.back().screen->update(input);
}
}
void ScreenManager::switchToNext() {
if (!nextScreen_) {
ELOG("switchToNext: No nextScreen_!");
}
Layer temp = {0, 0};
if (!stack_.empty()) {
temp = stack_.back();
stack_.pop_back();
}
Layer newLayer = {nextScreen_, 0};
stack_.push_back(newLayer);
if (temp.screen) {
delete temp.screen;
}
nextScreen_ = 0;
UI::SetFocusedView(0);
}
bool ScreenManager::touch(const TouchInput &touch) {
if (!stack_.empty()) {
return stack_.back().screen->touch(touch);
} else {
return false;
}
}
bool ScreenManager::key(const KeyInput &key) {
if (!stack_.empty()) {
return stack_.back().screen->key(key);
} else {
return false;
}
}
bool ScreenManager::axis(const AxisInput &axis) {
if (!stack_.empty()) {
return stack_.back().screen->axis(axis);
} else {
return false;
}
}
void ScreenManager::resized() {
// Have to notify the whole stack, otherwise there will be problems when going back
// to non-top screens.
for (auto iter = stack_.begin(); iter != stack_.end(); ++iter) {
iter->screen->resized();
}
}
void ScreenManager::render() {
if (!stack_.empty()) {
switch (stack_.back().flags) {
case LAYER_SIDEMENU:
case LAYER_TRANSPARENT:
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::sendMessage(const char *msg, const char *value) {
if (!strcmp(msg, "recreateviews"))
RecreateAllViews();
if (!stack_.empty())
stack_.back().screen->sendMessage(msg, value);
}
void ScreenManager::deviceLost() {
for (size_t i = 0; i < stack_.size(); i++) {
stack_[i].screen->deviceLost();
}
// Dialogs too? Nah, they should only use the standard UI texture anyway.
// TODO: Change this when it becomes necessary.
}
Screen *ScreenManager::topScreen() const {
if (!stack_.empty())
return stack_.back().screen;
else
return 0;
}
void ScreenManager::shutdown() {
for (auto x = stack_.begin(); x != stack_.end(); x++)
delete x->screen;
stack_.clear();
delete nextScreen_;
nextScreen_ = 0;
}
void ScreenManager::push(Screen *screen, int layerFlags) {
if (nextScreen_ && stack_.empty()) {
// we're during init, this is OK
switchToNext();
}
screen->setScreenManager(this);
if (screen->isTransparent()) {
layerFlags |= LAYER_TRANSPARENT;
}
UI::SetFocusedView(0);
Layer layer = {screen, layerFlags};
stack_.push_back(layer);
}
void ScreenManager::pop() {
if (stack_.size()) {
delete stack_.back().screen;
stack_.pop_back();
} else {
ELOG("Can't pop when stack empty");
}
}
void ScreenManager::RecreateAllViews() {
for (auto it = stack_.begin(); it != stack_.end(); ++it) {
it->screen->RecreateViews();
}
}
void ScreenManager::finishDialog(Screen *dialog, DialogResult result) {
if (stack_.empty()) {
ELOG("Must be in a dialog to finishDialog");
return;
}
if (dialog != stack_.back().screen) {
ELOG("Wrong dialog being finished!");
return;
}
dialog->onFinish(result);
dialogFinished_ = dialog;
dialogResult_ = result;
}
void ScreenManager::processFinishDialog() {
if (dialogFinished_) {
// Another dialog may have been pushed before the render, so search for it.
Screen *caller = 0;
for (size_t i = 0; i < stack_.size(); ++i) {
if (stack_[i].screen != dialogFinished_) {
continue;
}
stack_.erase(stack_.begin() + i);
// The previous screen was the caller (not necessarily the topmost.)
if (i > 0) {
caller = stack_[i - 1].screen;
}
}
if (!caller) {
ELOG("ERROR: no top screen when finishing dialog");
} else if (caller != topScreen()) {
// The caller may get confused if we call dialogFinished() now.
WLOG("Skipping non-top dialog when finishing dialog.");
} else {
caller->dialogFinished(dialogFinished_, dialogResult_);
}
delete dialogFinished_;
dialogFinished_ = 0;
}
}
#include "base/logging.h"
#include "input/input_state.h"
#include "ui/screen.h"
#include "ui/ui.h"
#include "ui/view.h"
ScreenManager::ScreenManager() {
nextScreen_ = 0;
uiContext_ = 0;
dialogFinished_ = 0;
}
ScreenManager::~ScreenManager() {
shutdown();
}
void ScreenManager::switchScreen(Screen *screen) {
if (screen == nextScreen_) {
ELOG("Already switching to this screen");
return;
}
// 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.
// TODO: is this still true?
if (nextScreen_ != 0) {
FLOG("Already had a nextScreen_");
}
if (screen == 0) {
WLOG("Swiching to a zero screen, this can't be good");
}
if (stack_.empty() || screen != stack_.back().screen) {
nextScreen_ = screen;
nextScreen_->setScreenManager(this);
}
}
void ScreenManager::update(InputState &input) {
if (nextScreen_) {
switchToNext();
}
if (stack_.size()) {
stack_.back().screen->update(input);
}
}
void ScreenManager::switchToNext() {
if (!nextScreen_) {
ELOG("switchToNext: No nextScreen_!");
}
Layer temp = {0, 0};
if (!stack_.empty()) {
temp = stack_.back();
stack_.pop_back();
}
Layer newLayer = {nextScreen_, 0};
stack_.push_back(newLayer);
if (temp.screen) {
delete temp.screen;
}
nextScreen_ = 0;
UI::SetFocusedView(0);
}
bool ScreenManager::touch(const TouchInput &touch) {
if (!stack_.empty()) {
return stack_.back().screen->touch(touch);
} else {
return false;
}
}
bool ScreenManager::key(const KeyInput &key) {
if (!stack_.empty()) {
return stack_.back().screen->key(key);
} else {
return false;
}
}
bool ScreenManager::axis(const AxisInput &axis) {
if (!stack_.empty()) {
return stack_.back().screen->axis(axis);
} else {
return false;
}
}
void ScreenManager::resized() {
// Have to notify the whole stack, otherwise there will be problems when going back
// to non-top screens.
for (auto iter = stack_.begin(); iter != stack_.end(); ++iter) {
iter->screen->resized();
}
}
void ScreenManager::render() {
if (!stack_.empty()) {
switch (stack_.back().flags) {
case LAYER_SIDEMENU:
case LAYER_TRANSPARENT:
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::sendMessage(const char *msg, const char *value) {
if (!strcmp(msg, "recreateviews"))
RecreateAllViews();
if (!stack_.empty())
stack_.back().screen->sendMessage(msg, value);
}
void ScreenManager::deviceLost() {
for (size_t i = 0; i < stack_.size(); i++) {
stack_[i].screen->deviceLost();
}
// Dialogs too? Nah, they should only use the standard UI texture anyway.
// TODO: Change this when it becomes necessary.
}
Screen *ScreenManager::topScreen() const {
if (!stack_.empty())
return stack_.back().screen;
else
return 0;
}
void ScreenManager::shutdown() {
for (auto x = stack_.begin(); x != stack_.end(); x++)
delete x->screen;
stack_.clear();
delete nextScreen_;
nextScreen_ = 0;
}
void ScreenManager::push(Screen *screen, int layerFlags) {
if (nextScreen_ && stack_.empty()) {
// we're during init, this is OK
switchToNext();
}
screen->setScreenManager(this);
if (screen->isTransparent()) {
layerFlags |= LAYER_TRANSPARENT;
}
UI::SetFocusedView(0);
Layer layer = {screen, layerFlags};
stack_.push_back(layer);
}
void ScreenManager::pop() {
if (stack_.size()) {
delete stack_.back().screen;
stack_.pop_back();
} else {
ELOG("Can't pop when stack empty");
}
}
void ScreenManager::RecreateAllViews() {
for (auto it = stack_.begin(); it != stack_.end(); ++it) {
it->screen->RecreateViews();
}
}
void ScreenManager::finishDialog(Screen *dialog, DialogResult result) {
if (stack_.empty()) {
ELOG("Must be in a dialog to finishDialog");
return;
}
if (dialog != stack_.back().screen) {
ELOG("Wrong dialog being finished!");
return;
}
dialog->onFinish(result);
dialogFinished_ = dialog;
dialogResult_ = result;
}
void ScreenManager::processFinishDialog() {
if (dialogFinished_) {
// Another dialog may have been pushed before the render, so search for it.
Screen *caller = 0;
for (size_t i = 0; i < stack_.size(); ++i) {
if (stack_[i].screen != dialogFinished_) {
continue;
}
stack_.erase(stack_.begin() + i);
// The previous screen was the caller (not necessarily the topmost.)
if (i > 0) {
caller = stack_[i - 1].screen;
}
}
if (!caller) {
ELOG("ERROR: no top screen when finishing dialog");
} else if (caller != topScreen()) {
// The caller may get confused if we call dialogFinished() now.
WLOG("Skipping non-top dialog when finishing dialog.");
} else {
caller->dialogFinished(dialogFinished_, dialogResult_);
}
delete dialogFinished_;
dialogFinished_ = 0;
}
}

View file

@ -1,146 +1,146 @@
// Super basic screen manager. Let's you, well, switch between screens. Can also be used
// to pop one screen in front for a bit while keeping another one running, it's basically
// a native "activity stack". Well actually that part is still a TODO.
//
// Semantics
//
// switchScreen: When you call this, on a newed screen, the ScreenManager takes ownership.
// On the next update, it switches to the new screen and deletes the previous screen.
//
// TODO: A way to do smooth transitions between screens. Will probably involve screenshotting
// the previous screen and then animating it on top of the current screen with transparency
// and/or other similar effects.
#pragma once
#include <vector>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/NativeApp.h"
namespace UI {
class View;
}
struct InputState;
enum DialogResult {
DR_OK,
DR_CANCEL,
DR_YES,
DR_NO,
DR_BACK,
};
class ScreenManager;
class UIContext;
class Thin3DContext;
class Screen {
public:
Screen() : screenManager_(0) { }
virtual ~Screen() {
screenManager_ = 0;
}
virtual void onFinish(DialogResult reason) {}
virtual void update(InputState &input) {}
virtual void render() {}
virtual void deviceLost() {}
virtual void resized() {}
virtual void dialogFinished(const Screen *dialog, DialogResult result) {}
virtual bool touch(const TouchInput &touch) { return false; }
virtual bool key(const KeyInput &key) { return false; }
virtual bool axis(const AxisInput &touch) { return false; }
virtual void sendMessage(const char *msg, const char *value) {}
virtual void RecreateViews() {}
ScreenManager *screenManager() { return screenManager_; }
void setScreenManager(ScreenManager *sm) { screenManager_ = sm; }
// This one is icky to use because you can't know what's in it until you know
// what screen it is.
virtual void *dialogData() { return 0; }
virtual std::string tag() const { return std::string(""); }
virtual bool isTransparent() const { return false; }
virtual bool isTopLevel() const { return false; }
private:
ScreenManager *screenManager_;
DISALLOW_COPY_AND_ASSIGN(Screen);
};
class Transition {
public:
Transition() {}
};
enum {
LAYER_SIDEMENU = 1,
LAYER_TRANSPARENT = 2,
};
class ScreenManager {
public:
ScreenManager();
virtual ~ScreenManager();
void switchScreen(Screen *screen);
void update(InputState &input);
void setUIContext(UIContext *context) { uiContext_ = context; }
UIContext *getUIContext() { return uiContext_; }
void setThin3DContext(Thin3DContext *context) { thin3DContext_ = context; }
Thin3DContext *getThin3DContext() { return thin3DContext_; }
void render();
void resized();
void deviceLost();
void shutdown();
// Push a dialog box in front. Currently 1-level only.
void push(Screen *screen, int layerFlags = 0);
// Recreate all views
void RecreateAllViews();
// Pops the dialog away.
void finishDialog(Screen *dialog, DialogResult result = DR_OK);
// Instant touch, separate from the update() mechanism.
bool touch(const TouchInput &touch);
bool key(const KeyInput &key);
bool axis(const AxisInput &touch);
// Generic facility for gross hacks :P
void sendMessage(const char *msg, const char *value);
Screen *topScreen() const;
private:
void pop();
void switchToNext();
void processFinishDialog();
Screen *nextScreen_;
UIContext *uiContext_;
Thin3DContext *thin3DContext_;
const Screen *dialogFinished_;
DialogResult dialogResult_;
struct Layer {
Screen *screen;
int flags; // From LAYER_ enum above
UI::View *focusedView; // TODO: save focus here. Going for quick solution now to reset focus.
};
// 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::vector<Layer> stack_;
};
// Super basic screen manager. Let's you, well, switch between screens. Can also be used
// to pop one screen in front for a bit while keeping another one running, it's basically
// a native "activity stack". Well actually that part is still a TODO.
//
// Semantics
//
// switchScreen: When you call this, on a newed screen, the ScreenManager takes ownership.
// On the next update, it switches to the new screen and deletes the previous screen.
//
// TODO: A way to do smooth transitions between screens. Will probably involve screenshotting
// the previous screen and then animating it on top of the current screen with transparency
// and/or other similar effects.
#pragma once
#include <vector>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/NativeApp.h"
namespace UI {
class View;
}
struct InputState;
enum DialogResult {
DR_OK,
DR_CANCEL,
DR_YES,
DR_NO,
DR_BACK,
};
class ScreenManager;
class UIContext;
class Thin3DContext;
class Screen {
public:
Screen() : screenManager_(0) { }
virtual ~Screen() {
screenManager_ = 0;
}
virtual void onFinish(DialogResult reason) {}
virtual void update(InputState &input) {}
virtual void render() {}
virtual void deviceLost() {}
virtual void resized() {}
virtual void dialogFinished(const Screen *dialog, DialogResult result) {}
virtual bool touch(const TouchInput &touch) { return false; }
virtual bool key(const KeyInput &key) { return false; }
virtual bool axis(const AxisInput &touch) { return false; }
virtual void sendMessage(const char *msg, const char *value) {}
virtual void RecreateViews() {}
ScreenManager *screenManager() { return screenManager_; }
void setScreenManager(ScreenManager *sm) { screenManager_ = sm; }
// This one is icky to use because you can't know what's in it until you know
// what screen it is.
virtual void *dialogData() { return 0; }
virtual std::string tag() const { return std::string(""); }
virtual bool isTransparent() const { return false; }
virtual bool isTopLevel() const { return false; }
private:
ScreenManager *screenManager_;
DISALLOW_COPY_AND_ASSIGN(Screen);
};
class Transition {
public:
Transition() {}
};
enum {
LAYER_SIDEMENU = 1,
LAYER_TRANSPARENT = 2,
};
class ScreenManager {
public:
ScreenManager();
virtual ~ScreenManager();
void switchScreen(Screen *screen);
void update(InputState &input);
void setUIContext(UIContext *context) { uiContext_ = context; }
UIContext *getUIContext() { return uiContext_; }
void setThin3DContext(Thin3DContext *context) { thin3DContext_ = context; }
Thin3DContext *getThin3DContext() { return thin3DContext_; }
void render();
void resized();
void deviceLost();
void shutdown();
// Push a dialog box in front. Currently 1-level only.
void push(Screen *screen, int layerFlags = 0);
// Recreate all views
void RecreateAllViews();
// Pops the dialog away.
void finishDialog(Screen *dialog, DialogResult result = DR_OK);
// Instant touch, separate from the update() mechanism.
bool touch(const TouchInput &touch);
bool key(const KeyInput &key);
bool axis(const AxisInput &touch);
// Generic facility for gross hacks :P
void sendMessage(const char *msg, const char *value);
Screen *topScreen() const;
private:
void pop();
void switchToNext();
void processFinishDialog();
Screen *nextScreen_;
UIContext *uiContext_;
Thin3DContext *thin3DContext_;
const Screen *dialogFinished_;
DialogResult dialogResult_;
struct Layer {
Screen *screen;
int flags; // From LAYER_ enum above
UI::View *focusedView; // TODO: save focus here. Going for quick solution now to reset focus.
};
// 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::vector<Layer> stack_;
};