Skip to content

Commit

Permalink
Widgets|libgui: Navigating paths in BrowserWidget
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent c254302 commit 1a15ea5
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 28 deletions.
2 changes: 2 additions & 0 deletions doomsday/libs/gui/include/de/widgets/browserwidget.h
Expand Up @@ -40,6 +40,8 @@ class LIBGUI_PUBLIC BrowserWidget : public GuiWidget

void setCurrentPath(const Path &path);

// DE_DEFINE_AUDIENCE2(Navigation, void browserNavigateTo(const Path &))

private:
DE_PRIVATE(d)
};
Expand Down
75 changes: 61 additions & 14 deletions doomsday/libs/gui/src/widgets/browserwidget.cpp
Expand Up @@ -18,6 +18,8 @@

#include "de/BrowserWidget"
#include "de/ButtonWidget"
#include "de/DialogContentStylist"
#include "de/FlowLayout"
#include "de/MenuWidget"
#include "de/ProgressWidget"
#include "de/ScrollAreaWidget"
Expand All @@ -31,13 +33,17 @@ DE_PIMPL(BrowserWidget)
const ui::TreeData *data = nullptr;
Path path;
LabelWidget *cwdLabel;
LabelWidget *currentPath;
// LabelWidget *currentPath;
LabelWidget *menuLabel;
ScrollAreaWidget *scroller;
MenuWidget *menu;
std::unique_ptr<FlowLayout> pathFlow;
DialogContentStylist stylist;
Dispatch dispatch;

Impl(Public *i)
: Base(i)
, stylist(*i)
{
RuleRectangle &rule = self().rule();

Expand All @@ -47,20 +53,25 @@ DE_PIMPL(BrowserWidget)
cwdLabel = LabelWidget::appendSeparatorWithText("Path", i);
layout << *cwdLabel;

currentPath = new LabelWidget("cwd");
pathFlow.reset(new FlowLayout(cwdLabel->rule().left(), cwdLabel->rule().bottom(),
rule.width()));

/*currentPath = new LabelWidget("cwd");
currentPath->setSizePolicy(ui::Fixed, ui::Expand);
currentPath->setAlignment(ui::AlignLeft);
layout << *currentPath;
layout << *currentPath;*/

layout.append(pathFlow->height());

menuLabel = LabelWidget::appendSeparatorWithText("Contents", i);
layout << *menuLabel;

scroller = new ScrollAreaWidget("scroller");
scroller = &i->addNew<ScrollAreaWidget>("scroller");
layout << *scroller;
scroller->rule()
.setInput(Rule::Bottom, rule.bottom());

menu = new MenuWidget("items");
menu = &scroller->addNew<MenuWidget>("items");
menu->setGridSize(1, ui::Filled, 0, ui::Expand);
menu->rule()
.setLeftTop(scroller->contentRule().left(), scroller->contentRule().top())
Expand All @@ -74,36 +85,72 @@ DE_PIMPL(BrowserWidget)
scroller->enableScrolling(true);
scroller->enableIndicatorDraw(true);

i->add(currentPath);
scroller->add(menu);
i->add(scroller);
// i->add(currentPath);
// scroller->add(menu);
// i->add(scroller);

// menu->organizer().audienceForWidgetCreation() += this;
}

void changeTo(const Path &newPath)
{
debug("[BrowserWidget] change to '%s'", newPath.c_str());

DE_ASSERT(data);

scroller->scrollY(0);

// TODO: This is an async op, need to show progress widget.
path = newPath;
currentPath->setText(path);
//currentPath->setText(path);
createPathButtons();
const ui::Data &items = data->items(path);
menu->setItems(items);

// TODO: Recreate the path segment buttons.
}

// void widgetCreatedForItem(GuiWidget &widget, const ui::Item &item) override
// {
// widget.as<ButtonWidget>().audienceForPress() += [this, &item]() {
void createPathButtons()
{
// Get rid of the old buttons.
for (auto *i : pathFlow->widgets())
{
GuiWidget::destroy(i);
}
pathFlow->clear();

// Create a new button for each segment of the path.
for (int i = 0; i < path.segmentCount(); ++i)
{
const auto &segment = path.segment(i);

auto &button = self().addNew<ButtonWidget>();
button.setSizePolicy(ui::Expand, ui::Expand);
button.setText(Stringf("%s/", String(segment).c_str()));

if (i == path.segmentCount() - 1)
{
button.setTextColor("accent");
}
else
{
const Path buttonPath = path.subPath({0, i + 1});
button.audienceForPress() += [this, buttonPath]() {
dispatch += [this, buttonPath](){
changeTo(buttonPath);
};
};
}

pathFlow->append(button);
}
}

// };
// }
// DE_PIMPL_AUDIENCE(Navigation)
};

//DE_AUDIENCE_METHOD(BrowserWidget, Navigation)

BrowserWidget::BrowserWidget(const String &name)
: GuiWidget(name)
, d(new Impl(this))
Expand Down
28 changes: 14 additions & 14 deletions doomsday/libs/gui/src/widgets/directorybrowserwidget.cpp
Expand Up @@ -27,7 +27,7 @@ DE_GUI_PIMPL(DirectoryBrowserWidget)
{
DirectoryTreeData dirTree;
IndirectRule *itemHeight = new IndirectRule;
LoopCallback mainCall;
Dispatch dispatch;

Impl(Public *i) : Base(i)
{
Expand All @@ -42,26 +42,26 @@ DE_GUI_PIMPL(DirectoryBrowserWidget)
releaseRef(itemHeight);
}

GuiWidget *makeItemWidget(const ui::Item &item, const GuiWidget *)
GuiWidget *makeItemWidget(const ui::Item &, const GuiWidget *)
{
const auto &dirItem = item.as<DirectoryItem>();

auto *widget = new ButtonWidget;
widget->setSizePolicy(ui::Fixed, ui::Fixed);
widget->setAlignment(ui::AlignLeft);
widget->rule().setInput(Rule::Height, *itemHeight);
widget->margins().setTopBottom(rule("unit"));

if (dirItem.isDirectory())
{
const NativePath subDir = dirItem.path();
widget->audienceForPress() += [this, subDir]() {
// Changing the directory causes this widget to be deleted, so
// we need to postpone the change until the press has been
// handled.
mainCall.enqueue([this, subDir]() { self().setCurrentPath(subDir); });
};
}
widget->audienceForPress() += [this, widget]() {
// Changing the directory causes this widget to be deleted, so
// we need to postpone the change until the press has been
// handled.
const ui::DataPos pos = self().menu().findItem(*widget);
const auto & dirItem = self().menu().items().at(pos).as<DirectoryItem>();
if (dirItem.isDirectory())
{
const NativePath toDir = dirItem.path();
dispatch += [this, toDir]() { self().setCurrentPath(toDir); };
}
};

return widget;
}
Expand Down

0 comments on commit 1a15ea5

Please sign in to comment.