Added keyboard-input for Lua-scripting.

ver1_5_1
Harald Schmidt 2004-01-09 20:19:47 +00:00
parent 32978ca4b6
commit 46d3574fcb
4 changed files with 111 additions and 15 deletions

View File

@ -284,7 +284,7 @@ CelestiaCore::CelestiaCore() :
messageDuration(0.0),
typedText(""),
typedTextCompletionIdx(-1),
textEnterMode(false),
textEnterMode(KbNormal),
hudDetail(1),
wireframe(false),
editMode(false),
@ -1002,7 +1002,7 @@ void CelestiaCore::keyDown(int key, int modifiers)
// Only process alphanumeric keys if we're not in text enter mode
if (islower(key))
key = toupper(key);
if (!(key >= 'A' && key <= 'Z' && textEnterMode))
if (!(key >= 'A' && key <= 'Z' && (textEnterMode != KbNormal) ))
{
if (modifiers & ShiftKey)
shiftKeysPressed[key] = true;
@ -1024,7 +1024,17 @@ void CelestiaCore::charEntered(char c)
{
Observer* observer = sim->getActiveObserver();
if (textEnterMode)
if (celxScript != NULL && (textEnterMode & KbPassToScript))
{
if (c != '\033' && celxScript->charEntered(c))
{
return;
}
// TODO: What to do with AutoComplete-activation while
// in PassToScript-mode?
}
if (textEnterMode & KbAutoComplete)
{
if ( c == ' ' || isalpha(c) || isdigit(c) || ispunct(c))
{
@ -1095,10 +1105,7 @@ void CelestiaCore::charEntered(char c)
}
else if (c == '\033') // ESC
{
typedText = "";
textEnterMode = false;
typedTextCompletion.clear();
typedTextCompletionIdx = -1;
setTextEnterMode(textEnterMode & ~KbAutoComplete);
}
else if (c == '\n' || c == '\r')
{
@ -1112,9 +1119,7 @@ void CelestiaCore::charEntered(char c)
}
typedText = "";
}
textEnterMode = false;
typedTextCompletion.clear();
typedTextCompletionIdx = -1;
setTextEnterMode(textEnterMode & ~KbAutoComplete);
}
return;
}
@ -1134,7 +1139,7 @@ void CelestiaCore::charEntered(char c)
case '\n':
case '\r':
textEnterMode = true;
setTextEnterMode(textEnterMode | KbAutoComplete);
break;
case '\b':
@ -1320,9 +1325,9 @@ void CelestiaCore::charEntered(char c)
case '\033': // Escape
cancelScript();
addToHistory();
if (textEnterMode == true)
if (textEnterMode != KbNormal)
{
textEnterMode = false;
setTextEnterMode(KbNormal);
}
else
{
@ -3038,7 +3043,7 @@ void CelestiaCore::renderOverlay()
}
// Text input
if (textEnterMode)
if (textEnterMode & KbAutoComplete)
{
overlay->setFont(titleFont);
// glPushMatrix();
@ -3700,6 +3705,22 @@ void CelestiaCore::setLightDelayActive(bool lightDelayActive)
lightTravelFlag = lightDelayActive;
}
void CelestiaCore::setTextEnterMode(int mode)
{
cout << "setTextEnterMode("<<mode<<")\n";
if (mode != textEnterMode)
{
if ((mode & KbAutoComplete) != (textEnterMode & KbAutoComplete))
{
typedText = "";
typedTextCompletion.clear();
typedTextCompletionIdx = -1;
}
textEnterMode = mode;
notifyWatchers(TextEnterModeChanged);
}
}
int CelestiaCore::getTextEnterMode() const
{
return textEnterMode;

View File

@ -147,8 +147,16 @@ class CelestiaCore // : public Watchable<CelestiaCore>
AmbientLightChanged = 16,
FaintestChanged = 32,
HistoryChanged = 64,
TextEnterModeChanged = 128,
};
enum
{
KbNormal = 0,
KbAutoComplete = 1,
KbPassToScript = 2,
};
typedef void (*ContextMenuFunc)(float, float, Selection);
public:
@ -205,6 +213,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
void setTimeZoneBias(int);
std::string getTimeZoneName() const;
void setTimeZoneName(const std::string&);
void setTextEnterMode(int);
int getTextEnterMode() const;
void initMovieCapture(MovieCapture*);
@ -293,7 +302,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
std::string typedText;
std::vector<std::string> typedTextCompletion;
int typedTextCompletionIdx;
bool textEnterMode;
int textEnterMode;
int hudDetail;
bool wireframe;
bool editMode;

View File

@ -57,6 +57,8 @@ static const int _Frame = 7;
// returning control to celestia
static const double MaxTimeslice = 5.0;
static const char* KbdCallback = "celestia_keyboard_callback";
// select which type of error will be fatal (call lua_error) and
// which will return a default value instead
enum FatalErrors {
@ -201,6 +203,33 @@ double LuaState::getTime() const
return timer->getTime();
}
// Callback for CelestiaCore::charEntered.
// Returns true if keypress has been consumed
bool LuaState::charEntered(char c)
{
int stack_top = lua_gettop(costate);
bool result = true;
lua_pushstring(costate, KbdCallback);
lua_gettable(costate, LUA_GLOBALSINDEX);
lua_pushnumber(costate, static_cast<lua_Number>(c));
timeout = getTime() + 1.0;
if (lua_pcall(costate, 1, 1, 0) != 0)
{
cerr << "Error while executing keyboard-callback: " << lua_tostring(costate, -1) << "\n";
result = false;
}
else
{
if (lua_isboolean(costate, -1))
{
result = static_cast<bool>(lua_toboolean(costate, -1));
}
}
// cleanup stack - is this necessary?
lua_settop(costate, stack_top);
return result;
}
static void checkTimeslice(lua_State *l, lua_Debug *ar)
{
lua_pushstring(l, "celestia-luastate");
@ -2675,6 +2704,41 @@ static int celestia_newframe(lua_State* l)
return 1;
}
static int celestia_requestkeyboard(lua_State* l)
{
checkArgs(l, 2, 2, "Need one arguments for celestia:requestkeyboard");
CelestiaCore* appCore = this_celestia(l);
if (!lua_isboolean(l, 2))
{
lua_pushstring(l, "First argument for celestia:requestkeyboard must be a boolean");
lua_error(l);
}
int mode = appCore->getTextEnterMode();
if (lua_toboolean(l, 2))
{
// Check for existence of charEntered:
lua_pushstring(l, KbdCallback);
lua_gettable(l, LUA_GLOBALSINDEX);
if (lua_isnil(l, -1))
{
lua_pushstring(l, "script requested keyboard, but did not provide callback");
lua_error(l);
}
lua_remove(l, -1);
mode = mode | CelestiaCore::KbPassToScript;
}
else
{
mode = mode & ~CelestiaCore::KbPassToScript;
}
appCore->setTextEnterMode(mode);
return 0;
}
static int celestia_tostring(lua_State* l)
{
@ -2715,6 +2779,7 @@ static void CreateCelestiaMetaTable(lua_State* l)
RegisterMethod(l, "newvector", celestia_newvector);
RegisterMethod(l, "newrotation", celestia_newrotation);
RegisterMethod(l, "getscripttime", celestia_getscripttime);
RegisterMethod(l, "requestkeyboard", celestia_requestkeyboard);
lua_pop(l, 1);
}

View File

@ -40,6 +40,7 @@ public:
bool isAlive() const;
bool timesliceExpired() const;
bool charEntered(char c);
double getTime() const;
private:
double timeout;