Added keyboard-input for Lua-scripting.
parent
32978ca4b6
commit
46d3574fcb
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
bool isAlive() const;
|
||||
bool timesliceExpired() const;
|
||||
|
||||
bool charEntered(char c);
|
||||
double getTime() const;
|
||||
private:
|
||||
double timeout;
|
||||
|
|
Loading…
Reference in New Issue