From 030ad20cc6673096bbb4b1517143f28ff6eae027 Mon Sep 17 00:00:00 2001 From: skyjake Date: Sun, 19 May 2013 16:17:13 +0300 Subject: [PATCH] Client|Widgets: Working on the LineEditWidget Drawing the wrapped lines and a blinking cursor. Todo: Fix cursor position issues. Todo for later: Apply a visual style. --- .../client/data/defaultstyle.pack/colors.dei | 4 ++ .../client/data/defaultstyle.pack/fonts.dei | 2 +- doomsday/client/src/ui/clientwindow.cpp | 5 +- .../client/src/ui/widgets/lineeditwidget.cpp | 69 ++++++++++++++----- 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/doomsday/client/data/defaultstyle.pack/colors.dei b/doomsday/client/data/defaultstyle.pack/colors.dei index aa45ace910..d86d614627 100644 --- a/doomsday/client/data/defaultstyle.pack/colors.dei +++ b/doomsday/client/data/defaultstyle.pack/colors.dei @@ -2,3 +2,7 @@ color text { rgb <1.0, 1.0, 1.0> } color background { rgba <0.0, 0.0, 0.0, 0.5> } + +group editor { + color cursor { rgb <1.0, 0.8, 0.4, 0.7> } +} diff --git a/doomsday/client/data/defaultstyle.pack/fonts.dei b/doomsday/client/data/defaultstyle.pack/fonts.dei index 1318ef2df4..d65d2e21d8 100644 --- a/doomsday/client/data/defaultstyle.pack/fonts.dei +++ b/doomsday/client/data/defaultstyle.pack/fonts.dei @@ -18,7 +18,7 @@ group { font default { family: Lucida Grande - size: 16pt + size: 24pt weight: normal style: normal } diff --git a/doomsday/client/src/ui/clientwindow.cpp b/doomsday/client/src/ui/clientwindow.cpp index 25716f7023..d7f19c7b22 100644 --- a/doomsday/client/src/ui/clientwindow.cpp +++ b/doomsday/client/src/ui/clientwindow.cpp @@ -88,13 +88,16 @@ DENG2_PIMPL(ClientWindow), root.add(taskBar);*/ LineEditWidget *editTest = new LineEditWidget; - editTest->setText("Hello World"); + editTest->setText("Hello World. Lorum ipsum asd asdlkj iaj sdoiajs doias daklsd s. lasdj askldj."); + editTest->setCursor(0); editTest->rule() .setInput(Rule::Left, root.viewLeft()) .setInput(Rule::Bottom, root.viewBottom()) .setInput(Rule::Width, root.viewWidth()); root.add(editTest); + root.setFocus(editTest); + // Initially the widget is disabled. It will be enabled when the window // is visible and ready to be drawn. legacy->disable(); diff --git a/doomsday/client/src/ui/widgets/lineeditwidget.cpp b/doomsday/client/src/ui/widgets/lineeditwidget.cpp index 69dc26fb40..0592aa3a82 100644 --- a/doomsday/client/src/ui/widgets/lineeditwidget.cpp +++ b/doomsday/client/src/ui/widgets/lineeditwidget.cpp @@ -29,6 +29,8 @@ using namespace de; static TimeDelta const ANIM_SPAN = .5f; +static duint const ID_BUF_TEXT = 1; +static duint const ID_BUF_CURSOR = 2; DENG2_PIMPL(LineEditWidget), DENG2_OBSERVES(Atlas, Reposition) @@ -41,11 +43,11 @@ DENG2_OBSERVES(Atlas, Reposition) // Style. Font const *font; int margin; + Time blinkTime; // GL objects. bool needGeometry; GLTextComposer composer; - VertexBuf *buf; Id bgTex; Drawable drawable; GLUniform uMvpMatrix; @@ -58,12 +60,12 @@ DENG2_OBSERVES(Atlas, Reposition) font(0), margin(0), needGeometry(false), - buf(0), uMvpMatrix("uMvpMatrix", GLUniform::Mat4), uColor ("uColor", GLUniform::Vec4), uTex ("uTex", GLUniform::Sampler2D) { height = new ScalarRule(0); + updateStyle(); uColor = Vector4f(1, 1, 1, 1); @@ -88,6 +90,8 @@ DENG2_OBSERVES(Atlas, Reposition) wraps.setFont(*font); wraps.clear(); + composer.setWrapping(wraps); + contentChanged(); } @@ -110,23 +114,28 @@ DENG2_OBSERVES(Atlas, Reposition) void glInit() { composer.setAtlas(atlas()); - composer.setText(self.text(), wraps); + composer.setText(self.text()); // We'll be using the shared atlas. uTex = atlas(); // Temporary background texture for development... - QImage bg(QSize(2, 2), QImage::Format_ARGB32); - bg.fill(QColor(0, 0, 255, 255).rgba()); + QImage bg(QSize(1, 1), QImage::Format_ARGB32); + bg.fill(QColor(255, 255, 255, 255).rgba()); bgTex = atlas().alloc(bg); - drawable.addBuffer(buf = new VertexBuf); + drawable.addBuffer(ID_BUF_TEXT, new VertexBuf); + drawable.addBufferWithNewProgram(ID_BUF_CURSOR, new VertexBuf, "cursor"); self.root().shaders().build(drawable.program(), "generic.tex_color") << uMvpMatrix //<< uColor << uTex; + self.root().shaders().build(drawable.program("cursor"), "generic.color") + << uMvpMatrix + << uColor; + updateProjection(); } @@ -138,7 +147,10 @@ DENG2_OBSERVES(Atlas, Reposition) void updateGeometry() { - composer.update(); + if(composer.update()) + { + needGeometry = true; + } Rectanglei pos; if(!self.checkPlace(pos) && !needGeometry) @@ -152,8 +164,7 @@ DENG2_OBSERVES(Atlas, Reposition) VertexBuf::Vertices verts; VertexBuf::Type v; - v.rgba = Vector4f(1, 1, 1, 1); //bgColor; - + v.rgba = bgColor; v.texCoord = atlas().imageRectf(bgTex).middle(); v.pos = pos.topLeft; verts << v; @@ -162,17 +173,35 @@ DENG2_OBSERVES(Atlas, Reposition) v.pos = pos.bottomRight; verts << v; // Text lines. - composer.makeVertices(verts, pos.shrunk(margin), - GLTextComposer::AlignCenter, + Rectanglei const contentRect = pos.shrunk(margin); + composer.makeVertices(verts, contentRect, + GLTextComposer::AlignLeft, GLTextComposer::AlignLeft); - buf->setVertices(gl::TriangleStrip, verts, gl::Static); + drawable.buffer(ID_BUF_TEXT) + .setVertices(gl::TriangleStrip, verts, gl::Static); + + // Cursor. + verts.clear(); + v.rgba = Vector4f(1, 1, 1, 1); + v.texCoord = atlas().imageRectf(bgTex).middle(); + + Vector2i const cursorPos = self.lineCursorPos(); + Vector2f const cp = wraps.charTopLeftInPixels(cursorPos.y, cursorPos.x) + + contentRect.topLeft; + + v.pos = cp; verts << v; + v.pos = cp + Vector2f(2, 0); verts << v; + v.pos = cp + Vector2f(0, font->height().value()); verts << v; + v.pos = cp + Vector2f(2, font->height().value()); verts << v; + + drawable.buffer(ID_BUF_CURSOR) + .setVertices(gl::TriangleStrip, verts, gl::Static); } void contentChanged() { - needGeometry = true; - composer.setText(self.text(), wraps); + composer.setText(self.text()); } void atlasContentRepositioned(Atlas &) @@ -217,6 +246,15 @@ void LineEditWidget::update() void LineEditWidget::draw() { + // Blink the cursor. + Vector4f col = style().colors().colorf("editor.cursor"); + col.w *= (int(d->blinkTime.since() * 2) & 1? .25f : 1.f); + if(!hasFocus()) + { + col.w = 0; + } + d->uColor = col; + d->updateGeometry(); d->drawable.draw(); } @@ -253,13 +291,12 @@ void LineEditWidget::numberOfLinesChanged(int /*lineCount*/) { // Changes in the widget's height are animated. d->height->set(d->calculateHeight(), ANIM_SPAN); - - d->contentChanged(); } void LineEditWidget::cursorMoved() { d->needGeometry = true; + d->blinkTime = Time(); } void LineEditWidget::contentChanged()