Completion patch

ver1_5_1
Christophe Teyssier 2003-05-31 10:55:44 +00:00
parent 1e5941ce43
commit 1de258c1fb
13 changed files with 266 additions and 14 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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
{

View File

@ -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,

View File

@ -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:

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}
}