Add utility to get a list of Windows disk drives. Rework UI events.

This commit is contained in:
Henrik Rydgard 2013-06-27 16:20:18 +02:00
parent 1777d9e835
commit f1ccdc11b5
5 changed files with 90 additions and 26 deletions

View File

@ -251,6 +251,10 @@ size_t getFilesInDir(const char *directory, std::vector<FileInfo> *files, const
struct dirent_large diren;
struct dirent *result = NULL;
//std::string directoryWithSlash = directory;
//if (directoryWithSlash.back() != '/')
// directoryWithSlash += "/";
DIR *dirp = opendir(directory);
if (!dirp)
return 0;
@ -358,3 +362,29 @@ void mkDir(const std::string &path)
mkdir(path.c_str(), 0777);
#endif
}
#ifdef _WIN32
// Returns a vector with the device names
std::vector<std::string> getWindowsDrives()
{
std::vector<std::string> drives;
const DWORD buffsize = GetLogicalDriveStrings(0, NULL);
std::vector<TCHAR> buff(buffsize);
if (GetLogicalDriveStrings(buffsize, buff.data()) == buffsize - 1)
{
auto drive = buff.data();
while (*drive)
{
std::string str(drive);
str.pop_back(); // we don't want the final backslash
str += "/";
drives.push_back(str);
// advance to next drive
while (*drive++) {}
}
}
return drives;
}
#endif

View File

@ -43,3 +43,7 @@ void deleteDir(const char *file);
bool exists(const std::string &filename);
void mkDir(const std::string &path);
std::string getDir(const std::string &path);
#ifdef _WIN32
std::vector<std::string> getWindowsDrives();
#endif

View File

@ -1,4 +1,5 @@
#include "base/display.h"
#include <queue>
#include "base/display.h"
#include "base/mutex.h"
#include "input/input_state.h"
#include "gfx_es2/draw_buffer.h"
@ -13,8 +14,39 @@ namespace UI {
static View *focusedView;
static bool focusMovementEnabled;
static recursive_mutex mutex_;
const float ITEM_HEIGHT = 64.f;
struct DispatchQueueItem {
Event *e;
EventParams params;
};
std::queue<DispatchQueueItem> g_dispatchQueue;
void EventTriggered(Event *e, EventParams params) {
lock_guard guard(mutex_);
DispatchQueueItem item;
item.e = e;
item.params = params;
g_dispatchQueue.push(item);
}
void DispatchEvents() {
lock_guard guard(mutex_);
while (!g_dispatchQueue.empty()) {
DispatchQueueItem item = g_dispatchQueue.back();
g_dispatchQueue.pop();
item.e->Dispatch(item.params);
}
}
View *GetFocusedView() {
return focusedView;
}
@ -58,21 +90,16 @@ void Event::Add(std::function<EventReturn(EventParams&)> func) {
// Call this from input thread or whatever, it doesn't matter
void Event::Trigger(EventParams &e) {
lock_guard guard(mutex_);
if (!triggered_) {
triggered_ = true;
eventParams_ = e;
}
EventTriggered(this, e);
}
// Call this from UI thread
void Event::Update() {
lock_guard guard(mutex_);
if (triggered_) {
for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) {
(iter->func)(eventParams_);
void Event::Dispatch(EventParams &e) {
for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) {
if ((iter->func)(e) == UI::EVENT_DONE) {
// Event is handled, stop looping immediately. This event might even have gotten deleted.
return;
}
triggered_ = false;
}
}
@ -128,7 +155,6 @@ void Clickable::Touch(const TouchInput &input) {
}
void Clickable::Update(const InputState &input_state) {
OnClick.Update();
if (!HasFocus())
return;
@ -182,21 +208,21 @@ void ClickableItem::Draw(UIContext &dc) {
void Choice::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
dc.Draw()->MeasureText(dc.theme->uiFont, text_.c_str(), &w, &h);
w += 16;
h += 16;
}
void Choice::Draw(UIContext &dc) {
ClickableItem::Draw(dc);
int paddingX = 4;
int paddingY = 4;
int paddingX = 8;
dc.Draw()->DrawText(dc.theme->uiFont, text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER);
// dc.draw->DrawText(dc.theme->uiFontSmaller, text_.c_str(), paddingX, paddingY, 0xFFFFFFFF, ALIGN_TOPLEFT);
}
void InfoItem::Draw(UIContext &dc) {
Item::Draw(dc);
int paddingX = 4;
int paddingY = 4;
int paddingX = 8;
dc.Draw()->DrawText(dc.theme->uiFont, text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER);
dc.Draw()->DrawText(dc.theme->uiFont, text_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER | ALIGN_RIGHT);
// dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y + 2, dc.theme->itemDownStyle.bgColor);
@ -209,8 +235,8 @@ void ItemHeader::Draw(UIContext &dc) {
void CheckBox::Draw(UIContext &dc) {
ClickableItem::Draw(dc);
int paddingX = 4;
int paddingY = 4;
int paddingX = 8;
int paddingY = 8;
int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff;

View File

@ -180,12 +180,14 @@ struct HandlerRegistration {
class Event {
public:
Event() : triggered_(false) {}
Event() {}
~Event() {
handlers_.clear();
}
// Call this from input thread or whatever, it doesn't matter
void Trigger(EventParams &e);
// Call this from UI thread
void Update();
void Dispatch(EventParams &e);
// This is suggested for use in most cases. Autobinds, allowing for neat syntax.
template<class T>
@ -198,11 +200,8 @@ public:
void Add(std::function<EventReturn(EventParams&)> func);
private:
recursive_mutex mutex_;
std::vector<HandlerRegistration> handlers_;
bool triggered_;
EventParams eventParams_;
DISALLOW_COPY_AND_ASSIGN(Event);
};
@ -368,6 +367,7 @@ public:
virtual void Draw(UIContext &dc);
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
const std::string &GetText() const { return text_; }
private:
Style style_;
@ -584,4 +584,7 @@ private:
void MeasureBySpec(Size sz, float contentWidth, MeasureSpec spec, float *measured);
void EventTriggered(Event *e, EventParams params);
void DispatchEvents();
} // namespace

View File

@ -682,6 +682,7 @@ void UpdateViewHierarchy(const InputState &input_state, ViewGroup *root) {
EnableFocusMovement(false);
root->Update(input_state);
DispatchEvents();
}
ListView::ListView(ListAdaptor *a, LayoutParams *layoutParams)