Completion patch
parent
1e5941ce43
commit
1de258c1fb
|
@ -493,3 +493,22 @@ bool PlanetarySystem::traverse(TraversalFunc func, void* info) const
|
|||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> PlanetarySystem::getCompletion(const std::string& _name) const
|
||||
{
|
||||
std::vector<std::string> completion;
|
||||
for (vector<Body*>::const_iterator iter = satellites.begin();
|
||||
iter != satellites.end(); iter++)
|
||||
{
|
||||
if (compareIgnoringCase((*iter)->getName(), _name, _name.length()) == 0)
|
||||
{
|
||||
completion.push_back((*iter)->getName());
|
||||
}
|
||||
if ((*iter)->getSatellites() != NULL)
|
||||
{
|
||||
std::vector<std::string> bodies = (*iter)->getSatellites()->getCompletion(_name);
|
||||
completion.insert(completion.end(), bodies.begin(), bodies.end());
|
||||
}
|
||||
}
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class PlanetarySystem
|
|||
|
||||
bool traverse(TraversalFunc, void*) const;
|
||||
Body* find(std::string, bool deepSearch = false) const;
|
||||
std::vector<std::string> getCompletion(const std::string& _name) const;
|
||||
|
||||
private:
|
||||
Star* star;
|
||||
|
|
|
@ -456,6 +456,32 @@ Selection Simulation::findObjectFromPath(string s)
|
|||
return universe->findPath(s, path, nPathEntries);
|
||||
}
|
||||
|
||||
std::vector<std::string> Simulation::getObjectCompletion(string s)
|
||||
{
|
||||
PlanetarySystem* path[2];
|
||||
int nPathEntries = 0;
|
||||
PlanetarySystem* sys = NULL;
|
||||
|
||||
if (selection.star != NULL)
|
||||
{
|
||||
SolarSystem* solsys = universe->getSolarSystem(selection.star);
|
||||
if (solsys != NULL)
|
||||
sys = path[nPathEntries++] = solsys->getPlanets();
|
||||
}
|
||||
else if (selection.body != NULL)
|
||||
{
|
||||
sys = selection.body->getSystem();
|
||||
while (sys != NULL && sys->getPrimaryBody() != NULL)
|
||||
sys = sys->getPrimaryBody()->getSystem();
|
||||
path[nPathEntries++] = sys;
|
||||
}
|
||||
|
||||
if (closestSolarSystem != NULL && closestSolarSystem->getPlanets() != sys)
|
||||
path[nPathEntries++] = closestSolarSystem->getPlanets();
|
||||
|
||||
return universe->getCompletionPath(s, path, nPathEntries);
|
||||
}
|
||||
|
||||
|
||||
double Simulation::getTimeScale() const
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ class Simulation
|
|||
void selectPlanet(int);
|
||||
Selection findObject(std::string s);
|
||||
Selection findObjectFromPath(std::string s);
|
||||
std::vector<std::string> getObjectCompletion(std::string s);
|
||||
void gotoSelection(double gotoTime,
|
||||
Vec3f up, astro::CoordinateSystem upFrame);
|
||||
void gotoSelection(double gotoTime, double distance,
|
||||
|
|
|
@ -100,7 +100,7 @@ Star* StarDatabase::find(const string& name) const
|
|||
// Search by the default catalog number
|
||||
uint32 catalogNumber = (uint32) atoi(string(name, 1, string::npos).c_str());
|
||||
return find(catalogNumber, 0);
|
||||
|
||||
|
||||
}
|
||||
else if (compareIgnoringCase(name, HDCatalogPrefix, HDCatalogPrefix.length()) == 0)
|
||||
{
|
||||
|
@ -152,6 +152,20 @@ Star* StarDatabase::find(const string& name) const
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> StarDatabase::getCompletion(const string& name) const
|
||||
{
|
||||
std::vector<std::string> completion;
|
||||
|
||||
if (name.empty())
|
||||
return completion;
|
||||
|
||||
// only named stars are supported by completion.
|
||||
if (names != NULL)
|
||||
{
|
||||
return names->getCompletion(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Return the name for the star with specified catalog number. The returned
|
||||
// string will be:
|
||||
|
|
|
@ -29,6 +29,7 @@ class StarDatabase
|
|||
inline uint32 size() const;
|
||||
Star* find(uint32 catalogNumber, unsigned int whichCatalog = 0) const;
|
||||
Star* find(const std::string&) const;
|
||||
std::vector<std::string> getCompletion(const std::string&) const;
|
||||
|
||||
void findVisibleStars(StarHandler& starHandler,
|
||||
const Point3f& position,
|
||||
|
|
|
@ -91,6 +91,20 @@ uint32 StarNameDatabase::findCatalogNumber(const string& name) const
|
|||
return iter->second;
|
||||
}
|
||||
|
||||
std::vector<std::string> StarNameDatabase::getCompletion(const std::string& name) const
|
||||
{
|
||||
std::vector<std::string> completion;
|
||||
for (NameIndex::const_iterator iter = nameIndex.begin();
|
||||
iter != nameIndex.end() ; iter++)
|
||||
{
|
||||
if (!compareIgnoringCase(iter->first, name, name.length()))
|
||||
{
|
||||
completion.push_back(iter->first);
|
||||
}
|
||||
}
|
||||
return completion;
|
||||
}
|
||||
|
||||
|
||||
// Return the first name matching the catalog number or finalName()
|
||||
// if there are no matching names. The first name *should* be the
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <celutil/basictypes.h>
|
||||
#include <celutil/util.h>
|
||||
#include <celengine/constellation.h>
|
||||
|
@ -73,6 +74,7 @@ class StarNameDatabase
|
|||
void add(uint32, const std::string&);
|
||||
uint32 findCatalogNumber(const std::string& name) const;
|
||||
uint32 findName(std::string name) const;
|
||||
std::vector<std::string> getCompletion(const std::string& name) const;
|
||||
NumberIndex::const_iterator findFirstName(uint32 catalogNumber) const;
|
||||
NumberIndex::const_iterator finalName() const;
|
||||
|
||||
|
|
|
@ -753,7 +753,7 @@ Selection Universe::findPath(const string& s,
|
|||
len = nextPos - pos - 1;
|
||||
|
||||
string name = string(s, pos + 1, len);
|
||||
|
||||
|
||||
Body* body = worlds->find(name);
|
||||
if (body == NULL)
|
||||
{
|
||||
|
@ -773,6 +773,82 @@ Selection Universe::findPath(const string& s,
|
|||
return Selection();
|
||||
}
|
||||
|
||||
std::vector<std::string> Universe::getCompletion(const string& s,
|
||||
PlanetarySystem** solarSystems,
|
||||
int nSolarSystems)
|
||||
{
|
||||
std::vector<std::string> completion;
|
||||
|
||||
// solar bodies first
|
||||
for (int i = 0; i < nSolarSystems; i++)
|
||||
{
|
||||
if (solarSystems[i] != NULL)
|
||||
{
|
||||
std::vector<std::string> bodies = solarSystems[i]->getCompletion(s);
|
||||
completion.insert(completion.end(), bodies.begin(), bodies.end());
|
||||
}
|
||||
}
|
||||
|
||||
// Deep sky object
|
||||
if (deepSkyCatalog != NULL)
|
||||
{
|
||||
for (DeepSkyCatalog::const_iterator iter = deepSkyCatalog->begin();
|
||||
iter != deepSkyCatalog->end(); iter++)
|
||||
{
|
||||
if (compareIgnoringCase((*iter)->getName(), s, s.length()) == 0)
|
||||
completion.push_back(Selection(*iter).getName());
|
||||
}
|
||||
}
|
||||
|
||||
// finaly stars;
|
||||
std::vector<std::string> stars = starCatalog->getCompletion(s);
|
||||
completion.insert(completion.end(), stars.begin(), stars.end());
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
||||
std::vector<std::string> Universe::getCompletionPath(const string& s,
|
||||
PlanetarySystem* solarSystems[],
|
||||
int nSolarSystems)
|
||||
{
|
||||
std::vector<std::string> completion;
|
||||
string::size_type pos = s.rfind('/', s.length());
|
||||
|
||||
if (pos == string::npos)
|
||||
return getCompletion(s, solarSystems, nSolarSystems);
|
||||
|
||||
string base(s, 0, pos);
|
||||
Selection sel = find(base, solarSystems, nSolarSystems);
|
||||
|
||||
if (sel.empty())
|
||||
return completion;
|
||||
|
||||
if (sel.deepsky != NULL)
|
||||
{
|
||||
completion.push_back(sel.deepsky->getName());
|
||||
return completion;
|
||||
}
|
||||
|
||||
PlanetarySystem* worlds = NULL;
|
||||
if (sel.body != NULL)
|
||||
{
|
||||
worlds = sel.body->getSatellites();
|
||||
}
|
||||
else if (sel.star != NULL)
|
||||
{
|
||||
SolarSystem* ssys = getSolarSystem(sel.star);
|
||||
if (ssys != NULL)
|
||||
worlds = ssys->getPlanets();
|
||||
}
|
||||
|
||||
if (worlds != NULL)
|
||||
{
|
||||
return worlds->getCompletion(s.substr(pos + 1));
|
||||
}
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
||||
|
||||
// Return the closest solar system to position, or NULL if there are no planets
|
||||
// with in one light year.
|
||||
|
|
|
@ -55,6 +55,12 @@ class Universe
|
|||
Selection findPath(const std::string& s,
|
||||
PlanetarySystem** solarSystems = NULL,
|
||||
int nSolarSystems = 0);
|
||||
std::vector<std::string> getCompletion(const std::string& s,
|
||||
PlanetarySystem** solarSystems = NULL,
|
||||
int nSolarSystems = 0);
|
||||
std::vector<std::string> getCompletionPath(const std::string& s,
|
||||
PlanetarySystem** solarSystems = NULL,
|
||||
int nSolarSystems = 0);
|
||||
|
||||
SolarSystem* getNearestSolarSystem(const UniversalCoord& position) const;
|
||||
SolarSystem* getSolarSystem(const Star* star) const;
|
||||
|
|
|
@ -282,7 +282,8 @@ CelestiaCore::CelestiaCore() :
|
|||
activeView(0),
|
||||
showActiveViewFrame(false),
|
||||
showViewFrames(true),
|
||||
resizeSplit(0)
|
||||
resizeSplit(0),
|
||||
typedTextCompletionIdx(-1)
|
||||
{
|
||||
/* Get a renderer here so it may be queried for capabilities of the
|
||||
underlying engine even before rendering is enabled. It's initRenderer()
|
||||
|
@ -889,21 +890,65 @@ void CelestiaCore::charEntered(char c)
|
|||
|
||||
if (textEnterMode)
|
||||
{
|
||||
if (c == ' ' || isalpha(c) || isdigit(c) || ispunct(c))
|
||||
if ( c == ' ' || isalpha(c) || isdigit(c) || ispunct(c))
|
||||
{
|
||||
typedText += c;
|
||||
typedTextCompletion = sim->getObjectCompletion(typedText);
|
||||
if (typedTextCompletion.size() == 1)
|
||||
typedText = typedTextCompletion[0];
|
||||
}
|
||||
else if (c == '\b')
|
||||
{
|
||||
typedTextCompletionIdx = -1;
|
||||
if (typedText.size() > 0)
|
||||
typedText = string(typedText, 0, typedText.size() - 1);
|
||||
{
|
||||
do
|
||||
{
|
||||
typedText = string(typedText, 0, typedText.size() - 1);
|
||||
if (typedText.size() > 0)
|
||||
{
|
||||
typedTextCompletion = sim->getObjectCompletion(typedText);
|
||||
} else {
|
||||
typedTextCompletion.clear();
|
||||
}
|
||||
} while (typedText.size() > 0 && typedTextCompletion.size() == 1);
|
||||
}
|
||||
}
|
||||
else if (c == '\011') // TAB
|
||||
{
|
||||
if (typedTextCompletionIdx + 1 < typedTextCompletion.size())
|
||||
typedTextCompletionIdx++;
|
||||
else if (typedTextCompletion.size() > 0 && typedTextCompletionIdx + 1 == typedTextCompletion.size())
|
||||
typedTextCompletionIdx = 0;
|
||||
if (typedTextCompletionIdx >= 0) {
|
||||
typedText = typedTextCompletion[typedTextCompletionIdx];
|
||||
}
|
||||
}
|
||||
else if (c == Key_BackTab)
|
||||
{
|
||||
if (typedTextCompletionIdx > 0)
|
||||
typedTextCompletionIdx--;
|
||||
else if (typedTextCompletionIdx == 0)
|
||||
typedTextCompletionIdx = typedTextCompletion.size() - 1;
|
||||
else if (typedTextCompletion.size() > 0)
|
||||
typedTextCompletionIdx = typedTextCompletion.size() - 1;
|
||||
if (typedTextCompletionIdx >= 0) {
|
||||
typedText = typedTextCompletion[typedTextCompletionIdx];
|
||||
}
|
||||
}
|
||||
else if (c == '\033') // ESC
|
||||
{
|
||||
typedText = "";
|
||||
textEnterMode = false;
|
||||
typedTextCompletion.clear();
|
||||
typedTextCompletionIdx = -1;
|
||||
}
|
||||
else if (c == '\n' || c == '\r')
|
||||
{
|
||||
if (typedText != "")
|
||||
{
|
||||
Selection sel = sim->findObjectFromPath(typedText);
|
||||
if (!sel.empty())
|
||||
if (!sel.empty())
|
||||
{
|
||||
addToHistory();
|
||||
sim->setSelection(sel);
|
||||
|
@ -911,6 +956,8 @@ void CelestiaCore::charEntered(char c)
|
|||
typedText = "";
|
||||
}
|
||||
textEnterMode = false;
|
||||
typedTextCompletion.clear();
|
||||
typedTextCompletionIdx = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2484,14 +2531,46 @@ void CelestiaCore::renderOverlay()
|
|||
if (textEnterMode)
|
||||
{
|
||||
overlay->setFont(titleFont);
|
||||
glPushMatrix();
|
||||
// glPushMatrix();
|
||||
glColor4f(0.7f, 0.7f, 1.0f, 0.2f);
|
||||
overlay->rect(0, 0, width, 70);
|
||||
glTranslatef(0, fontHeight * 3 + 5, 0);
|
||||
overlay->rect(0, 0, width, 100);
|
||||
glTranslatef(0, fontHeight * 3 + 35, 0);
|
||||
glColor4f(0.6f, 0.6f, 1.0f, 1);
|
||||
overlay->beginText();
|
||||
*overlay << "Target name: " << typedText;
|
||||
glPopMatrix();
|
||||
overlay->endText();
|
||||
overlay->setFont(font);
|
||||
if (typedTextCompletion.size() > 1)
|
||||
{
|
||||
int nb_cols = 4;
|
||||
int nb_lines = 3;
|
||||
int start;
|
||||
glTranslatef( 3, - font->getHeight() - 3, 0);
|
||||
std::vector<std::string>::const_iterator iter = typedTextCompletion.begin();
|
||||
if (typedTextCompletionIdx >= nb_cols * nb_lines)
|
||||
{
|
||||
start = (typedTextCompletionIdx / nb_lines + 1 - nb_cols) * nb_lines;
|
||||
iter += start;
|
||||
}
|
||||
for (int i=0; iter < typedTextCompletion.end() && i < nb_cols; i++)
|
||||
{
|
||||
glPushMatrix();
|
||||
overlay->beginText();
|
||||
for (int j = 0; iter < typedTextCompletion.end() && j < nb_lines; iter++, j++)
|
||||
{
|
||||
if (i * nb_lines + j == typedTextCompletionIdx - start)
|
||||
glColor4f(1.0f, 0.6f, 0.6f, 1);
|
||||
else
|
||||
glColor4f(0.6f, 0.6f, 1.0f, 1);
|
||||
*overlay << *iter << "\n";
|
||||
}
|
||||
overlay->endText();
|
||||
glPopMatrix();
|
||||
glTranslatef( (width/nb_cols), 0, 0);
|
||||
}
|
||||
}
|
||||
// glPopMatrix();
|
||||
// overlay->setFont(font);
|
||||
}
|
||||
|
||||
// Text messages
|
||||
|
|
|
@ -132,6 +132,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
Key_NumPad7 = 31,
|
||||
Key_NumPad8 = 32,
|
||||
Key_NumPad9 = 33,
|
||||
Key_BackTab = 127,
|
||||
KeyCount = 128,
|
||||
};
|
||||
|
||||
|
@ -279,6 +280,8 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
double messageStart;
|
||||
double messageDuration;
|
||||
std::string typedText;
|
||||
std::vector<std::string> typedTextCompletion;
|
||||
int typedTextCompletionIdx;
|
||||
bool textEnterMode;
|
||||
int hudDetail;
|
||||
bool wireframe;
|
||||
|
|
|
@ -363,9 +363,19 @@ void KdeGlWidget::keyPressEvent( QKeyEvent* e )
|
|||
switch (e->key())
|
||||
{
|
||||
case Key_Escape:
|
||||
if (inputMode)
|
||||
{
|
||||
for (unsigned int n=0; n<actionColl->count(); n++) {
|
||||
if (actionColl->action(n)->shortcut().seq(0).key(0).modFlags()==0)
|
||||
actionColl->action(n)->setEnabled(true);
|
||||
}
|
||||
inputMode = !inputMode;
|
||||
}
|
||||
appCore->charEntered('\033');
|
||||
break;
|
||||
|
||||
case Key_BackTab:
|
||||
appCore->charEntered(CelestiaCore::Key_BackTab);
|
||||
break;
|
||||
case Key_Q:
|
||||
if( e->state() == ControlButton )
|
||||
{
|
||||
|
@ -379,9 +389,9 @@ void KdeGlWidget::keyPressEvent( QKeyEvent* e )
|
|||
if ((e->text() != 0) && (e->text() != ""))
|
||||
{
|
||||
for (unsigned int i=0; i<e->text().length(); i++)
|
||||
{
|
||||
{
|
||||
char c = e->text().at(i).latin1();
|
||||
if (c == 0x0D) {
|
||||
if (c == 0x0D || c=='\033') {
|
||||
if (!inputMode) { // entering input mode
|
||||
for (unsigned int n=0; n<actionColl->count(); n++) {
|
||||
if (actionColl->action(n)->shortcut().count() > 0
|
||||
|
@ -396,7 +406,7 @@ void KdeGlWidget::keyPressEvent( QKeyEvent* e )
|
|||
}
|
||||
inputMode = !inputMode;
|
||||
}
|
||||
if (c >= 0x20 || c == 0x0D || c== 0x08) appCore->charEntered(c);
|
||||
if (c >= 0x20 || c == 0x0D || c== 0x08 || c=='\011') appCore->charEntered(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue