Display a basic list of assets, set up scrolling and notifier listening
* Display a non-interactive list of assets, updates as assets get loaded. * Notifier listening happens via the view, so the grid-view supports listening to notifiers. This is what triggers regular redraws as assets get loaded. * Scrolling may need more fine tuning, so that scroll-bars are hidden if they don't apply (e.g. don't show horizontal scroll-bar for the vertically expanding grid-view layout).
This commit is contained in:
parent
a54bd5fe19
commit
3df2e4e888
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup editorui
|
||||
*
|
||||
* API for simple creation of grid UIs, supporting typically needed features.
|
||||
* https://wiki.blender.org/wiki/Source/Interface/Views/Grid_Views
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct wmNotifier;
|
||||
|
||||
namespace blender::ui {
|
||||
|
||||
class AbstractGridViewItem {
|
||||
public:
|
||||
virtual ~AbstractGridViewItem() = default;
|
||||
|
||||
protected:
|
||||
AbstractGridViewItem() = default;
|
||||
};
|
||||
|
||||
class AbstractGridView {
|
||||
public:
|
||||
virtual ~AbstractGridView() = default;
|
||||
|
||||
/** Listen to a notifier, returning true if a redraw is needed. */
|
||||
virtual bool listen(const wmNotifier &) const;
|
||||
|
||||
// protected:
|
||||
virtual void build() = 0;
|
||||
};
|
||||
|
||||
} // namespace blender::ui
|
|
@ -80,6 +80,7 @@ struct wmKeyMapItem;
|
|||
struct wmMsgBus;
|
||||
struct wmOperator;
|
||||
struct wmOperatorType;
|
||||
struct wmRegionListenerParams;
|
||||
struct wmWindow;
|
||||
|
||||
typedef struct uiBlock uiBlock;
|
||||
|
@ -91,6 +92,8 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle;
|
|||
typedef struct uiTreeViewHandle uiTreeViewHandle;
|
||||
/* C handle for C++ #ui::AbstractTreeViewItem type. */
|
||||
typedef struct uiTreeViewItemHandle uiTreeViewItemHandle;
|
||||
/* C handle for C++ #ui::AbstractGridView type. */
|
||||
typedef struct uiGridViewHandle uiGridViewHandle;
|
||||
|
||||
/* Defines */
|
||||
|
||||
|
@ -3163,6 +3166,9 @@ void UI_interface_tag_script_reload(void);
|
|||
/* Support click-drag motion which presses the button and closes a popover (like a menu). */
|
||||
#define USE_UI_POPOVER_ONCE
|
||||
|
||||
void UI_block_views_listen(const uiBlock *block,
|
||||
const struct wmRegionListenerParams *listener_params);
|
||||
|
||||
bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item);
|
||||
bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a, const uiTreeViewItemHandle *b);
|
||||
/**
|
||||
|
@ -3201,6 +3207,11 @@ uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const struct ARegion *regi
|
|||
const int xy[2]) ATTR_NONNULL(1, 2);
|
||||
uiTreeViewItemHandle *UI_block_tree_view_find_active_item(const struct ARegion *region);
|
||||
|
||||
/**
|
||||
* Listen to \a notifier, returning true if the region should redraw.
|
||||
*/
|
||||
bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view, const wmNotifier *notifier);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,7 @@ struct uiSearchItems;
|
|||
|
||||
namespace blender::ui {
|
||||
|
||||
class AbstractGridView;
|
||||
class AbstractTreeView;
|
||||
|
||||
/**
|
||||
|
@ -69,6 +70,10 @@ void attribute_search_add_items(
|
|||
/**
|
||||
* Override this for all available tree types.
|
||||
*/
|
||||
blender::ui::AbstractGridView *UI_block_add_view(
|
||||
uiBlock &block,
|
||||
blender::StringRef idname,
|
||||
std::unique_ptr<blender::ui::AbstractGridView> tree_view);
|
||||
blender::ui::AbstractTreeView *UI_block_add_view(
|
||||
uiBlock &block,
|
||||
blender::StringRef idname,
|
||||
|
|
|
@ -38,6 +38,7 @@ set(INC
|
|||
)
|
||||
|
||||
set(SRC
|
||||
grid_view.cc
|
||||
interface.c
|
||||
interface_align.c
|
||||
interface_anim.c
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup edinterface
|
||||
*/
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
|
||||
#include "UI_grid_view.hh"
|
||||
|
||||
namespace blender::ui {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
bool AbstractGridView::listen(const wmNotifier &) const
|
||||
{
|
||||
/* Nothing by default. */
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace blender::ui
|
||||
|
||||
using namespace blender::ui;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view_handle,
|
||||
const wmNotifier *notifier)
|
||||
{
|
||||
const AbstractGridView &view = *reinterpret_cast<const AbstractGridView *>(view_handle);
|
||||
return view.listen(*notifier);
|
||||
}
|
|
@ -24,15 +24,22 @@
|
|||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "interface_intern.h"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
|
||||
#include "UI_grid_view.hh"
|
||||
#include "UI_tree_view.hh"
|
||||
|
||||
using namespace blender;
|
||||
|
@ -44,10 +51,11 @@ using namespace blender::ui;
|
|||
*/
|
||||
struct ViewLink : public Link {
|
||||
using TreeViewPtr = std::unique_ptr<AbstractTreeView>;
|
||||
using GridViewPtr = std::unique_ptr<AbstractGridView>;
|
||||
|
||||
std::string idname;
|
||||
/* NOTE: Can't use std::get() on this until minimum macOS deployment target is 10.14. */
|
||||
std::variant<TreeViewPtr> view;
|
||||
std::variant<TreeViewPtr, GridViewPtr> view;
|
||||
};
|
||||
|
||||
template<class T> T *get_view_from_link(ViewLink &link)
|
||||
|
@ -56,17 +64,32 @@ template<class T> T *get_view_from_link(ViewLink &link)
|
|||
return t_uptr ? t_uptr->get() : nullptr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static T *ui_block_add_view_impl(uiBlock &block, StringRef idname, std::unique_ptr<T> view)
|
||||
{
|
||||
static_assert(std::is_same_v<T, AbstractTreeView> || std::is_same_v<T, AbstractGridView>,
|
||||
"Unsupported view type");
|
||||
ViewLink *view_link = MEM_new<ViewLink>(__func__);
|
||||
BLI_addtail(&block.views, view_link);
|
||||
|
||||
view_link->view = std::move(view);
|
||||
view_link->idname = idname;
|
||||
|
||||
return get_view_from_link<T>(*view_link);
|
||||
}
|
||||
|
||||
AbstractGridView *UI_block_add_view(uiBlock &block,
|
||||
StringRef idname,
|
||||
std::unique_ptr<AbstractGridView> tree_view)
|
||||
{
|
||||
return ui_block_add_view_impl<AbstractGridView>(block, idname, std::move(tree_view));
|
||||
}
|
||||
|
||||
AbstractTreeView *UI_block_add_view(uiBlock &block,
|
||||
StringRef idname,
|
||||
std::unique_ptr<AbstractTreeView> tree_view)
|
||||
{
|
||||
ViewLink *view_link = MEM_new<ViewLink>(__func__);
|
||||
BLI_addtail(&block.views, view_link);
|
||||
|
||||
view_link->view = std::move(tree_view);
|
||||
view_link->idname = idname;
|
||||
|
||||
return get_view_from_link<AbstractTreeView>(*view_link);
|
||||
return ui_block_add_view_impl<AbstractTreeView>(block, idname, std::move(tree_view));
|
||||
}
|
||||
|
||||
void ui_block_free_views(uiBlock *block)
|
||||
|
@ -76,6 +99,19 @@ void ui_block_free_views(uiBlock *block)
|
|||
}
|
||||
}
|
||||
|
||||
void UI_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
|
||||
{
|
||||
LISTBASE_FOREACH (ViewLink *, view_link, &block->views) {
|
||||
/* TODO only grid views, should this be supported by all views? */
|
||||
if (AbstractGridView *grid_view = get_view_from_link<AbstractGridView>(*view_link)) {
|
||||
if (UI_grid_view_listen_should_redraw(reinterpret_cast<uiGridViewHandle *>(grid_view),
|
||||
listener_params->notifier)) {
|
||||
ED_region_tag_redraw(listener_params->region);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const ARegion *region, const int xy[2])
|
||||
{
|
||||
uiButTreeRow *tree_row_but = (uiButTreeRow *)ui_tree_row_find_mouse_over(region, xy);
|
||||
|
|
|
@ -161,6 +161,10 @@ void ED_region_do_listen(wmRegionListenerParams *params)
|
|||
region->type->listener(params);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) {
|
||||
UI_block_views_listen(block, params);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (uiList *, list, ®ion->ui_lists) {
|
||||
if (list->type && list->type->listener) {
|
||||
list->type->listener(list, params);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "asset_browser_intern.hh"
|
||||
#include "asset_view.hh"
|
||||
|
@ -38,9 +39,12 @@ using namespace blender::ed::asset_browser;
|
|||
void asset_browser_main_region_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
const SpaceAssets *asset_space = CTX_wm_space_assets(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
|
||||
UI_ThemeClearColor(TH_BACK);
|
||||
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
||||
uiLayout *layout = UI_block_layout(block,
|
||||
|
@ -55,6 +59,15 @@ void asset_browser_main_region_draw(const bContext *C, ARegion *region)
|
|||
|
||||
asset_view_create_in_layout(*C, asset_space->asset_library_ref, *layout);
|
||||
|
||||
/* Update main region View2d dimensions. */
|
||||
int layout_width, layout_height;
|
||||
UI_block_layout_resolve(block, &layout_width, &layout_height);
|
||||
UI_view2d_totRect_set(v2d, layout_width, layout_height);
|
||||
|
||||
UI_block_end(C, block);
|
||||
UI_block_draw(C, block);
|
||||
|
||||
/* reset view matrix */
|
||||
UI_view2d_view_restore(C);
|
||||
UI_view2d_scrollers_draw(v2d, nullptr);
|
||||
}
|
||||
|
|
|
@ -25,23 +25,31 @@
|
|||
#include "ED_asset.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_interface.hh"
|
||||
|
||||
#include "asset_view.hh"
|
||||
|
||||
namespace ui = blender::ui;
|
||||
|
||||
namespace blender::ed::asset_browser {
|
||||
|
||||
AssetGridView::AssetGridView(const AssetLibraryReference &asset_library_ref)
|
||||
: asset_library_ref_(asset_library_ref)
|
||||
AssetGridView::AssetGridView(const AssetLibraryReference &asset_library_ref, uiLayout &layout)
|
||||
: asset_library_ref_(asset_library_ref), layout(layout)
|
||||
{
|
||||
}
|
||||
|
||||
void AssetGridView::build()
|
||||
{
|
||||
ED_assetlist_iterate(asset_library_ref_, [](AssetHandle asset) {
|
||||
std::cout << ED_asset_handle_get_name(&asset) << std::endl;
|
||||
ED_assetlist_iterate(asset_library_ref_, [this](AssetHandle asset) {
|
||||
uiItemL(
|
||||
&layout, ED_asset_handle_get_name(&asset), ED_asset_handle_get_preview_icon_id(&asset));
|
||||
return true;
|
||||
});
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
bool AssetGridView::listen(const wmNotifier ¬ifier) const
|
||||
{
|
||||
return ED_assetlist_listen(&asset_library_ref_, ¬ifier);
|
||||
}
|
||||
|
||||
void asset_view_create_in_layout(const bContext &C,
|
||||
|
@ -55,8 +63,10 @@ void asset_view_create_in_layout(const bContext &C,
|
|||
|
||||
UI_block_layout_set_current(block, &layout);
|
||||
|
||||
AssetGridView grid_view{asset_library_ref};
|
||||
grid_view.build();
|
||||
ui::AbstractGridView *grid_view = UI_block_add_view(
|
||||
*block, "asset grid view", std::make_unique<AssetGridView>(asset_library_ref, layout));
|
||||
|
||||
grid_view->build();
|
||||
}
|
||||
|
||||
} // namespace blender::ed::asset_browser
|
||||
|
|
|
@ -20,19 +20,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "UI_grid_view.hh"
|
||||
|
||||
struct bContext;
|
||||
struct AssetLibraryReference;
|
||||
struct uiLayout;
|
||||
|
||||
namespace blender::ed::asset_browser {
|
||||
|
||||
class AssetGridView {
|
||||
class AssetGridView : public blender::ui::AbstractGridView {
|
||||
AssetLibraryReference asset_library_ref_;
|
||||
|
||||
public:
|
||||
AssetGridView(const AssetLibraryReference &);
|
||||
/* TODO temp. */
|
||||
uiLayout &layout;
|
||||
|
||||
void build();
|
||||
public:
|
||||
AssetGridView(const AssetLibraryReference &, uiLayout &layout);
|
||||
|
||||
void build() override;
|
||||
bool listen(const wmNotifier &) const override;
|
||||
};
|
||||
|
||||
void asset_view_create_in_layout(const bContext &C,
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "asset_browser_intern.hh"
|
||||
#include "asset_view.hh"
|
||||
|
@ -57,10 +58,16 @@ static SpaceLink *asset_browser_create(const ScrArea *UNUSED(area), const Scene
|
|||
}
|
||||
|
||||
{
|
||||
/* Main window. */
|
||||
/* Main region. */
|
||||
ARegion *region = MEM_cnew<ARegion>("asset browser main region");
|
||||
BLI_addtail(&assets_space->regionbase, region);
|
||||
region->regiontype = RGN_TYPE_WINDOW;
|
||||
|
||||
region->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
|
||||
region->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
|
||||
region->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
|
||||
region->v2d.keeptot = V2D_KEEPTOT_STRICT;
|
||||
region->v2d.minzoom = region->v2d.maxzoom = 1.0f;
|
||||
}
|
||||
|
||||
return (SpaceLink *)assets_space;
|
||||
|
@ -90,8 +97,9 @@ static void asset_browser_keymap(wmKeyConfig *UNUSED(keyconf))
|
|||
/* ---------------------------------------------------------------------- */
|
||||
/* Main Region */
|
||||
|
||||
static void asset_browser_main_region_init(wmWindowManager *UNUSED(wm), ARegion *UNUSED(region))
|
||||
static void asset_browser_main_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
|
||||
{
|
||||
UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy);
|
||||
}
|
||||
|
||||
static void asset_browser_main_region_listener(const wmRegionListenerParams *UNUSED(params))
|
||||
|
|
|
@ -102,6 +102,7 @@ set(SRC
|
|||
../include/ED_uvedit.h
|
||||
../include/ED_view3d.h
|
||||
../include/ED_view3d_offscreen.h
|
||||
../include/UI_grid_view.hh
|
||||
../include/UI_icons.h
|
||||
../include/UI_interface.h
|
||||
../include/UI_interface.hh
|
||||
|
|
Loading…
Reference in New Issue