Skip to content

Commit

Permalink
Client|UI|ProgressWidget: Defining a visual subrange for progress
Browse files Browse the repository at this point in the history
At the moment, this is used in a sequence of busy tasks.
  • Loading branch information
skyjake committed Aug 2, 2013
1 parent d31a267 commit cd20868
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
13 changes: 12 additions & 1 deletion doomsday/client/include/ui/widgets/progresswidget.h
Expand Up @@ -47,6 +47,8 @@ class ProgressWidget : public LabelWidget
ProgressWidget(de::String const &name = "");

Mode mode() const;
de::Rangei range() const;
bool isAnimating() const;

void setColor(de::DotPath const &styleId);
void setShadowColor(de::DotPath const &styleId);
Expand All @@ -59,7 +61,16 @@ class ProgressWidget : public LabelWidget
void setText(de::String const &text);

void setMode(Mode progressMode);
void setRange(de::Rangei const &range);

/**
* Sets the range of values that can be given in setProgress().
* Automatically switches the widget to Ranged mode.
*
* @param range Range of valid values for setProgress().
* @param visualRange Range to which @a range maps to (within 0...1).
*/
void setRange(de::Rangei const &range, de::Rangef const &visualRange = de::Rangef(0.f, 1.f));

void setProgress(int currentProgress, de::TimeDelta const &transitionSpan = 0.5);

// Events.
Expand Down
43 changes: 33 additions & 10 deletions doomsday/client/src/ui/widgets/progresswidget.cpp
Expand Up @@ -28,6 +28,7 @@ DENG2_PIMPL(ProgressWidget), public Lockable
{
Mode mode;
Rangei range;
Rangef visualRange;
Animation pos;
float angle;
Id gearTex;
Expand All @@ -38,6 +39,7 @@ DENG2_PIMPL(ProgressWidget), public Lockable
Instance(Public *i)
: Base(i),
mode(Indefinite),
visualRange(0, 1),
pos(0, Animation::Linear),
angle(0),
colorId("progress.light.wheel"),
Expand Down Expand Up @@ -76,11 +78,11 @@ ProgressWidget::ProgressWidget(String const &name) : d(new Instance(this))

// Set up the static progress ring image.
setImage(style().images().image("progress.wheel"));
setImageFit(ui::FitToHeight | ui::OriginalAspectRatio);
setImageScale(.18f);
setImageFit(ui::FitToSize | ui::OriginalAspectRatio);
setImageScale(.6f);

setAlignment(ui::AlignCenter, AlignOnlyByImage);
setText("Loading Blah Blah...");
//setText("Loading Blah Blah...");
setTextAlignment(ui::AlignRight);
}

Expand All @@ -90,6 +92,18 @@ ProgressWidget::Mode ProgressWidget::mode() const
return d->mode;
}

Rangei ProgressWidget::range() const
{
DENG2_GUARD(d);
return d->range;
}

bool ProgressWidget::isAnimating() const
{
DENG2_GUARD(d);
return !d->pos.done();
}

void ProgressWidget::setColor(DotPath const &styleId)
{
d->colorId = styleId;
Expand All @@ -114,10 +128,12 @@ void ProgressWidget::setMode(ProgressWidget::Mode progressMode)
d->mode = progressMode;
}

void ProgressWidget::setRange(Rangei const &range)
void ProgressWidget::setRange(Rangei const &range, Rangef const &visualRange)
{
DENG2_GUARD(d);
d->range = range;
d->visualRange = visualRange;
setMode(Ranged);
}

void ProgressWidget::setProgress(int currentProgress, TimeDelta const &transitionSpan)
Expand Down Expand Up @@ -167,24 +183,31 @@ void ProgressWidget::glMakeGeometry(DefaultVertexBuf::Builder &verts)
contentLayout(layout);

// There is a shadow behind the wheel.
float innerShadowRadius = layout.image.width() / 2;
float outerShadowRadius = layout.image.width() * 2;
verts.makeRing(layout.image.middle(), innerShadowRadius, 0, 30,
float shadowRadius = layout.image.width() / 2;
float ringRadius = layout.image.width() / 4;
float ringThick = layout.image.width() / 10;
verts.makeRing(layout.image.middle(), shadowRadius + ringRadius, shadowRadius + ringThick, 30,
style().colors().colorf(d->shadowColorId),
root().atlas().imageRectf(root().borderGlow()), 0);
verts.makeRing(layout.image.middle(), shadowRadius - ringThick, shadowRadius + ringThick, 30,
style().colors().colorf(d->shadowColorId),
root().atlas().imageRectf(root().borderGlow()).middle());
verts.makeRing(layout.image.middle(), outerShadowRadius, innerShadowRadius, 30,
verts.makeRing(layout.image.middle(), shadowRadius - ringRadius, shadowRadius - ringThick, 30,
style().colors().colorf(d->shadowColorId),
root().atlas().imageRectf(root().borderGlow()), 0);

LabelWidget::glMakeGeometry(verts);

// Draw the rotating indicator on the label's image.
Rectanglef const tc = d->atlas().imageRectf(d->gearTex);
float pos = 1;
float pos = 1;
if(d->mode != Indefinite)
{
pos = de::clamp(0.f, d->pos.value(), 1.f);
}
}

// Map to the visual range.
pos = d->visualRange.start + pos * d->visualRange.size();

int const edgeCount = de::max(1, int(pos * 30));
float const radius = layout.image.width() / 2;
Expand Down

0 comments on commit cd20868

Please sign in to comment.