More UI fixes
This commit is contained in:
parent
27db010dde
commit
2b3e1355ad
7 changed files with 106 additions and 23 deletions
|
@ -86,16 +86,7 @@ public:
|
|||
free(buffer_);
|
||||
}
|
||||
|
||||
void parse() {
|
||||
char *error_pos;
|
||||
char *error_desc;
|
||||
int error_line;
|
||||
root_ = json_parse((char *)buffer_, &error_pos, &error_desc, &error_line, &alloc_);
|
||||
if (!root_) {
|
||||
ELOG("Error at (%i): %s\n%s\n\n", error_line, error_desc, error_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ok() const { return root_ != 0; }
|
||||
|
||||
json_value *root() { return root_; }
|
||||
|
@ -106,6 +97,18 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool parse() {
|
||||
char *error_pos;
|
||||
char *error_desc;
|
||||
int error_line;
|
||||
root_ = json_parse((char *)buffer_, &error_pos, &error_desc, &error_line, &alloc_);
|
||||
if (!root_) {
|
||||
ELOG("Error at (%i): %s\n%s\n\n", error_line, error_desc, error_pos);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char *buffer_;
|
||||
block_allocator alloc_;
|
||||
json_value *root_;
|
||||
|
|
|
@ -80,6 +80,8 @@
|
|||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\libpng;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -97,6 +99,8 @@
|
|||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\libpng;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -118,6 +122,7 @@
|
|||
<AdditionalIncludeDirectories>..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\libpng;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -141,6 +146,7 @@
|
|||
<AdditionalIncludeDirectories>..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\native\ext\glew;..\SDL\include;..\libpng;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
|
|
@ -119,12 +119,20 @@ int Client::GET(const char *resource, Buffer *output) {
|
|||
if (!output->ReadAll(sock()))
|
||||
return -1;
|
||||
|
||||
// Grab the first header line that contains the http code.
|
||||
|
||||
// Skip the header. TODO: read HTTP code and file size so we can make progress bars.
|
||||
|
||||
std::string firstline;
|
||||
CHECK_GT(output->TakeLineCRLF(&firstline), 0);
|
||||
int code = atoi(&firstline[9]);
|
||||
|
||||
|
||||
while (output->SkipLineCRLF() > 0)
|
||||
;
|
||||
|
||||
// output now contains the rest of the reply.
|
||||
return 200;
|
||||
return code;
|
||||
}
|
||||
|
||||
int Client::POST(const char *resource, const std::string &data, const std::string &mime, Buffer *output) {
|
||||
|
@ -172,7 +180,7 @@ int Client::POST(const char *resource, const std::string &data, Buffer *output)
|
|||
}
|
||||
|
||||
Download::Download(const std::string &url, const std::string &outfile)
|
||||
: url_(url), outfile_(outfile), progress_(0.0f), failed_(false) {
|
||||
: url_(url), outfile_(outfile), progress_(0.0f), failed_(false), resultCode_(0) {
|
||||
|
||||
std::thread th(std::bind(&Download::Do, this));
|
||||
th.detach();
|
||||
|
@ -197,16 +205,18 @@ void Download::Do() {
|
|||
return;
|
||||
}
|
||||
client.Connect();
|
||||
if (client.GET(fileUrl.Resource().c_str(), &buffer_)) {
|
||||
int resultCode = client.GET(fileUrl.Resource().c_str(), &buffer_);
|
||||
if (resultCode == 200) {
|
||||
progress_ = 1.0f;
|
||||
ILOG("Completed downloading %s to %s", url_.c_str(), outfile_.c_str());
|
||||
if (!outfile_.empty() && !buffer_.FlushToFile(outfile_.c_str())) {
|
||||
ELOG("Failed writing download to %s", outfile_.c_str());
|
||||
}
|
||||
} else {
|
||||
ELOG("Error downloading %s to %s", url_.c_str(), outfile_.c_str());
|
||||
progress_ = 1.0f;
|
||||
ELOG("Error downloading %s to %s: %i", url_.c_str(), outfile_.c_str(), resultCode);
|
||||
}
|
||||
|
||||
resultCode_ = resultCode;
|
||||
net::Shutdown();
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ public:
|
|||
|
||||
bool Failed() const { return failed_; }
|
||||
|
||||
int ResultCode() const { return resultCode_; }
|
||||
|
||||
std::string url() const { return url_; }
|
||||
std::string outfile() const { return outfile_; }
|
||||
|
||||
|
@ -94,9 +96,12 @@ private:
|
|||
Buffer buffer_;
|
||||
std::string url_;
|
||||
std::string outfile_;
|
||||
int resultCode_;
|
||||
bool failed_;
|
||||
};
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
class Downloader {
|
||||
public:
|
||||
std::shared_ptr<Download> StartDownload(const std::string &url, const std::string &outfile);
|
||||
|
|
21
ui/view.cpp
21
ui/view.cpp
|
@ -127,8 +127,15 @@ void Clickable::Touch(const TouchInput &input) {
|
|||
}
|
||||
|
||||
void Clickable::Update(const InputState &input_state) {
|
||||
OnClick.Update();
|
||||
if (!HasFocus())
|
||||
return;
|
||||
|
||||
if (!enabled_) {
|
||||
down_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_state.pad_buttons_down & PAD_BUTTON_A) {
|
||||
down_ = true;
|
||||
} else if (input_state.pad_buttons_up & PAD_BUTTON_A) {
|
||||
|
@ -199,7 +206,8 @@ void Button::Draw(UIContext &dc) {
|
|||
Style style = dc.theme->buttonStyle;
|
||||
if (HasFocus()) style = dc.theme->buttonFocusedStyle;
|
||||
if (down_) style = dc.theme->buttonDownStyle;
|
||||
|
||||
if (!enabled_) style = dc.theme->buttonDisabledStyle;
|
||||
|
||||
dc.Draw()->DrawImage4Grid(dc.theme->buttonImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y2(), style.bgColor);
|
||||
dc.Draw()->DrawText(dc.theme->uiFont, text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER);
|
||||
}
|
||||
|
@ -228,6 +236,17 @@ void TextView::Draw(UIContext &dc) {
|
|||
dc.Draw()->SetFontScale(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void ProgressBar::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
|
||||
dc.Draw()->MeasureText(dc.theme->uiFont, " 100% ", &w, &h);
|
||||
}
|
||||
|
||||
void ProgressBar::Draw(UIContext &dc) {
|
||||
char temp[32];
|
||||
sprintf(temp, "%i%%", (int)(progress_ * 100.0f));
|
||||
dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x + bounds_.w * progress_, bounds_.h);
|
||||
dc.Draw()->DrawTextRect(dc.theme->uiFont, temp, bounds_.x, bounds_.y, bounds_.w, bounds_.h, 0xFFFFFFFF, ALIGN_CENTER);
|
||||
}
|
||||
|
||||
void TriggerButton::Touch(const TouchInput &input) {
|
||||
if (input.flags & TOUCH_DOWN) {
|
||||
if (bounds_.Contains(input.x, input.y)) {
|
||||
|
|
32
ui/view.h
32
ui/view.h
|
@ -43,6 +43,12 @@ enum DrawableType {
|
|||
DRAW_4GRID,
|
||||
};
|
||||
|
||||
enum Visibility {
|
||||
V_VISIBLE,
|
||||
V_INVISIBLE, // Keeps position, not drawn or interacted with
|
||||
V_GONE, // Does not participate in layout
|
||||
};
|
||||
|
||||
struct Drawable {
|
||||
Drawable() : type(DRAW_NOTHING) {}
|
||||
|
||||
|
@ -71,6 +77,7 @@ struct Theme {
|
|||
Style buttonStyle;
|
||||
Style buttonFocusedStyle;
|
||||
Style buttonDownStyle;
|
||||
Style buttonDisabledStyle;
|
||||
|
||||
Style itemDownStyle;
|
||||
Style itemFocusedStyle;
|
||||
|
@ -207,7 +214,7 @@ View *GetFocusedView();
|
|||
|
||||
class View {
|
||||
public:
|
||||
View(LayoutParams *layoutParams = 0) : layoutParams_(layoutParams), enabled_(true) {
|
||||
View(LayoutParams *layoutParams = 0) : layoutParams_(layoutParams), enabled_(true), visibility_(V_VISIBLE) {
|
||||
if (!layoutParams)
|
||||
layoutParams_.reset(new LayoutParams());
|
||||
}
|
||||
|
@ -255,13 +262,17 @@ public:
|
|||
}
|
||||
|
||||
void SetEnabled(bool enabled) { enabled_ = enabled; }
|
||||
bool Enabled() const { return enabled_; }
|
||||
bool GetEnabled() const { return enabled_; }
|
||||
|
||||
void SetVisibility(Visibility visibility) { visibility_ = visibility; }
|
||||
Visibility GetVisibility() const { return visibility_; }
|
||||
|
||||
protected:
|
||||
// Inputs to layout
|
||||
scoped_ptr<LayoutParams> layoutParams_;
|
||||
|
||||
bool enabled_;
|
||||
Visibility visibility_;
|
||||
|
||||
// Results of measure pass. Set these in Measure.
|
||||
float measuredWidth_;
|
||||
|
@ -447,7 +458,7 @@ public:
|
|||
|
||||
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
|
||||
virtual void Draw(UIContext &dc);
|
||||
|
||||
virtual void SetText(const std::string &text) { text_ = text; }
|
||||
private:
|
||||
int font_;
|
||||
std::string text_;
|
||||
|
@ -472,6 +483,21 @@ private:
|
|||
ImageSizeMode sizeMode_;
|
||||
};
|
||||
|
||||
class ProgressBar : public InertView {
|
||||
public:
|
||||
ProgressBar(LayoutParams *layoutParams = 0)
|
||||
: InertView(layoutParams), progress_(0.0) {}
|
||||
|
||||
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
|
||||
virtual void Draw(UIContext &dc);
|
||||
|
||||
void SetProgress(float progress) { progress_ = progress; }
|
||||
float GetProgress() const { return progress_; }
|
||||
|
||||
private:
|
||||
float progress_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// This tab strip is a little special.
|
||||
|
|
|
@ -32,21 +32,24 @@ ViewGroup::~ViewGroup() {
|
|||
void ViewGroup::Touch(const TouchInput &input) {
|
||||
for (auto iter = views_.begin(); iter != views_.end(); ++iter) {
|
||||
// TODO: If there is a transformation active, transform input coordinates accordingly.
|
||||
(*iter)->Touch(input);
|
||||
if ((*iter)->GetVisibility() == V_VISIBLE)
|
||||
(*iter)->Touch(input);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewGroup::Draw(UIContext &dc) {
|
||||
for (auto iter = views_.begin(); iter != views_.end(); ++iter) {
|
||||
// TODO: If there is a transformation active, transform input coordinates accordingly.
|
||||
(*iter)->Draw(dc);
|
||||
if ((*iter)->GetVisibility() == V_VISIBLE)
|
||||
(*iter)->Draw(dc);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewGroup::Update(const InputState &input_state) {
|
||||
for (auto iter = views_.begin(); iter != views_.end(); ++iter) {
|
||||
// TODO: If there is a transformation active, transform input coordinates accordingly.
|
||||
(*iter)->Update(input_state);
|
||||
if ((*iter)->GetVisibility() != V_GONE)
|
||||
(*iter)->Update(input_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +77,8 @@ float GetDirectionScore(View *origin, View *destination, FocusDirection directio
|
|||
// Skip labels and things like that.
|
||||
if (!destination->CanBeFocused())
|
||||
return 0.0f;
|
||||
if (destination->GetEnabled() == false)
|
||||
return 0.0f;
|
||||
|
||||
float dx = destination->GetBounds().centerX() - origin->GetBounds().centerX();
|
||||
float dy = destination->GetBounds().centerY() - origin->GetBounds().centerY();
|
||||
|
@ -203,7 +208,13 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v
|
|||
float weightSum = 0.0f;
|
||||
float weightZeroSum = 0.0f;
|
||||
|
||||
int numVisible = 0;
|
||||
|
||||
for (size_t i = 0; i < views_.size(); i++) {
|
||||
if (views_[i]->GetVisibility() == V_GONE)
|
||||
continue;
|
||||
numVisible++;
|
||||
|
||||
const LayoutParams *layoutParams = views_[i]->GetLayoutParams();
|
||||
const LinearLayoutParams *linLayoutParams = dynamic_cast<const LinearLayoutParams *>(layoutParams);
|
||||
Margins margins = defaultMargins_;
|
||||
|
@ -240,7 +251,7 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v
|
|||
}
|
||||
}
|
||||
|
||||
weightZeroSum += spacing_ * (views_.size() - 1);
|
||||
weightZeroSum += spacing_ * (numVisible - 1);
|
||||
|
||||
// Awright, got the sum. Let's take the remaining space after the fixed-size views,
|
||||
// and distribute among the weighted ones.
|
||||
|
@ -293,6 +304,9 @@ void LinearLayout::Layout() {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < views_.size(); i++) {
|
||||
if (views_[i]->GetVisibility() == V_GONE)
|
||||
continue;
|
||||
|
||||
const LayoutParams *layoutParams = views_[i]->GetLayoutParams();
|
||||
const LinearLayoutParams *linLayoutParams = dynamic_cast<const LinearLayoutParams *>(layoutParams);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue