Skip to content

Commit

Permalink
Client|UI|Default Style: Console command line autocompletion popup
Browse files Browse the repository at this point in the history
A DocumentWidget is used to display all the possible completions in
a popup.

Todo: Make it a background task to wrap the document text initially,
as it may take a while with longer lists.
  • Loading branch information
skyjake committed Jul 31, 2013
1 parent 77c6605 commit f8c48a8
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 13 deletions.
12 changes: 12 additions & 0 deletions doomsday/client/data/defaultstyle.pack/colors.dei
Expand Up @@ -21,6 +21,10 @@ group label {
group editor {
color cursor { rgb $= gui.colorAlpha(accent.rgb, 0.7) }
color hint { rgb $= gui.colorMix(text.rgb, accent.rgb, 0.5) }

group completion {
color background { rgb <1.0, 1.0, 1.0> }
}
}

group log {
Expand All @@ -30,3 +34,11 @@ group log {
color accent { rgb $= accent.rgb }
color dimaccent { rgb <0.85, 0.68, 0.34> }
}

group document {
color normal { rgb $= gui.colorMix(inverted.text.rgb, [1, 1, 1], 0.2) }
color highlight { rgb $= inverted.text.rgb }
color dimmed { rgb <0.5, 0.5, 0.5> }
color accent { rgb $= accent.rgb }
color dimaccent { rgb <0.85, 0.68, 0.34> }
}
14 changes: 8 additions & 6 deletions doomsday/client/src/ui/widgets/consolecommandwidget.cpp
Expand Up @@ -45,15 +45,14 @@ public IGameChangeObserver

// Popup for autocompletions.
completions = new DocumentWidget;
completions->setText("Hello World!");
completions->setMaximumLineWidth(640);
completions->rule().setInput(Rule::Height,
OperatorRule::minimum(Const(400),
completions->contentRule().height() + 2 *
completions->margin()));

popup = new PopupWidget;
//popup->set(Background(self.style().colors().colorf("inverted.background")));
popup->set(Background(self.style().colors().colorf("editor.completion.background")));
popup->setContent(completions);
self.add(popup);
}
Expand Down Expand Up @@ -95,6 +94,10 @@ void ConsoleCommandWidget::focusGained()
void ConsoleCommandWidget::focusLost()
{
LineEditWidget::focusLost();

// Get rid of the autocompletion popup.
d->popup->close();

emit lostFocus();
}

Expand Down Expand Up @@ -157,12 +160,11 @@ bool ConsoleCommandWidget::handleEvent(Event const &event)
void ConsoleCommandWidget::autoCompletionBegan()
{
// Prepare a list of completions.
//qDebug() << Con_AnnotatedConsoleTerms(suggestedCompletions());

//d->completions->setText(Con_AnnotatedConsoleTerms(suggestedCompletions()));
d->completions->setText(Con_AnnotatedConsoleTerms(suggestedCompletions()));
d->completions->scrollToTop(0);

// Note: this is a fixed position, so it will not be updated if the view is resized.
d->popup->setAnchor(Vector2i(cursorRect().middle().x, rule().top().valuei()));

d->popup->open();
}

Expand Down
117 changes: 110 additions & 7 deletions doomsday/client/src/ui/widgets/documentwidget.cpp
Expand Up @@ -29,15 +29,26 @@ static int const ID_BACKGROUND = 1; // does not scroll
static int const ID_TEXT = 2; // scrolls

DENG2_PIMPL(DocumentWidget),
DENG2_OBSERVES(Atlas, Reposition)
DENG2_OBSERVES(Atlas, Reposition),
public Font::RichFormat::IStyle
{
typedef DefaultVertexBuf VertexBuf;

// Style.
ColorBank::Color normalColor;
ColorBank::Color highlightColor;
ColorBank::Color dimmedColor;
ColorBank::Color accentColor;
ColorBank::Color dimAccentColor;

// State.
ui::SizePolicy widthPolicy;
int maxLineWidth;
int oldScrollY;
String styledText;
String text;

// GL objects.
Font::RichFormat format;
FontLineWrapping wraps;
GLTextComposer composer;
Expand All @@ -53,6 +64,7 @@ DENG2_OBSERVES(Atlas, Reposition)
widthPolicy(ui::Expand),
maxLineWidth(1000),
oldScrollY(0),
format(*this),
uMvpMatrix ("uMvpMatrix", GLUniform::Mat4),
uScrollMvpMatrix("uMvpMatrix", GLUniform::Mat4),
uColor ("uColor", GLUniform::Vec4)
Expand All @@ -63,12 +75,102 @@ DENG2_OBSERVES(Atlas, Reposition)

void updateStyle()
{
Style const &st = self.style();

normalColor = st.colors().color("document.normal");
highlightColor = st.colors().color("document.highlight");
dimmedColor = st.colors().color("document.dimmed");
accentColor = st.colors().color("document.accent");
dimAccentColor = st.colors().color("document.dimaccent");

wraps.setFont(self.font());
wraps.clear();
composer.forceUpdate();
self.requestGeometry();
}

Font::RichFormat::IStyle::Color richStyleColor(int index) const
{
switch(index)
{
default:
case Font::RichFormat::NormalColor:
return normalColor;

case Font::RichFormat::HighlightColor:
return highlightColor;

case Font::RichFormat::DimmedColor:
return dimmedColor;

case Font::RichFormat::AccentColor:
return accentColor;

case Font::RichFormat::DimAccentColor:
return dimAccentColor;
}
}

void richStyleFormat(int contentStyle,
float &sizeFactor,
Font::RichFormat::Weight &fontWeight,
Font::RichFormat::Style &fontStyle,
int &colorIndex) const
{
switch(contentStyle)
{
default:
case Font::RichFormat::NormalStyle:
sizeFactor = 1.f;
fontWeight = Font::RichFormat::OriginalWeight;
fontStyle = Font::RichFormat::OriginalStyle;
colorIndex = Font::RichFormat::OriginalColor;
break;

case Font::RichFormat::MajorStyle:
sizeFactor = 1.f;
fontWeight = Font::RichFormat::Bold;
fontStyle = Font::RichFormat::Regular;
colorIndex = Font::RichFormat::HighlightColor;
break;

case Font::RichFormat::MinorStyle:
sizeFactor = .8f;
fontWeight = Font::RichFormat::Normal;
fontStyle = Font::RichFormat::Regular;
colorIndex = Font::RichFormat::DimmedColor;
break;

case Font::RichFormat::MetaStyle:
sizeFactor = .9f;
fontWeight = Font::RichFormat::Light;
fontStyle = Font::RichFormat::Italic;
colorIndex = Font::RichFormat::AccentColor;
break;

case Font::RichFormat::MajorMetaStyle:
sizeFactor = .9f;
fontWeight = Font::RichFormat::Bold;
fontStyle = Font::RichFormat::Italic;
colorIndex = Font::RichFormat::AccentColor;
break;

case Font::RichFormat::MinorMetaStyle:
sizeFactor = .8f;
fontWeight = Font::RichFormat::Light;
fontStyle = Font::RichFormat::Italic;
colorIndex = Font::RichFormat::DimAccentColor;
break;

case Font::RichFormat::AuxMetaStyle:
sizeFactor = .8f;
fontWeight = Font::RichFormat::Light;
fontStyle = Font::RichFormat::OriginalStyle;
colorIndex = Font::RichFormat::DimmedColor;
break;
}
}

void glInit()
{
self.root().atlas().audienceForReposition += this;
Expand Down Expand Up @@ -128,7 +230,6 @@ DENG2_OBSERVES(Atlas, Reposition)
if(wraps.isEmpty() || wraps.maximumWidth() != maxLineWidth)
{
wraps.wrapTextToWidth(text, format, maxLineWidth);
qDebug() << text << "wrapped width" << wraps.width();
self.setContentWidth(wraps.width());
self.setContentHeight(wraps.totalHeightInPixels());
}
Expand All @@ -145,7 +246,7 @@ DENG2_OBSERVES(Atlas, Reposition)

// Determine visible range of lines.
Font const &font = self.font();
int contentHeight = self.rule().height().valuei() - 2 * margin;
int contentHeight = self.contentHeight();
int const extraLines = 1;
int numVisLines = contentHeight / font.lineSpacing().valuei() + 2 * extraLines;
int firstVisLine = scrollY / font.lineSpacing().valuei() - extraLines + 1;
Expand All @@ -164,14 +265,12 @@ DENG2_OBSERVES(Atlas, Reposition)
VertexBuf::Builder verts;
composer.makeVertices(verts, Vector2i(0, 0), ui::AlignLeft);
drawable.buffer<VertexBuf>(ID_TEXT).setVertices(gl::TriangleStrip, verts, gl::Static);

qDebug() << "text vertices" << verts.size();
}
}

uScrollMvpMatrix = self.root().projMatrix2D() *
Matrix4f::translate(Vector2f(self.contentRule().left().valuei(),
self.contentRule().top().valuei() - scrollY));
self.contentRule().top().valuei()));

// Background and scroll indicator.
VertexBuf::Builder verts;
Expand All @@ -181,6 +280,10 @@ DENG2_OBSERVES(Atlas, Reposition)

uMvpMatrix = self.root().projMatrix2D();

DENG2_ASSERT(drawable.buffer(ID_BACKGROUND).isReady());
DENG2_ASSERT(drawable.buffer(ID_TEXT).isReady());
DENG2_ASSERT(drawable.isReady());

// Geometry is now up to date.
self.requestGeometry(false);
}
Expand Down Expand Up @@ -209,7 +312,7 @@ void DocumentWidget::setText(String const &styledText)
if(styledText != d->styledText)
{
d->wraps.clear();
d->composer.forceUpdate();
d->composer.release();

d->styledText = styledText;
d->text = d->format.initFromStyledText(styledText);
Expand Down

0 comments on commit f8c48a8

Please sign in to comment.