namespace util {
+ using ucl::util::wrapUnique;
using ucl::util::makeUnique;
using ucl::util::dispose;
}
return m_items;
}
- void CustomMediaAlbum::addChangeHandler(const NotiHandler &handler)
+ void CustomMediaAlbum::addChangeHandler(NotiHandler handler)
{
}
- void CustomMediaAlbum::delChangeHandler(const NotiHandler &handler)
+ void CustomMediaAlbum::delChangeHandler(NotiHandler::CDRef handler)
{
}
// IMediaAlbum //
- virtual void addChangeHandler(
- const NotiHandler &handler) final override;
+ virtual void addChangeHandler(NotiHandler handler) final override;
virtual void delChangeHandler(
- const NotiHandler &handler) final override;
+ NotiHandler::CDRef handler) final override;
virtual ucl::Result forEachMedia(EachCb cb) const final override;
virtual ucl::Result getMediaCount(int &count) const final override;
UCL_DECLARE_REF_ALIASES(IJob);
- class IJob : public ucl::Polymorphic {
+ class IJob : protected ucl::NonCopyable {
public:
virtual ucl::Result getResult() const = 0;
virtual bool isCancelable() const = 0;
UCL_DECLARE_REF_ALIASES(IMediaAlbum);
- class IMediaAlbum : public ucl::Polymorphic {
+ class IMediaAlbum : protected ucl::NonCopyable {
public:
using EachCb = ucl::Delegate<bool(MediaItemSRef media)>;
public:
- virtual void addChangeHandler(const NotiHandler &handler) = 0;
- virtual void delChangeHandler(const NotiHandler &handler) = 0;
+ virtual void addChangeHandler(NotiHandler handler) = 0;
+ virtual void delChangeHandler(NotiHandler::CDRef handler) = 0;
virtual ucl::Result forEachMedia(EachCb cb) const = 0;
virtual ucl::Result getMediaCount(int &count) const = 0;
namespace gallery { namespace { namespace impl {
- using ucl::AutoHandle;
+ using ucl::AutoObject;
const std::string MIME_PREFIX_IMAGE {"image/"};
const std::string MIME_PREFIX_VIDEO {"video/"};
const std::string URI_PREFIX_FILE {"file://"};
- using AutoImageMeta = AutoHandle<image_meta_h, int, image_meta_destroy>;
+ using AutoImageMeta = AutoObject<image_meta_h, int, image_meta_destroy>;
MediaType getFileMediaType(const std::string &filePath)
{
}
if (isNotEmpty(m_thumbPath)) {
- cb(RES_OK, m_thumbPath);
+ if (const auto cbLock = cb.lock()) {
+ cbLock(RES_OK, m_thumbPath);
+ }
return RES_OK;
}
return RES_FALSE;
}
- auto cbProxy = util::makeUnique(new ThumbCbProxy{this});
+ auto cbProxy = util::wrapUnique(new ThumbCbProxy{this});
cbProxy->callbacks += cb;
{
#include <media_content.h>
-#include "ucl/misc/AutoHandle.h"
+#include "ucl/misc/AutoObject.h"
#include "ucl/misc/Event.h"
#include "IJob.h"
using MediaItems = std::vector<MediaItemSRef>;
- class MediaItem : public ucl::Polymorphic {
+ class MediaItem : protected ucl::NonCopyable {
public:
using ThumbnailPathGetCb =
ucl::WeakDelegate<void(ucl::Result, const std::string &path)>;
};
private:
- using AutoMediaInfo = ucl::AutoHandle<
+ using AutoMediaInfo = ucl::AutoObject<
media_info_h, int, media_info_destroy>;
private:
return m_maxMediaVolume;
}
- void SoundManager::addMediaDeviceStateChangeHandler(
- const NotiHandler &handler)
+ void SoundManager::addMediaDeviceStateChangeHandler(NotiHandler handler)
{
- m_onMediaDeviceStateChange += handler;
+ m_onMediaDeviceStateChange += std::move(handler);
}
void SoundManager::delMediaDeviceStateChangeHandler(
- const NotiHandler &handler)
+ NotiHandler::CDRef handler)
{
m_onMediaDeviceStateChange -= handler;
}
- void SoundManager::addMediaVolumeChangeHandler(const NotiHandler &handler)
+ void SoundManager::addMediaVolumeChangeHandler(NotiHandler handler)
{
- m_onMediaVolumeChange += handler;
+ m_onMediaVolumeChange += std::move(handler);
}
- void SoundManager::delMediaVolumeChangeHandler(const NotiHandler &handler)
+ void SoundManager::delMediaVolumeChangeHandler(NotiHandler::CDRef handler)
{
m_onMediaVolumeChange -= handler;
}
int getCurrentMediaVolume() const;
int getMaxMediaVolume() const;
- void addMediaDeviceStateChangeHandler(const NotiHandler &handler);
- void delMediaDeviceStateChangeHandler(const NotiHandler &handler);
+ void addMediaDeviceStateChangeHandler(NotiHandler handler);
+ void delMediaDeviceStateChangeHandler(NotiHandler::CDRef handler);
- void addMediaVolumeChangeHandler(const NotiHandler &handler);
- void delMediaVolumeChangeHandler(const NotiHandler &handler);
+ void addMediaVolumeChangeHandler(NotiHandler handler);
+ void delMediaVolumeChangeHandler(NotiHandler::CDRef handler);
private:
friend class ucl::ReffedObj<SoundManager>;
if (m_selfPtr) {
*m_selfPtr = nullptr;
}
- if (m_onComplete) {
- m_onComplete();
+ if (const auto handler = m_onComplete.lock()) {
+ handler();
}
}
}
return RES_OK;
}
- void GalleryAlbum::addChangeHandler(const NotiHandler &handler)
+ void GalleryAlbum::addChangeHandler(NotiHandler handler)
{
- m_onChange += handler;
+ m_onChange += std::move(handler);
}
- void GalleryAlbum::delChangeHandler(const NotiHandler &handler)
+ void GalleryAlbum::delChangeHandler(NotiHandler::CDRef handler)
{
m_onChange -= handler;
}
public:
// IMediaAlbum //
- virtual void addChangeHandler(
- const NotiHandler &handler) final override;
+ virtual void addChangeHandler(NotiHandler handler) final override;
virtual void delChangeHandler(
- const NotiHandler &handler) final override;
+ NotiHandler::CDRef handler) final override;
virtual ucl::Result forEachMedia(EachCb cb) const final override;
virtual ucl::Result getMediaCount(int &count) const final override;
FAIL_RETURN(util::createCircleSurface(*m_navi),
"util::createCircleSurface() failed!");
- m_sysEventProvider.addEventHandler(
- WEAK_DELEGATE(Instance::onSysEvent, asWeak(*this)));
+ m_sysEventProvider.addEventHandler(WEAK_DELEGATE_THIS(onSysEvent));
return RES_OK;
}
LOG_RETURN(RES_FAIL, "Gallery::newInstance() failed!");
}
- m_gallery->getAlbum()->addChangeHandler(WEAK_DELEGATE(
- Instance::onAlbumChanged, asWeak(*this)));
+ m_gallery->getAlbum()->addChangeHandler(
+ WEAK_DELEGATE_THIS(onAlbumChanged));
return RES_OK;
}
{
DLOG("Creating NoContentPage.");
m_page = NoContentPage::Builder().setNaviframe(m_navi).
- build(WEAK_DELEGATE(
- Instance::onPageExitRequest, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onPageExitRequest));
}
void Instance::createThumbnailPage()
m_page = ThumbnailPage::Builder().setNaviframe(m_navi).
setAlbum(m_gallery->getAlbum()).
- build(WEAK_DELEGATE(
- Instance::onPageExitRequest, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onPageExitRequest));
}
void Instance::createPreviewPage(const IMediaAlbumSRef &album,
setAlbum(album).
setStartupMode(PreviewPage::Mode::OPERATION_VIEW).
setStartItemIndex(startItemIndex).
- build(WEAK_DELEGATE(
- Instance::onPageExitRequest, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onPageExitRequest));
}
void Instance::createVideoPlayerPage(const MediaItemSRef &media)
DLOG("Creating VideoPlayerPage.");
m_page = VideoPlayerPage::Builder().setNaviframe(m_navi).
setMedia(media).
- build(WEAK_DELEGATE(
- Instance::onPageExitRequest, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onPageExitRequest));
}
void Instance::onAlbumChanged()
Result Dialog::createPopup(ElmWidget &parent, const PopupType popupType)
{
Evas_Object *const popupEo = ((popupType == PopupType::NORMAL) ?
- elm_popup_add(parent) : elm_ctxpopup_add(parent));
+ elm_popup_add(as_eo(parent)) : elm_ctxpopup_add(as_eo(parent)));
if (!popupEo) {
LOG_RETURN(RES_FAIL, "elm_popup_add() failed!");
}
m_popup = makeShared<StyledWidget>(popupEo);
- m_popup->addEventHandler(POPUP_DISMISSED, WEAK_DELEGATE(
- Dialog::onPopupDismissed, asWeak(*this)));
+ m_popup->addEventHandler(POPUP_DISMISSED,
+ WEAK_DELEGATE_THIS(onPopupDismissed));
- eext_object_event_callback_add(*m_popup, EEXT_CALLBACK_BACK,
+ eext_object_event_callback_add(popupEo, EEXT_CALLBACK_BACK,
CALLBACK_A(Dialog::onPopupHWBackKey), this);
return RES_OK;
if (m_popup && !m_isDismissed) {
m_isDismissed = true;
deactivateBy(m_popup.get());
- elm_popup_dismiss(*m_popup);
+ elm_popup_dismiss(as_eo(*m_popup));
}
}
void Dialog::dispose()
{
if (m_popup) {
- eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
+ eext_object_event_callback_del(as_eo(*m_popup), EEXT_CALLBACK_BACK,
CALLBACK_A(Dialog::onPopupHWBackKey));
deactivateBy(m_popup.get());
}
m_navi->addEventHandler(NAVI_TRANSITION_STARTED,
- WEAK_DELEGATE(Page::onTransitionStarted, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onTransitionStarted));
m_navi->addEventHandler(NAVI_TRANSITION_FINISHED,
- WEAK_DELEGATE(Page::onTransitionFinished, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onTransitionFinished));
m_navi->addEventHandler(impl::TOP_PAGE_CHANGED,
- WEAK_DELEGATE(Page::onTopPageChanged, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onTopPageChanged));
eext_object_event_callback_add(content, EEXT_CALLBACK_BACK,
CALLBACK_A(Page::onHWBackKey), this);
void Page::requestExit()
{
- if (m_onExitRequest) {
- m_onExitRequest(*this);
+ if (const auto handler = m_onExitRequest.lock()) {
+ handler(*this);
} else {
WLOG("m_onExitRequest is NULL");
exit();
const LayoutTheme iconTheme, const TString &text)
{
const auto btn = makeShared<StyledWidget>(
- elm_button_add(*m_popup), false);
+ elm_button_add(as_eo(*m_popup)), false);
btn->setStyle(btnStyle);
m_popup->setContent(*btn, part);
show(*btn);
btn->setData(impl::BTN_EVENT_DATA, impl::asData(event));
- btn->addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
- AlertDialog::onBtnClick, asWeak(*this)));
+ btn->addEventHandler(BTN_CLICKED, WEAK_DELEGATE_THIS(onBtnClick));
return RES_OK;
}
bool AlertDialog::dispatchEvent(const Event event)
{
- if (!m_handler) {
- WLOG("Handler was destroyed!");
- return true;
+ if (const auto handler = m_handler.lock()) {
+ return handler(*this, event);
}
- return m_handler(*this, event);
+ WLOG("Handler was destroyed!");
+ return true;
+
}
void AlertDialog::onBtnClick(Widget &widget, void *eventInfo)
FAIL_RETURN(GuiPresenter::prepare(parent, PF_DEACTIVATOR),
"GuiPresenter::prepare() failed!");
- Evas_Object *const more = eext_more_option_add(parentWidget);
+ Evas_Object *const more = eext_more_option_add(as_eo(parentWidget));
if (!more) {
LOG_RETURN(RES_FAIL, "eext_more_option_add() failed!");
}
FAIL_RETURN(addItem(option), "addItem() failed!");
}
- m_widget->addEventHandler(impl::MORE_OPENED, WEAK_DELEGATE(
- MoreOptionsPresenter::onOpened, asWeak(*this)));
- m_widget->addEventHandler(impl::MORE_CLOSED, WEAK_DELEGATE(
- MoreOptionsPresenter::onClosed, asWeak(*this)));
+ m_widget->addEventHandler(impl::MORE_OPENED,
+ WEAK_DELEGATE_THIS(onOpened));
+ m_widget->addEventHandler(impl::MORE_CLOSED,
+ WEAK_DELEGATE_THIS(onClosed));
- m_widget->addEventHandler(impl::MORE_ITEM_CLICKED, WEAK_DELEGATE(
- MoreOptionsPresenter::onItemClicked, asWeak(*this)));
- m_widget->addEventHandler(impl::MORE_ITEM_SELECTED, WEAK_DELEGATE(
- MoreOptionsPresenter::onItemSelected, asWeak(*this)));
+ m_widget->addEventHandler(impl::MORE_ITEM_CLICKED,
+ WEAK_DELEGATE_THIS(onItemClicked));
+ m_widget->addEventHandler(impl::MORE_ITEM_SELECTED,
+ WEAK_DELEGATE_THIS(onItemSelected));
deactivateBy(m_widget.get());
Result MoreOptionsPresenter::addItem(const Option &option)
{
- const auto item = eext_more_option_item_append(*m_widget);
+ const auto item = eext_more_option_item_append(as_eo(*m_widget));
if (!item) {
LOG_RETURN(RES_FAIL, "eext_more_option_item_append() failed!");
}
LOG_RETURN(RES_FAIL, "Layout::build() failed!");
}
eext_more_option_item_part_content_set(item,
- impl::PART_ICON.name, *icon);
+ impl::PART_ICON.name, as_eo(*icon));
}
impl::setText(item, option.text, impl::PART_MAIN_TEXT);
void MoreOptionsPresenter::setOpened(const bool isOpened)
{
stopTimer();
- eext_more_option_opened_set(*m_widget, toEina(isOpened));
+ eext_more_option_opened_set(as_eo(*m_widget), toEina(isOpened));
}
bool MoreOptionsPresenter::isOpened() const
{
- return eext_more_option_opened_get(*m_widget);
+ return eext_more_option_opened_get(as_eo(*m_widget));
}
void MoreOptionsPresenter::setOpenedDelayed(
ucl::ElmWidgetSRef m_parentWidget;
};
- class IListener : public ucl::Polymorphic {
+ class IListener : protected ucl::NonCopyable {
public:
virtual void onMoreOptionClicked(MoreOptionsPresenter &sender,
int optionId) = 0;
Result ProcessingPresenter::createProgress()
{
- Evas_Object *const progressEo = elm_progressbar_add(*m_widget);
+ Evas_Object *const progressEo = elm_progressbar_add(as_eo(*m_widget));
if (!progressEo) {
LOG_RETURN(RES_FAIL, "elm_progressbar_add() failed!");
}
- StyledWidget progress{progressEo};
+ StyledWidget progress{progressEo, false};
progress.setStyle(ElmStyle("process"));
m_widget->setContent(progress, EdjePart("gallery.swallow.progress"));
- elm_progressbar_pulse(progress, EINA_TRUE);
+ elm_progressbar_pulse(as_eo(progress), EINA_TRUE);
show(progress);
return RES_OK;
m_popup = makeShared<StyledWidget>(popupEo);
m_popup->setStyle(impl::POPUP_STYLE);
- m_popup->addEventHandler(POPUP_DISMISSED, WEAK_DELEGATE(
- ProcessingPresenter::onPopupDismissed, asWeak(*this)));
+ m_popup->addEventHandler(POPUP_DISMISSED,
+ WEAK_DELEGATE_THIS(onPopupDismissed));
- eext_object_event_callback_add(*m_popup, EEXT_CALLBACK_BACK,
+ eext_object_event_callback_add(as_eo(*m_popup), EEXT_CALLBACK_BACK,
CALLBACK_A(ProcessingPresenter::onPopupHWBackKey), this);
return RES_OK;
m_popup->setContent(*icon, impl::PART_TOAST_ICON);
- elm_object_mirrored_automatic_set(*icon, EINA_FALSE);
- elm_object_mirrored_set(*icon, EINA_FALSE);
+ elm_object_mirrored_automatic_set(as_eo(*icon), EINA_FALSE);
+ elm_object_mirrored_set(as_eo(*icon), EINA_FALSE);
m_icon = icon;
if (m_popup && !m_isDismissed) {
m_isDismissed = true;
deactivateBy(m_popup.get());
- elm_popup_dismiss(*m_popup);
+ elm_popup_dismiss(as_eo(*m_popup));
}
}
void ProcessingPresenter::deletePopup()
{
if (m_popup) {
- eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
+ eext_object_event_callback_del(as_eo(*m_popup), EEXT_CALLBACK_BACK,
CALLBACK_A(ProcessingPresenter::onPopupHWBackKey));
deactivateBy(m_popup.get());
void ProcessingPresenter::onPopupDismissed(Widget &widget, void *eventInfo)
{
- if (m_dismissHandler) {
- m_dismissHandler();
+ if (const auto handler = m_dismissHandler.lock()) {
+ handler();
}
m_widget.reset();
deletePopup();
FAIL_RETURN(GuiPresenter::prepare(parent, PF_DEACTIVATOR),
"GuiPresenter::prepare() failed!");
- m_selectButton = makeShared<StyledWidget>(elm_button_add(*m_content));
+ m_selectButton = makeShared<StyledWidget>(
+ elm_button_add(as_eo(*m_content)));
m_selectButton->setStyle(impl::SELECT_BTN_STYLE);
m_content->set(*m_selectButton, PageContent::Part::SELECT_BUTTON);
m_content->setSelectButtonVisible(false);
show(*m_selectButton);
- m_selectButton->addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
- SelectModePresenter::onSelectBtnClick, asWeak(*this)));
+ m_selectButton->addEventHandler(BTN_CLICKED,
+ WEAK_DELEGATE_THIS(onSelectBtnClick));
if ((m_flags & FLAG_NO_BOTTOM_BUTTON) == 0) {
m_bottomButton = makeShared<StyledWidget>(
- elm_button_add(*m_content));
+ elm_button_add(as_eo(*m_content)));
m_bottomButton->setStyle(impl::BOTTOM_BTN_STYLE);
hide(*m_bottomButton);
- m_bottomButton->addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
- SelectModePresenter::onBottomBtnClick, asWeak(*this)));
+ m_bottomButton->addEventHandler(BTN_CLICKED,
+ WEAK_DELEGATE_THIS(onBottomBtnClick));
}
if ((m_flags & FLAG_NO_DISMISS_ON_ROTARY) == 0) {
{
m_isPopupDismissed = false;
- m_popup = makeShared<StyledWidget>(elm_ctxpopup_add(*m_content));
+ m_popup = makeShared<StyledWidget>(elm_ctxpopup_add(as_eo(*m_content)));
m_popup->setStyle(impl::SELECT_POPUP_STYLE);
- elm_ctxpopup_direction_priority_set(*m_popup,
+ elm_ctxpopup_direction_priority_set(as_eo(*m_popup),
ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_UP,
ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_UP);
WidgetItem deselectItem;
if (m_selectCount < m_totalCount) {
- selectItem = WidgetItem{elm_ctxpopup_item_append(*m_popup,
+ selectItem = WidgetItem{elm_ctxpopup_item_append(as_eo(*m_popup),
STR_SELECT_ALL.translate(), nullptr, CALLBACK_A(
SelectModePresenter::onSelectAll), this)};
}
if (m_selectCount > 0) {
- deselectItem = WidgetItem{elm_ctxpopup_item_append(*m_popup,
+ deselectItem = WidgetItem{elm_ctxpopup_item_append(as_eo(*m_popup),
STR_DESELECT_ALL.translate(), nullptr, CALLBACK_A(
SelectModePresenter::onDeselectAll), this)};
}
movePopup();
- m_popup->addEventHandler(POPUP_DISMISSED, WEAK_DELEGATE(
- SelectModePresenter::onPopupDismissed, asWeak(*this)));
+ m_popup->addEventHandler(POPUP_DISMISSED,
+ WEAK_DELEGATE_THIS(onPopupDismissed));
- eext_object_event_callback_add(*m_popup, EEXT_CALLBACK_BACK,
+ eext_object_event_callback_add(as_eo(*m_popup), EEXT_CALLBACK_BACK,
CALLBACK_A(SelectModePresenter::onPopupHWBackKey), this);
broadcastDeactivate();
{
if (m_popup && !m_isPopupDismissed) {
m_isPopupDismissed = true;
- elm_ctxpopup_dismiss(*m_popup);
+ elm_ctxpopup_dismiss(as_eo(*m_popup));
}
}
void SelectModePresenter::deletePopup()
{
if (m_popup) {
- eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
+ eext_object_event_callback_del(as_eo(*m_popup), EEXT_CALLBACK_BACK,
CALLBACK_A(SelectModePresenter::onPopupHWBackKey));
m_popup.reset();
void SelectModePresenter::onSelectAll(
Evas_Object *obj, void *eventInfo)
{
- if (m_popup && (m_popup->getEo() == obj)) {
+ if (as_eo(m_popup) == obj) {
dismissPopup();
dispatchEvent(Event::SELECT_ALL);
}
void SelectModePresenter::onDeselectAll(
Evas_Object *obj, void *eventInfo)
{
- if (m_popup && (m_popup->getEo() == obj)) {
+ if (as_eo(m_popup) == obj) {
dismissPopup();
dispatchEvent(Event::DESELECT_ALL);
}
BOTTOM_BUTTON_CLICK
};
- class IListener : public ucl::Polymorphic {
+ class IListener : protected ucl::NonCopyable {
public:
virtual void onSelectModeEvent(Event event) = 0;
};
// PreviewPage::Item //
- class PreviewPage::Item : public RefCountAware {
+ class PreviewPage::Item final : public RefCountAware {
public:
Item(IRefCountObj &rc, MediaItemSRef &&media,
ImageGrid &imageGrid, const int itemIndex) :
if (m_media->getFlags() & MediaItem::FLAG_THUMBNAIL) {
FAIL_LOG(result = m_media->getThumbnailPath(
- WEAK_DELEGATE(Item::onThumbnail, asWeak(*this))),
+ WEAK_DELEGATE_THIS(onThumbnail)),
"getThumbnailPath() failed!");
}
void unrealize()
{
- m_media->cancelThumbnailPathGet(
- WEAK_DELEGATE(Item::onThumbnail, asWeak(*this)));
+ m_media->cancelThumbnailPathGet(WEAK_DELEGATE_THIS(onThumbnail));
}
MediaItemSRef getMedia()
PreviewPage::~PreviewPage()
{
if (m_album) {
- m_album->delChangeHandler(WEAK_DELEGATE(
- PreviewPage::onAlbumChanged, asWeak(*this)));
+ m_album->delChangeHandler(DELEGATE_THIS(onAlbumChanged));
}
closeTempViews();
util::dispose(m_page);
LOG_RETURN(RES_FAIL, "Naviframe::push() failed!");
}
- m_album->addChangeHandler(WEAK_DELEGATE(
- PreviewPage::onAlbumChanged, asWeak(*this)));
+ m_album->addChangeHandler(WEAK_DELEGATE_THIS(onAlbumChanged));
if (m_startupMode == Mode::SELECT) {
switchToSelectMode();
setText((itemCount == 1) ?
STR_DELETE_1_PHOTO :
TString(STR_DELETE_N_PHOTO.format(itemCount))).
- setHandler(WEAK_DELEGATE(
- PreviewPage::onAlertEvent, asWeak(*this))).
+ setHandler(WEAK_DELEGATE_THIS(onAlertEvent)).
build(getNaviframe());
}
m_job = MediaItem::SaverBuilder().
setItem(m_items[itemIndex]->getMedia()).
- build(WEAK_DELEGATE(
- PreviewPage::onSaveJobComplete, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onSaveJobComplete));
if (!m_job) {
LOG_RETURN_VOID(RES_FAIL,
"MediaItem::SaverBuilder::build() failed!");
m_job = MediaItem::RemoverBuilder().
setItems(items).
- build(WEAK_DELEGATE(
- PreviewPage::onRemoveJobComplete, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onRemoveJobComplete));
if (!m_job) {
ELOG("MediaItem::RemoverBuilder::build() failed!");
return true;
info.isImageLoadSizeFull);
}
- m_page = builder.build(WEAK_DELEGATE(
- PreviewPage::onPageExitRequest, asWeak(*this)));
+ m_page = builder.build(WEAK_DELEGATE_THIS(onPageExitRequest));
}
void PreviewPage::onPageExitRequest(Page &page)
m_index(index)
{
FAIL_LOG(m_parent.m_mediaItems[m_index]->getThumbnailPath(
- WEAK_DELEGATE(RealizedItem::onThumbnail, asWeak(this))),
+ WEAK_DELEGATE_THIS(onThumbnail)),
"getThumbnailPath() failed!");
}
virtual ~RealizedItem()
{
m_parent.m_mediaItems[m_index]->cancelThumbnailPathGet(
- WEAK_DELEGATE(RealizedItem::onThumbnail, asWeak(this)));
+ WEAK_DELEGATE_THIS(onThumbnail));
}
int getIndex() const
ThumbnailPage::~ThumbnailPage()
{
if (m_album) {
- m_album->delChangeHandler(WEAK_DELEGATE(
- ThumbnailPage::onAlbumChanged, asWeak(*this)));
+ m_album->delChangeHandler(DELEGATE_THIS(onAlbumChanged));
}
if (m_more) {
m_more->setOpened(false);
LOG_RETURN(RES_FAIL, "Naviframe::push() failed!");
}
- m_album->addChangeHandler(WEAK_DELEGATE(
- ThumbnailPage::onAlbumChanged, asWeak(*this)));
+ m_album->addChangeHandler(WEAK_DELEGATE_THIS(onAlbumChanged));
m_more->setListener(asWeakThis<MoreOptionsPresenter::IListener>(this));
PreviewPage::Mode::SELECT : PreviewPage::Mode::NORMAL).
setStartItemIndex(itemIndex).
setAutoSelectStartItem(true).
- build(WEAK_DELEGATE(
- ThumbnailPage::onPageExitRequest, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onPageExitRequest));
}
void ThumbnailPage::onMoreOptionClicked(MoreOptionsPresenter &sender,
setAlbum(m_album).
setStartupMode(PreviewPage::Mode::SELECT).
setStartItemIndex(m_imageGrid->getScrolledToItemIndex()).
- build(WEAK_DELEGATE(
- ThumbnailPage::onPageExitRequest, asWeak(*this)));
+ build(WEAK_DELEGATE_THIS(onPageExitRequest));
break;
default:
sender.setOpened(false);
namespace gallery {
- using ucl::AutoAppCtrl;
+ using ucl::AppCtrlAuto;
using ucl::NaviItem;
using ucl::NaviframeSRef;
util::dispose(m_alert);
if (m_soundMgr) {
- m_soundMgr->delMediaDeviceStateChangeHandler(WEAK_DELEGATE(
- VideoPlayerPage::onMediaDeviceStateChanged, asWeak(*this)));
- m_soundMgr->delMediaVolumeChangeHandler(WEAK_DELEGATE(
- VideoPlayerPage::onMediaVolumeChanged, asWeak(*this)));
+ m_soundMgr->delMediaDeviceStateChangeHandler(
+ DELEGATE_THIS(onMediaDeviceStateChanged));
+ m_soundMgr->delMediaVolumeChangeHandler(
+ DELEGATE_THIS(onMediaVolumeChanged));
}
- if (isWindowReady()) {
- setScreenAlwaysOn(false);
- }
+ setScreenAlwaysOn(false);
delRotaryEventHandler(CALLBACK_A(VideoPlayerPage::onRotary), this);
LOG_RETURN(RES_FAIL, "m_content is NULL");
}
- elm_object_mirrored_automatic_set(*m_content, EINA_FALSE);
- elm_object_mirrored_set(*m_content, EINA_FALSE);
+ elm_object_mirrored_automatic_set(as_eo(*m_content), EINA_FALSE);
+ elm_object_mirrored_set(as_eo(*m_content), EINA_FALSE);
item = getNaviframe().push(*m_content, NAVIFRAME_NO_CLIP);
if (!item) {
updatePlayTimeText();
m_touchParser = makeShared<TouchParser>(*m_image);
- m_touchParser->setTapHandler(WEAK_DELEGATE(
- VideoPlayerPage::onTap, asWeak(*this)));
+ m_touchParser->setTapHandler(WEAK_DELEGATE_THIS(onTap));
- getWindow().addEventHandler(INSTANCE_PAUSED, WEAK_DELEGATE(
- VideoPlayerPage::onInstancePaused, asWeak(*this)));
- getWindow().addEventHandler(INSTANCE_RESUMED, WEAK_DELEGATE(
- VideoPlayerPage::onInstanceResumed, asWeak(*this)));
+ getWindow().addEventHandler(INSTANCE_PAUSED,
+ WEAK_DELEGATE_THIS(onInstancePaused));
+ getWindow().addEventHandler(INSTANCE_RESUMED,
+ WEAK_DELEGATE_THIS(onInstanceResumed));
addRotaryEventHandler(CALLBACK_A(VideoPlayerPage::onRotary), this);
LOG_RETURN(RES_FAIL, "SoundManager::newInstance() failed!");
}
- m_soundMgr->addMediaDeviceStateChangeHandler(WEAK_DELEGATE(
- VideoPlayerPage::onMediaDeviceStateChanged, asWeak(*this)));
+ m_soundMgr->addMediaDeviceStateChangeHandler(
+ WEAK_DELEGATE_THIS(onMediaDeviceStateChanged));
- m_soundMgr->addMediaVolumeChangeHandler(WEAK_DELEGATE(
- VideoPlayerPage::onMediaVolumeChanged, asWeak(*this)));
+ m_soundMgr->addMediaVolumeChangeHandler(
+ WEAK_DELEGATE_THIS(onMediaVolumeChanged));
return RES_OK;
}
"player_create() failed!");
FAIL_RETURN(util::call(player_set_display, m_player,
- PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(m_image->getEo())),
+ PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(as_eo(*m_image))),
"player_set_display() failed!");
FAIL_RETURN(util::call(player_set_display_mode, m_player,
void VideoPlayerPage::createControls()
{
createButton(impl::STYLE_VOLUME_ON_BTN, impl::PART_VOLUME_ON_BTN,
- WEAK_DELEGATE(VideoPlayerPage::onVolumeBtnClick,
- asWeak(*this)));
+ WEAK_DELEGATE_THIS(onVolumeBtnClick));
m_volumeMuteBtn = createButton(impl::STYLE_VOLUME_MUTE_BTN,
impl::PART_VOLUME_MUTE_BTN,
- WEAK_DELEGATE(VideoPlayerPage::onVolumeBtnClick,
- asWeak(*this)));
+ WEAK_DELEGATE_THIS(onVolumeBtnClick));
createButton(impl::STYLE_PLAY_BTN, impl::PART_PLAY_BTN,
- WEAK_DELEGATE(VideoPlayerPage::onPlayBtnClick,
- asWeak(*this)));
+ WEAK_DELEGATE_THIS(onPlayBtnClick));
createButton(impl::STYLE_PAUSE_BTN, impl::PART_PAUSE_BTN,
- WEAK_DELEGATE(VideoPlayerPage::onPauseBtnClick,
- asWeak(*this)));
+ WEAK_DELEGATE_THIS(onPauseBtnClick));
}
StyledWidgetSRef VideoPlayerPage::createButton(const ElmStyle style,
const EdjePart part, const WidgetEventHandler &handler)
{
const auto btn = makeShared<StyledWidget>(
- elm_button_add(*m_content), false);
+ elm_button_add(as_eo(*m_content)), false);
btn->setStyle(style);
show(*btn);
m_alert = AlertDialog::Builder().
setType(AlertDialog::Type::OK).
setText(STR_UNSUPPORTED_FORMAT).
- setHandler(WEAK_DELEGATE(
- VideoPlayerPage::onAlertEvent, asWeak(*this))).
+ setHandler(WEAK_DELEGATE_THIS(onAlertEvent)).
build(getNaviframe());
}
void VideoPlayerPage::setScreenAlwaysOn(bool isAlwaysOn)
{
- efl_util_set_window_screen_mode(getWindow(),
- (isAlwaysOn ? EFL_UTIL_SCREEN_MODE_ALWAYS_ON :
- EFL_UTIL_SCREEN_MODE_DEFAULT));
+ if (const auto win = getWindowRef()) {
+ efl_util_set_window_screen_mode(as_eo(*win),
+ (isAlwaysOn ? EFL_UTIL_SCREEN_MODE_ALWAYS_ON :
+ EFL_UTIL_SCREEN_MODE_DEFAULT));
+ }
}
Result VideoPlayerPage::launchVolumeSettings()
{
- AutoAppCtrl appCtrl;
+ AppCtrlAuto appCtrl;
FAIL_RETURN(util::getNz(app_control_create, appCtrl),
"app_control_create() failed!");
}
if (useThumb) {
- FAIL_RETURN(m_media->getThumbnailPath(WEAK_DELEGATE(
- ViewerPage::onThumbnail, asWeak(*this))),
+ FAIL_RETURN(m_media->getThumbnailPath(
+ WEAK_DELEGATE_THIS(onThumbnail)),
"m_media->getThumbnailPath() failed!");
} else if (!forceLoad) {
m_imageViewer->setLowResImagePath(m_media->getFilePath());
}
m_imageViewer->addEventHandler(IMAGE_VIEWER_ZOOM_END,
- WEAK_DELEGATE(ViewerPage::onZoomEnd, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onZoomEnd));
const auto topItem = getNaviframe().getTopItem();
if (topItem) {
}
m_touchParser = makeShared<TouchParser>(*m_imageViewer);
- m_touchParser->setDoubleTapHandler(WEAK_DELEGATE(
- ViewerPage::onDoubleTap, asWeak(*this)));
+ m_touchParser->setDoubleTapHandler(WEAK_DELEGATE_THIS(onDoubleTap));
return RES_OK;
}
int tmpW = 0;
int tmpH = 0;
- evas_object_image_size_get(image, &tmpW, &tmpH);
+ evas_object_image_size_get(as_eo(image), &tmpW, &tmpH);
if ((tmpW <= 0) || (tmpH <= 0)) {
return false;
ImageGridSRef ImageGrid::Builder::build(ElmWidget &parent) const
{
- Evas_Object *const scrollerEo = elm_scroller_add(parent);
+ Evas_Object *const scrollerEo = elm_scroller_add(as_eo(parent));
if (!scrollerEo) {
ELOG("elm_scroller_add() failed!");
return {};
ImageGrid &imageGrid, ElmWidget &parent) :
RefCountAware(&rc),
m_imageGrid(imageGrid),
- m_btn(elm_button_add(parent)),
+ m_btn(elm_button_add(as_eo(parent))),
m_image(evas_object_image_filled_add(m_btn.getEvas()))
{
- m_btn.setFocusAlowed(false);
+ m_btn.setFocusAllowed(false);
m_btn.setStyle(imageGrid.m_info.btnStyle);
show(m_btn);
- evas_object_image_load_orientation_set(m_image, EINA_TRUE);
+ evas_object_image_load_orientation_set(
+ as_eo(m_image), EINA_TRUE);
m_btn.setContent(m_image);
show(m_image);
m_image.addEventHandler(WidgetEvent::IMAGE_PRELOADED,
- WEAK_DELEGATE(Item::onImagePreloaded, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onImagePreloaded));
- m_btn.addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
- Item::onClicked, asWeak(*this)));
+ m_btn.addEventHandler(BTN_CLICKED,
+ WEAK_DELEGATE_THIS(onClicked));
m_touchParser = makeShared<TouchParser>(m_btn);
m_touchParser->setDoubleTapHandler(
- WEAK_DELEGATE(Item::onDoubleTap, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onDoubleTap));
m_touchParser->setTapAndHoldHandler(
- WEAK_DELEGATE(Item::onTapAndHold, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onTapAndHold));
}
Widget &getWidget()
if ((m_imageWidth <= 0) || (m_imageHeight <= 0)) {
setImageLoadSize(0);
- evas_object_image_file_set(m_image,
+ evas_object_image_file_set(as_eo(m_image),
params.imagePath.c_str(), NULL);
if (!impl::getImageSize(m_image,
}
} else {
- evas_object_image_file_set(m_image,
+ evas_object_image_file_set(as_eo(m_image),
params.imagePath.c_str(), NULL);
}
updateImageLoadSize();
- evas_object_image_preload(m_image, EINA_FALSE);
+ evas_object_image_preload(as_eo(m_image), EINA_FALSE);
}
void updateImageLoadSize()
void setImageLoadSize(const int newLoadSize)
{
m_imageLoadSize = newLoadSize;
- evas_object_image_load_size_set(m_image,
+ evas_object_image_load_size_set(as_eo(m_image),
newLoadSize, newLoadSize);
}
if (!m_bgImage) {
m_bgImage = makeShared<Widget>(
evas_object_image_filled_add(m_btn.getEvas()));
- evas_object_image_load_orientation_set(*m_bgImage,
+ evas_object_image_load_orientation_set(as_eo(*m_bgImage),
EINA_TRUE);
m_btn.setContent(*m_bgImage, impl::BTN_PART_BG);
show(*m_bgImage);
}
- evas_object_image_file_set(*m_bgImage,
+ evas_object_image_file_set(as_eo(*m_bgImage),
params.bgImagePath.c_str(), NULL);
m_bgImage->setARHint(WidgetARHint::NEITHER,
public:
Slot(ImageGrid &imageGrid, const bool isOdd) :
m_info(imageGrid.m_info),
- m_layout(elm_layout_add(imageGrid.m_box), true),
+ m_layout(elm_layout_add(as_eo(imageGrid.m_box)), true),
m_isRealized(false)
{
int imageMinLoadSize = 0;
} else if (imageGrid.m_isInSelectMode) {
m_layout.emit(impl::SIGNAL_FORCE_SELECT_MODE);
edje_object_message_signal_process(
- elm_layout_edje_get(m_layout));
+ elm_layout_edje_get(as_eo(m_layout)));
}
imageMinLoadSize = ELM_SCALE_SIZE(m_layout.getData(
impl::DATA_IMAGE_MIN_LOAD_SIZE).asInt());
m_info(getInfo(type)),
m_scroller(makeShared<StyledWidget>(scroller, false).get()),
- m_box(elm_box_add(*m_scroller)),
+ m_box(elm_box_add(scroller)),
m_rect1(evas_object_rectangle_add(m_box.getEvas())),
m_rect2(evas_object_rectangle_add(m_box.getEvas())),
m_circleScroller(nullptr),
if (m_animator) {
finalizeTransition();
}
- evas_object_event_callback_del_full(m_box, EVAS_CALLBACK_RESIZE,
+ evas_object_event_callback_del_full(as_eo(m_box), EVAS_CALLBACK_RESIZE,
CALLBACK_A(ImageGrid::onBoxResize), this);
}
void ImageGrid::prepare()
{
fill(m_rect1);
- elm_box_pack_end(m_box, m_rect1);
+ elm_box_pack_end(as_eo(m_box), as_eo(m_rect1));
makeTransparent(m_rect1);
show(m_rect1);
expandAndFill(m_rect2);
- elm_box_pack_end(m_box, m_rect2);
+ elm_box_pack_end(as_eo(m_box), as_eo(m_rect2));
makeTransparent(m_rect2);
show(m_rect2);
m_scroller->setContent(m_box);
- elm_box_horizontal_set(m_box, toEina(m_info.isHorizontal));
+ elm_box_horizontal_set(as_eo(m_box), toEina(m_info.isHorizontal));
show(m_box);
m_scroller->setStyle(SCROLLER_STYLE);
expandAndFill(*m_scroller);
if (m_info.isHorizontal) {
elm_scroller_page_scroll_limit_set(
- *m_scroller, m_info.scrollLimit, 0);
- elm_scroller_bounce_set(*m_scroller, EINA_TRUE, EINA_FALSE);
+ as_eo(*m_scroller), m_info.scrollLimit, 0);
+ elm_scroller_bounce_set(as_eo(*m_scroller), EINA_TRUE, EINA_FALSE);
} else {
elm_scroller_page_scroll_limit_set(
- *m_scroller, 0, m_info.scrollLimit);
- elm_scroller_bounce_set(*m_scroller, EINA_FALSE, EINA_TRUE);
+ as_eo(*m_scroller), 0, m_info.scrollLimit);
+ elm_scroller_bounce_set(as_eo(*m_scroller), EINA_FALSE, EINA_TRUE);
}
show(*m_scroller);
createCircleScroller();
m_scroller->addEventHandler(SmartEvent{"language,changed"},
- WEAK_DELEGATE(ImageGrid::onLanguageChanged, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onLanguageChanged));
m_scroller->addEventHandler(WidgetEvent::RESIZE,
- WEAK_DELEGATE(ImageGrid::onScrollerResize, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onScrollerResize));
m_scroller->addEventHandler(WidgetEvent::MOVE,
- WEAK_DELEGATE(ImageGrid::onScrollerMove, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onScrollerMove));
- m_box.addEventHandler(WidgetEvent::MOVE,
- WEAK_DELEGATE(ImageGrid::onBoxMove, asWeak(*this)));
+ m_box.addEventHandler(WidgetEvent::MOVE, WEAK_DELEGATE_THIS(onBoxMove));
- evas_object_event_callback_priority_add(m_box,
+ evas_object_event_callback_priority_add(as_eo(m_box),
EVAS_CALLBACK_RESIZE, EO_CALLBACK_PRIORITY_AFTER,
CALLBACK_A(ImageGrid::onBoxResize), this);
}
LOG_RETURN_VOID(RES_FAIL, "util::getCircleSurface() failed!");
}
- m_circleScroller = eext_circle_object_scroller_add(*m_scroller, sfc);
+ m_circleScroller = eext_circle_object_scroller_add(
+ as_eo(*m_scroller), sfc);
if (!m_circleScroller) {
LOG_RETURN_VOID(RES_FAIL,
"eext_circle_object_scroller_add() failed!");
m_isInSelectMode = enabled;
- elm_object_scroll_freeze_push(*m_scroller);
- evas_object_freeze_events_set(*m_scroller, EINA_TRUE);
+ elm_object_scroll_freeze_push(as_eo(*m_scroller));
+ evas_object_freeze_events_set(as_eo(*m_scroller), EINA_TRUE);
eext_rotary_object_event_activated_set(m_circleScroller, EINA_FALSE);
for (auto &slot: m_slots) {
auto &slotlayout = m_slots[m_beginSlotIndex & 1]->getLayout();
slotlayout.addEventHandler(WidgetEvent::CHANGED_SIZE_HINTS,
- WEAK_DELEGATE(ImageGrid::onSlotResize, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onSlotResize));
- elm_object_signal_callback_add(slotlayout,
+ elm_object_signal_callback_add(as_eo(slotlayout),
impl::SIGNAL_TRANSITION_FINISHED.name, "",
CALLBACK_A(ImageGrid::onTransitionFinished), this);
finalizeTransition();
- elm_object_scroll_freeze_pop(*m_scroller);
- evas_object_freeze_events_set(*m_scroller, EINA_FALSE);
+ elm_object_scroll_freeze_pop(as_eo(*m_scroller));
+ evas_object_freeze_events_set(as_eo(*m_scroller), EINA_FALSE);
if (m_isRotaryActive) {
eext_rotary_object_event_activated_set(m_circleScroller, EINA_TRUE);
}
auto &slotlayout = m_slots[m_beginSlotIndex & 1]->getLayout();
slotlayout.delEventHandler(WidgetEvent::CHANGED_SIZE_HINTS,
- WEAK_DELEGATE(ImageGrid::onSlotResize, asWeak(*this)));
+ DELEGATE_THIS(onSlotResize));
- elm_object_signal_callback_del(slotlayout,
+ elm_object_signal_callback_del(as_eo(slotlayout),
"gallery,transition,finished", "",
CALLBACK_A(ImageGrid::onTransitionFinished));
}
void ImageGrid::evalSlotSizes()
{
for (auto &slot: m_slots) {
- elm_layout_sizing_eval(slot->getLayout());
+ elm_layout_sizing_eval(as_eo(slot->getLayout()));
}
}
if (elm_config_mirrored_get()) {
int childSizeX = 0;
int childSizeY = 0;
- elm_scroller_child_size_get(*m_scroller, &childSizeX, &childSizeY);
+ elm_scroller_child_size_get(as_eo(*m_scroller),
+ &childSizeX, &childSizeY);
scrollOffset = ((m_info.isHorizontal ? childSizeX : childSizeY) -
m_scrollerSize - offset);
}
if (m_info.isHorizontal) {
- scrollFunc(*m_scroller, scrollOffset, 0, m_scrollerSize, 1);
+ scrollFunc(as_eo(*m_scroller), scrollOffset, 0, m_scrollerSize, 1);
} else {
- scrollFunc(*m_scroller, 0, scrollOffset, 1, m_scrollerSize);
+ scrollFunc(as_eo(*m_scroller), 0, scrollOffset, 1, m_scrollerSize);
}
}
for (int i = m_slotCount; i < newSlotCount; ++i) {
const bool isOdd = ((m_beginSlotIndex + i) & 1);
- auto slot = util::makeUnique(new Slot(*this, isOdd));
+ auto slot = util::wrapUnique(new Slot(*this, isOdd));
if (m_slotSize == 0) {
UCL_ASSERT(!isOdd, "Must be even!");
setSlotSize(slot->getSize());
}
- elm_box_pack_before(m_box, slot->getLayout(), m_rect2);
+ elm_box_pack_before(as_eo(m_box),
+ as_eo(slot->getLayout()), as_eo(m_rect2));
m_slots.emplace_back(std::move(slot));
}
m_slotSize = newSlotSize;
const int pageSize = (m_slotSize * m_info.slotsPerPage);
if (m_info.isHorizontal) {
- elm_scroller_page_size_set(*m_scroller, pageSize, 0);
+ elm_scroller_page_size_set(as_eo(*m_scroller), pageSize, 0);
} else {
- elm_scroller_page_size_set(*m_scroller, 0, pageSize);
+ elm_scroller_page_size_set(as_eo(*m_scroller), 0, pageSize);
}
}
int scrollerSizeX = 0;
int scrollerSizeY = 0;
- elm_scroller_region_get(*m_scroller, &scrollOffsetX, &scrollOffsetY,
+ elm_scroller_region_get(as_eo(*m_scroller),
+ &scrollOffsetX, &scrollOffsetY,
&scrollerSizeX, &scrollerSizeY);
if (elm_config_mirrored_get()) {
int childSizeX = 0;
int childSizeY = 0;
- elm_scroller_child_size_get(*m_scroller, &childSizeX, &childSizeY);
+ elm_scroller_child_size_get(as_eo(*m_scroller),
+ &childSizeX, &childSizeY);
scrollOffsetX = (childSizeX - scrollerSizeX - scrollOffsetX);
scrollOffsetY = (childSizeY - scrollerSizeY - scrollOffsetY);
for (int i = 0; i < count; ++i) {
SlotUPtr slot = std::move(m_slots.back());
m_slots.pop_back();
- elm_box_unpack(m_box, slot->getLayout());
- elm_box_pack_after(m_box, slot->getLayout(), m_rect1);
+ elm_box_unpack(as_eo(m_box), as_eo(slot->getLayout()));
+ elm_box_pack_after(as_eo(m_box),
+ as_eo(slot->getLayout()), as_eo(m_rect1));
m_slots.emplace_front(std::move(slot));
}
}
for (int i = 0; i < count; ++i) {
SlotUPtr slot = std::move(m_slots.front());
m_slots.pop_front();
- elm_box_unpack(m_box, slot->getLayout());
- elm_box_pack_before(m_box, slot->getLayout(), m_rect2);
+ elm_box_unpack(as_eo(m_box), as_eo(slot->getLayout()));
+ elm_box_pack_before(as_eo(m_box),
+ as_eo(slot->getLayout()), as_eo(m_rect2));
m_slots.emplace_back(std::move(slot));
}
}
TAP_AND_HOLD
};
- class IListener : public ucl::Polymorphic {
+ class IListener : protected ucl::NonCopyable {
public:
virtual void onItemRealized(int itemIndex) = 0;
virtual void onItemUnrealized(int itemIndex) = 0;
"m_highResPath is empty!");
}
- auto scroller = elm_scroller_add(parent);
+ auto scroller = elm_scroller_add(as_eo(parent));
if (!scroller) {
LOG_RETURN_VALUE(RES_FAIL, {}, "elm_scroller_add() failed!");
}
ElmWidget(&rc, scroller),
m_scroller(makeShared<StyledWidget>(scroller, false).get()),
- m_layout(elm_layout_add(*m_scroller)),
+ m_layout(elm_layout_add(as_eo(*m_scroller))),
m_grid(evas_object_grid_add(m_layout.getEvas())),
m_lowResImage(evas_object_image_filled_add(m_grid.getEvas())),
m_highResImage(evas_object_image_filled_add(m_grid.getEvas())),
{
expandAndFill(*m_scroller);
m_scroller->setStyle(SCROLLER_STYLE);
- elm_scroller_bounce_set(*m_scroller, EINA_TRUE, EINA_TRUE);
- elm_scroller_policy_set(*m_scroller,
+ elm_scroller_bounce_set(as_eo(*m_scroller), EINA_TRUE, EINA_TRUE);
+ elm_scroller_policy_set(as_eo(*m_scroller),
ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
- elm_scroller_single_direction_set(*m_scroller,
+ elm_scroller_single_direction_set(as_eo(*m_scroller),
ELM_SCROLLER_SINGLE_DIRECTION_NONE);
- elm_object_mirrored_automatic_set(*m_scroller, EINA_FALSE);
- elm_object_mirrored_set(*m_scroller, EINA_FALSE);
+ elm_object_mirrored_automatic_set(as_eo(*m_scroller), EINA_FALSE);
+ elm_object_mirrored_set(as_eo(*m_scroller), EINA_FALSE);
show(*m_scroller);
expandAndFill(m_layout);
m_scroller->setContent(m_layout);
show(m_layout);
- evas_object_grid_size_set(m_grid, 1, 1);
+ evas_object_grid_size_set(as_eo(m_grid), 1, 1);
m_layout.setContent(m_grid);
show(m_grid);
- evas_object_image_load_orientation_set(m_lowResImage, EINA_TRUE);
- evas_object_grid_pack(m_grid, m_lowResImage, 0, 0, 1, 1);
+ evas_object_image_load_orientation_set(as_eo(m_lowResImage), EINA_TRUE);
+ evas_object_grid_pack(as_eo(m_grid), as_eo(m_lowResImage), 0, 0, 1, 1);
if (loadSize > 0) {
- evas_object_image_load_size_set(m_lowResImage, loadSize, loadSize);
+ evas_object_image_load_size_set(
+ as_eo(m_lowResImage), loadSize, loadSize);
}
show(m_lowResImage);
makeTransparent(m_lowResImage);
- evas_object_image_load_orientation_set(m_highResImage, EINA_TRUE);
- evas_object_grid_pack(m_grid, m_highResImage, 0, 0, 1, 1);
+ evas_object_image_load_orientation_set(
+ as_eo(m_highResImage), EINA_TRUE);
+ evas_object_grid_pack(as_eo(m_grid), as_eo(m_highResImage), 0, 0, 1, 1);
if (forceLoad) {
if (loadSize > 0) {
- evas_object_image_load_size_set(m_highResImage,
+ evas_object_image_load_size_set(as_eo(m_highResImage),
loadSize, loadSize);
}
- evas_object_image_file_set(m_highResImage,
+ evas_object_image_file_set(as_eo(m_highResImage),
highResPath.c_str(), nullptr);
show(m_highResImage);
} else {
hide(m_highResImage);
m_highResImage.addEventHandler(WidgetEvent::IMAGE_PRELOADED,
- WEAK_DELEGATE(ImageViewer::onImagePreloaded,
- asWeak(*this)));
- evas_object_image_file_set(m_highResImage,
+ WEAK_DELEGATE_THIS(onImagePreloaded));
+ evas_object_image_file_set(as_eo(m_highResImage),
highResPath.c_str(), nullptr);
- evas_object_image_preload(m_highResImage, EINA_FALSE);
+ evas_object_image_preload(as_eo(m_highResImage), EINA_FALSE);
}
- evas_object_image_size_get(m_highResImage, &m_imageW, &m_imageH);
+ evas_object_image_size_get(as_eo(m_highResImage), &m_imageW, &m_imageH);
if ((m_imageW == 0) || (m_imageH == 0)) {
WLOG("Invalid image size!");
m_imageW = 1;
}
m_scroller->addEventHandler(WidgetEvent::RESIZE,
- WEAK_DELEGATE(ImageViewer::onScrollerResize, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onScrollerResize));
}
void ImageViewer::onScrollerResize(Widget &widget, void *eventInfo)
const int sx = std::lround((m_xf1 * m_gridW) - (xf2 * m_scrollerW));
const int sy = std::lround((m_yf1 * m_gridH) - (yf2 * m_scrollerH));
- elm_scroller_region_show(*m_scroller, sx, sy, m_scrollerW, m_scrollerH);
+ elm_scroller_region_show(as_eo(*m_scroller),
+ sx, sy, m_scrollerW, m_scrollerH);
}
void ImageViewer::setLowResImagePath(const std::string &path)
{
- evas_object_image_file_set(m_lowResImage, path.c_str(), nullptr);
+ evas_object_image_file_set(as_eo(m_lowResImage), path.c_str(), nullptr);
makeWhite(m_lowResImage);
}
int sx = 0;
int sy = 0;
- elm_scroller_region_get(*m_scroller, &sx, &sy, nullptr, nullptr);
+ elm_scroller_region_get(as_eo(*m_scroller),
+ &sx, &sy, nullptr, nullptr);
m_xf1 = (1.0 * (sx + newOriginX) / m_gridW);
m_yf1 = (1.0 * (sy + newOriginY) / m_gridH);
{
int sx = 0;
int sy = 0;
- elm_scroller_region_get(*m_scroller, &sx, &sy, nullptr, nullptr);
+ elm_scroller_region_get(as_eo(*m_scroller),
+ &sx, &sy, nullptr, nullptr);
if (m_gridW < m_scrollerW) {
sx = (0.5 * (m_gridW - m_scrollerW));
PageContent::PageContent(IRefCountObj &rc,
const LayoutSRef &layout, const int flags) :
- ElmWidget(&rc, *layout),
+ ElmWidget(&rc, as_eo(*layout)),
m_mainLayout(layout.get())
{
prepare(flags);
}
}
- Result PageContent::set(Evas_Object *const eo, const Part part)
+ Result PageContent::set(ucl::Widget &widget, const Part part)
{
return doWithPart(part,
- [eo](Layout &layout, const EdjePart part)
+ [&widget](Layout &layout, const EdjePart part)
{
- layout.setContent(eo, part);
+ layout.setContent(widget, part);
});
}
};
public:
- ucl::Result set(Evas_Object *eo, Part part = Part::DEFAULT);
+ ucl::Result set(ucl::Widget &widget, Part part = Part::DEFAULT);
Evas_Object *unset(Part part = Part::DEFAULT);
Evas_Object *get(Part part = Part::DEFAULT) const;
m_isTapPossible(false)
{
eventSource.addEventHandler(WidgetEvent::MOUSE_DOWN,
- WEAK_DELEGATE(TouchParser::onMouseDown, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onMouseDown));
eventSource.addEventHandler(WidgetEvent::MOUSE_UP,
- WEAK_DELEGATE(TouchParser::onMouseUp, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onMouseUp));
eventSource.addEventHandler(WidgetEvent::MOUSE_MOVE,
- WEAK_DELEGATE(TouchParser::onMouseMove, asWeak(*this)));
+ WEAK_DELEGATE_THIS(onMouseMove));
}
TouchParser::~TouchParser()
if (!isFastTap(e->timestamp, e->canvas.x, e->canvas.y)) {
m_tapCounter = 0;
restartHoldTimer();
- } else if (m_doubleTapHandler && (m_tapCounter == 1)) {
- m_doubleTapHandler(m_downX, m_downY);
+ } else if (m_tapCounter == 1) {
+ if (const auto handler = m_doubleTapHandler.lock()) {
+ handler(m_downX, m_downY);
+ }
}
m_downTime = e->timestamp;
++m_tapCounter;
- if (m_tapHandler) {
- m_tapHandler(e->canvas.x, e->canvas.y);
+ if (const auto handler = m_tapHandler.lock()) {
+ handler(e->canvas.x, e->canvas.y);
}
}
Eina_Bool TouchParser::onHoldTimer()
{
m_holdTimer = nullptr;
- if (m_tapAndHoldHandler) {
- m_tapAndHoldHandler(m_downX, m_downY);
+ if (const auto handler = m_tapAndHoldHandler.lock()) {
+ handler(m_downX, m_downY);
}
return ECORE_CALLBACK_CANCEL;
}
"Circle Surface data already set!");
}
- const auto sfc = eext_circle_surface_naviframe_add(navi);
+ const auto sfc = eext_circle_surface_naviframe_add(as_eo(navi));
if (!sfc) {
LOG_RETURN(RES_FAIL,
"eext_circle_surface_conformant_add() failed!");
UCL_DECLARE_REF_ALIASES(IInstance);
- class IInstance : public Polymorphic {
+ /**
+ * @brief Abstract interface for the application instances
+ * @details Instance is an object inside the application executable that
+ * represents it. UIApp may have only 1 instance per application.
+ * Other types of applications (widget) may have more that one
+ * instance (or none) in a single executable.
+ */
+ class IInstance : protected NonCopyable {
public:
+ /**
+ * @brief Called when instance is created.
+ * @details This function is called when instance gets created.
+ * Implementation must allocate all global resources in this
+ * function. For UIApp function called in app's "create" cb.
+ * @param[in] context Pointer to the context of this instance
+ * @return RES_OK on success,
+ * otherwise other result
+ */
virtual Result onCreate(IInstanceContext *context) = 0;
+
+ /**
+ * @brief Called when instance is paused
+ * @details For UIApp function called in app's "pause" cb.
+ */
virtual void onPause() = 0;
+
+ /**
+ * @brief Called when instance is resumed
+ * @details For UIApp function called in app's "resume" cb.
+ */
virtual void onResume() = 0;
+
+ protected:
+ /**
+ * @brief Destructor
+ * @details Deallocate all resources here
+ */
+ ~IInstance() = default;
};
}
namespace ucl {
- class IInstanceAppControlExt : public Polymorphic {
+ /**
+ * @brief Extension interface for instances that supports processing of app
+ * controll requests.
+ */
+ class IInstanceAppControlExt : protected NonCopyable {
public:
+ /**
+ * @brief Called to process an app control request.
+ * @details For UIApp function called in app's "app_control" cb.
+ * @param[in] appControl App control request to process
+ */
virtual void onAppControl(app_control_h appControl) = 0;
+
+ protected:
+ /**
+ * @brief Destructor
+ */
+ ~IInstanceAppControlExt() = default;
};
}
namespace ucl {
- class IInstanceContext : public Polymorphic {
+ /**
+ * @brief Abstract interface for the instance context.
+ * @details Instance context allows an instance to communicate with the
+ * application
+ */
+ class IInstanceContext : protected NonCopyable {
public:
+ /**
+ * @brief Gets type of the application
+ * @return The application type
+ */
virtual AppType getAppType() const = 0;
+
+ /**
+ * @brief Gets window of the instance
+ * @return Window object of the instance
+ */
virtual WindowSRef getWindow() = 0;
+
+ /**
+ * @brief Singals to the application to terminate
+ */
virtual void exitApp() = 0;
+
+ protected:
+ /**
+ * @brief Destructor
+ */
+ ~IInstanceContext() = default;
};
}
namespace ucl {
- class InstanceManagerBase : public Polymorphic {
+ /**
+ * @brief Base class for implementing instance manager
+ * @details Instance manager is class that is used by the application
+ * class (UIApp) to create instances.
+ */
+ class InstanceManagerBase : protected NonCopyable {
public:
- InstanceManagerBase(AppParams appParams);
- virtual ~InstanceManagerBase();
-
+ /**
+ * @brief Gets customization parameters for the application
+ * @return Reference to the parameters object
+ */
const AppParams &getAppParams() const;
+ /**
+ * @brief Stores systems event provider in the manager
+ * @param[in] provider Unique pointer to system event provider object
+ */
void setSysEventProvider(SysEventProviderUPtr provider);
+ /**
+ * @brief Creates new application instance object
+ * @return Shared reference to the new instance
+ */
virtual IInstanceSRef newInstance() const = 0;
protected:
+ /**
+ * @brief Constructor
+ * @param[in] appParams Customization parameters for the application
+ */
+ InstanceManagerBase(AppParams appParams);
+
+ /**
+ * @brief Destructor
+ */
+ ~InstanceManagerBase();
+
+ /**
+ * @brief Gets system event provider that was stored in the manager
+ * @details If system event provider was not stored before using this
+ * function runtime assert is performed
+ * @return Reference to the stored system event provider
+ */
SysEventProvider &getSysEventProvider() const;
private:
class SysEventProvider;
using SysEventProviderUPtr = std::unique_ptr<SysEventProvider>;
- class SysEventProvider final : public NonCopyable {
+ /**
+ * @brief Provider for system events.
+ */
+ class SysEventProvider final : protected NonCopyable {
public:
+ /**
+ * @brief Pointer to function that adds Tizen system event handler
+ */
using EventHandlerAddFunc = int (*)(app_event_handler_h *,
app_event_type_e, app_event_cb, void *);
+
+ /**
+ * @brief Pointer to function that deletes Tizen system event handler
+ */
using EventHandlerDelFunc = int (*)(app_event_handler_h);
public:
+ /**
+ * @brief Constructor
+ * @param[in] addFunc Tizen API for adding system event handler
+ * @param[in] delFunc Tizen API for deleting system event handler
+ */
SysEventProvider(EventHandlerAddFunc addFunc,
EventHandlerDelFunc delFunc);
+
+ /**
+ * @brief Destructor
+ */
~SysEventProvider();
- void addEventHandler(const SysEventHandler &handler);
- void delEventHandler(const SysEventHandler &handler);
+ /**
+ * @brief Registers system event handler
+ */
+ void addEventHandler(SysEventHandler handler);
+
+ /**
+ * @brief Deregisters system event handler
+ */
+ void delEventHandler(SysEventHandler::CDRef handler);
private:
int addEventHandler(app_event_handler_h *handler,
namespace ucl {
inline void SysEventProvider::addEventHandler(
- const SysEventHandler &handler)
+ SysEventHandler handler)
{
- m_event += handler;
+ m_event += std::move(handler);
}
inline void SysEventProvider::delEventHandler(
- const SysEventHandler &handler)
+ SysEventHandler::CDRef handler)
{
m_event -= handler;
}
namespace ucl {
+ /**
+ * @brief Represent Tizen UI application.
+ * @details Root object of any application.
+ */
class UIApp final : private IInstanceContext {
public:
+ /**
+ * @brief Constructor
+ * @param[in] instanceMgr Reference to the instance manager
+ */
UIApp(InstanceManagerBase &instanceMgr);
- virtual ~UIApp();
+ /**
+ * @brief Destructor
+ */
+ ~UIApp();
+
+ /**
+ * @brief Runs the application
+ * @details Must be run in the application "main()" function
+ * @param[in] argc Count of command line arguments
+ * (must be passed from "main()"")
+ * @param[in] argv Array of command line arguments
+ * (must be passed from "main()"")
+ * @return 0 on success,
+ * otherwise a negative error value
+ */
int run(int argc, char *argv[]);
private:
namespace ucl {
+ /**
+ * @brief Generates full path to the resource file.
+ * @param[in] relativePath Relative (to the "res" folder) path of the
+ * resource file (without leading "/")
+ * @return Full path to the resource file
+ */
std::string getResPath(const char *relativePath);
}
#include "ucl/misc/HashMap.h"
#include "ucl/misc/Event.h"
-#include "ucl/misc/AutoHandle.h"
+#include "ucl/misc/AutoObject.h"
namespace ucl {
+ /**
+ * @brief Enumeration of application types
+ */
enum class AppType {
UI,
WIDGET,
WATCH
};
+ /**
+ * @brief Defines keys for the application customization parameters
+ */
enum class AppParam {
BASE_SCALE,
- ACCELERATION_PREFERENECE,
+ ACCELERATION_PREFERENCE,
WINDOW_TYPE,
- WINDOW_NAME
+ WINDOW_NAME,
};
+ /**
+ * @brief Application customization parameters
+ */
using AppParams = HashMap<AppParam, Variant>;
+ /**
+ * @brief Enumeration of system events
+ */
enum class SysEvent {
LANGUAGE_CHANGED,
REGION_FMT_CHANGED,
UPDATE_REQUESTED
};
+ /**
+ * @brief Delegate to handle system events
+ */
using SysEventHandler = WeakDelegate<void(SysEvent)>;
- using AutoAppCtrl = AutoHandle<app_control_h, int, app_control_destroy>;
+ /**
+ * @brief Automatic handle to native Tizen app control
+ */
+ using AppCtrlAuto = AutoObject<app_control_h, int, app_control_destroy>;
}
#endif // __UCL_APPFW_TYPES_H__
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UCL_GUI_ATSPI_H__
+#define __UCL_GUI_ATSPI_H__
+
+#include "types.h"
+
+#include "ucl/misc/Event.h"
+
+namespace ucl {
+
+ UCL_DECLARE_REF_ALIASES(Atspi);
+
+ /**
+ * @brief Provides Accessibility interface
+ */
+ class Atspi final : private NonCopyable {
+ public:
+ /**
+ * @brief Gets the underlying Access object
+ * @param[in] atspi Reference to target atspi
+ * @return Pointer to the underlying Access object
+ */
+ friend Elm_Interface_Atspi_Accessible *as_ao(Atspi &atspi);
+
+ /**
+ * @brief Gets the underlying constant Access object
+ * @param[in] atspi Constant reference to target atspi
+ * @return Pointer to the underlying constant Access object
+ */
+ friend const Elm_Interface_Atspi_Accessible *as_ao(const Atspi &atspi);
+
+ public:
+ /**
+ * @brief Constructor
+ * @param[in] eo Underlying Access object of the Atspi
+ */
+ explicit Atspi(Elm_Interface_Atspi_Accessible *ao);
+
+ /**
+ * @brief Destructor
+ * @details Unregisters all Access object callbacks
+ */
+ ~Atspi();
+
+ /**
+ * @brief Sets name
+ * @param[in] name New name
+ */
+ void setName(const std::string &name);
+
+ /**
+ * @brief Gets name
+ * @return Current name
+ */
+ std::string getName() const;
+
+ /**
+ * @brief Sets name callback
+ * @param[in] cb name callback
+ */
+ void setNameCb(AtspiStringCb cb);
+
+ /**
+ * @brief Sets description
+ * @param[in] description New description
+ */
+ void setDescription(const std::string &description);
+
+ /**
+ * @brief Gets description
+ * @return Current description
+ */
+ std::string getDescription() const;
+
+ /**
+ * @brief Sets description callback
+ * @param[in] cb description callback
+ */
+ void setDescriptionCb(AtspiStringCb cb);
+
+ /**
+ * @brief Sets translation domain
+ * @param[in] domain New translation domain
+ */
+ void setTDomain(const std::string &domain);
+
+ /**
+ * @brief Gets translation domain
+ * @return Current translation domain
+ */
+ std::string getTDomain() const;
+
+ /**
+ * @brief Sets reding information type mask
+ * @param[in] info New reding information type mask
+ */
+ void setReadingInfo(Elm_Atspi_Reading_Info_Type_Mask info);
+
+ /**
+ * @brief Gets reding information type mask
+ * @return Current reding information type mask
+ */
+ Elm_Atspi_Reading_Info_Type_Mask getReadingInfo() const;
+
+ /**
+ * @brief Sets role
+ * @param[in] role New role
+ */
+ void setRole(Elm_Atspi_Role role);
+
+ /**
+ * @brief Gets role
+ * @return Current role
+ */
+ Elm_Atspi_Role getRole() const;
+
+ /**
+ * @brief Sets higlightability status
+ * @param[in] value New higlightability status
+ */
+ void setHighlightable(bool value);
+
+ /**
+ * @brief Gets higlightability status
+ * @return Current higlightability status
+ */
+ bool isHighlightable() const;
+
+ /**
+ * @brief Makes this Access object highlighted
+ */
+ void highlight();
+
+ /**
+ * @brief Makes this Access object not highlighted
+ */
+ void unhighlight();
+
+ /**
+ * @brief Adds new relationship
+ * @param[in] type Type of the new relationship
+ * @param[in] relation Pointer to relation Access object
+ */
+ void addRelationship(Elm_Atspi_Relation_Type type,
+ const Elm_Interface_Atspi_Accessible *relation);
+
+ /**
+ * @brief Deletes exiting relationship
+ * @param[in] type Type of the exiting relationship
+ * @param[in] relation Pointer to relation Access object,
+ * or NULL for all relations of the type (optional)
+ */
+ void delRelationship(Elm_Atspi_Relation_Type type,
+ const Elm_Interface_Atspi_Accessible *relation = nullptr);
+
+ /**
+ * @brief Deletes all exiting relationships
+ */
+ void clearRelationships();
+
+ /**
+ * @brief Registers gesture event handler
+ * @param[in] handler Handler of the event
+ */
+ void addGestureHandler(AtspiGestureHandler handler);
+
+ /**
+ * @brief Deregisters gesture event handler
+ * @param[in] handler Handler of the event
+ */
+ void delGestureHandler(const AtspiGestureHandler &handler);
+
+ private:
+ Elm_Interface_Atspi_Accessible *getAo();
+ const Elm_Interface_Atspi_Accessible *getAo() const;
+
+ void registerGestureCb();
+ void registerNameCb();
+ void registerDescriptionCb();
+
+ void unregisterGestureCb();
+ void unregisterNameCb();
+ void unregisterDescriptionCb();
+ void unregisterAllCallbacks();
+
+ Eina_Bool onAtspiGesture(
+ Elm_Atspi_Gesture_Info gestureInfo, Evas_Object *obj);
+ char *onAtspiNameCb(Evas_Object *obj);
+ char *onAtspiDescriptionCb(Evas_Object *obj);
+
+ private:
+ Elm_Interface_Atspi_Accessible *const m_ao;
+
+ Event<AtspiGestureHandler> m_onGesture;
+ AtspiStringCb m_nameCb;
+ AtspiStringCb m_descriptionCb;
+
+ bool m_isGestureCbRegistered;
+ bool m_isNameCbRegistered;
+ bool m_isDescriptionCbRegistered;
+ };
+
+ // Non-member functions //
+
+ /**
+ * @brief Gets Access object from pointed object
+ * @param[in] ptr Target object pointer
+ * @return Pointer to Access object or NULL
+ */
+ template <class T>
+ inline auto as_ao(const T &ptr) -> typename std::enable_if<
+ std::is_convertible<T, bool>::value, decltype(as_ao(*ptr))>::type
+ {
+ return (ptr ? as_ao(*ptr) : nullptr);
+ }
+
+ /**
+ * @brief Gets Access object from iterator
+ * @param[in] ptr Target object iterator
+ * @return Pointer to Access object or NULL
+ */
+ template <class T>
+ inline auto as_ao(const T &iter) -> typename std::enable_if<
+ !std::is_convertible<T, bool>::value, decltype(as_ao(*iter))>::type
+ {
+ return as_ao(*iter);
+ }
+
+ /**
+ * @brief Passes through original Access object pointer
+ * @param[in] ao Access object pointer
+ * @return Access object pointer
+ */
+ Elm_Interface_Atspi_Accessible *as_ao(Elm_Interface_Atspi_Accessible *ao);
+
+ /**
+ * @brief Passes through original constant Access object pointer
+ * @param[in] ao Constant Access object pointer
+ * @return Constant Access object pointer
+ */
+ const Elm_Interface_Atspi_Accessible *as_ao(
+ const Elm_Interface_Atspi_Accessible *ao);
+}
+
+#include "Atspi.hpp"
+
+#endif // __UCL_GUI_ATSPI_H__
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucl/util/helpers.h"
+#include "ucl/util/logging.h"
+
+namespace ucl {
+
+ inline Atspi::Atspi(Elm_Interface_Atspi_Accessible *const ao) :
+ m_ao(ao),
+ m_isGestureCbRegistered(false),
+ m_isNameCbRegistered(false),
+ m_isDescriptionCbRegistered(false)
+ {
+ UCL_ASSERT(ao, "ao is NULL");
+ }
+
+ inline Atspi::~Atspi()
+ {
+ unregisterAllCallbacks();
+ }
+
+ inline Elm_Interface_Atspi_Accessible *Atspi::getAo()
+ {
+ return m_ao;
+ }
+
+ inline const Elm_Interface_Atspi_Accessible *Atspi::getAo() const
+ {
+ return m_ao;
+ }
+
+ inline void Atspi::setName(const std::string &name)
+ {
+ elm_atspi_accessible_name_set(getAo(), name.c_str());
+ }
+
+ inline std::string Atspi::getName() const
+ {
+ return nz(elm_atspi_accessible_name_get(getAo()));
+ }
+
+ inline void Atspi::setNameCb(AtspiStringCb cb)
+ {
+ if (cb) {
+ registerNameCb();
+ }
+ m_nameCb = std::move(cb);
+ }
+
+ inline void Atspi::setDescription(const std::string &description)
+ {
+ elm_atspi_accessible_description_set(getAo(), description.c_str());
+ }
+
+ inline std::string Atspi::getDescription() const
+ {
+ return nz(elm_atspi_accessible_description_get(getAo()));
+ }
+
+ inline void Atspi::setDescriptionCb(AtspiStringCb cb)
+ {
+ if (cb) {
+ registerDescriptionCb();
+ }
+ m_descriptionCb = std::move(cb);
+ }
+
+ inline void Atspi::setTDomain(const std::string &domain)
+ {
+ elm_atspi_accessible_translation_domain_set(getAo(), domain.c_str());
+ }
+
+ inline std::string Atspi::getTDomain() const
+ {
+ return nz(elm_atspi_accessible_translation_domain_get(getAo()));
+ }
+
+ inline void Atspi::setReadingInfo(
+ const Elm_Atspi_Reading_Info_Type_Mask info)
+ {
+ elm_atspi_accessible_reading_info_type_set(getAo(), info);
+ }
+
+ inline Elm_Atspi_Reading_Info_Type_Mask Atspi::getReadingInfo() const
+ {
+ return elm_atspi_accessible_reading_info_type_get(getAo());
+ }
+
+ inline void Atspi::setRole(const Elm_Atspi_Role role)
+ {
+ elm_atspi_accessible_role_set(getAo(), role);
+ }
+
+ inline Elm_Atspi_Role Atspi::getRole() const
+ {
+ return elm_atspi_accessible_role_get(getAo());
+ }
+
+ inline void Atspi::setHighlightable(const bool value)
+ {
+ elm_atspi_accessible_can_highlight_set(getAo(), toEina(value));
+ }
+
+ inline bool Atspi::isHighlightable() const
+ {
+ return elm_atspi_accessible_can_highlight_get(getAo());
+ }
+
+ inline void Atspi::highlight()
+ {
+ elm_atspi_component_highlight_grab(getAo());
+ }
+
+ inline void Atspi::unhighlight()
+ {
+ elm_atspi_component_highlight_clear(getAo());
+ }
+
+ inline void Atspi::addRelationship(const Elm_Atspi_Relation_Type type,
+ const Elm_Interface_Atspi_Accessible *const relation)
+ {
+ elm_atspi_accessible_relationship_append(getAo(), type, relation);
+ }
+
+ inline void Atspi::delRelationship(const Elm_Atspi_Relation_Type type,
+ const Elm_Interface_Atspi_Accessible *const relation)
+ {
+ elm_atspi_accessible_relationship_remove(getAo(), type, relation);
+ }
+
+ inline void Atspi::clearRelationships()
+ {
+ elm_atspi_accessible_relationships_clear(getAo());
+ }
+
+ inline void Atspi::addGestureHandler(AtspiGestureHandler handler)
+ {
+ if (handler) {
+ registerGestureCb();
+ m_onGesture += std::move(handler);
+ }
+ }
+
+ inline void Atspi::delGestureHandler(const AtspiGestureHandler &handler)
+ {
+ m_onGesture -= handler;
+ }
+
+ inline void Atspi::registerGestureCb()
+ {
+ if (!m_isGestureCbRegistered) {
+ m_isGestureCbRegistered = true;
+ elm_atspi_accessible_gesture_cb_set(m_ao,
+ UCL_CALLBACK_A(Atspi::onAtspiGesture), this);
+ }
+ }
+
+ inline void Atspi::registerNameCb()
+ {
+ if (!m_isNameCbRegistered) {
+ m_isNameCbRegistered = true;
+ elm_atspi_accessible_name_cb_set(m_ao,
+ UCL_CALLBACK_A(Atspi::onAtspiNameCb), this);
+ }
+ }
+
+ inline void Atspi::registerDescriptionCb()
+ {
+ if (!m_isDescriptionCbRegistered) {
+ m_isDescriptionCbRegistered = true;
+ elm_atspi_accessible_description_cb_set(m_ao,
+ UCL_CALLBACK_A(Atspi::onAtspiDescriptionCb), this);
+ }
+ }
+
+ inline void Atspi::unregisterGestureCb()
+ {
+ if (m_isGestureCbRegistered) {
+ m_isGestureCbRegistered = false;
+ elm_atspi_accessible_gesture_cb_set(m_ao, nullptr, nullptr);
+ }
+ }
+
+ inline void Atspi::unregisterNameCb()
+ {
+ if (m_isNameCbRegistered) {
+ m_isNameCbRegistered = false;
+ elm_atspi_accessible_name_cb_set(m_ao, nullptr, nullptr);
+ }
+ }
+
+ inline void Atspi::unregisterDescriptionCb()
+ {
+ if (m_isDescriptionCbRegistered) {
+ m_isDescriptionCbRegistered = false;
+ elm_atspi_accessible_description_cb_set(m_ao, nullptr, nullptr);
+ }
+ }
+
+ inline void Atspi::unregisterAllCallbacks()
+ {
+ unregisterGestureCb();
+ unregisterNameCb();
+ unregisterDescriptionCb();
+ }
+
+ inline Eina_Bool Atspi::onAtspiGesture(
+ Elm_Atspi_Gesture_Info gestureInfo, Evas_Object *obj)
+ {
+ AtspiGestureEventInfo eventInfo{gestureInfo};
+ m_onGesture.dispatchPred(
+ [&eventInfo]() { return !eventInfo.stopPropagation; },
+ *this, eventInfo);
+ return toEina(eventInfo.preventDefault);
+ }
+
+ inline char *Atspi::onAtspiNameCb(Evas_Object *obj)
+ {
+ if (const auto cb = m_nameCb.lock()) {
+ return cb(*this).release();
+ }
+ return nullptr;
+ }
+
+ inline char *Atspi::onAtspiDescriptionCb(Evas_Object *obj)
+ {
+ if (const auto cb = m_descriptionCb.lock()) {
+ return cb(*this).release();
+ }
+ return nullptr;
+ }
+
+ // Non-member functions //
+
+ inline Elm_Interface_Atspi_Accessible *as_ao(Atspi &atspi)
+ {
+ return atspi.m_ao;
+ }
+
+ inline const Elm_Interface_Atspi_Accessible *as_ao(const Atspi &atspi)
+ {
+ return atspi.m_ao;
+ }
+
+ inline Elm_Interface_Atspi_Accessible *as_ao(
+ Elm_Interface_Atspi_Accessible *const ao)
+ {
+ return ao;
+ }
+
+ inline const Elm_Interface_Atspi_Accessible *as_ao(
+ const Elm_Interface_Atspi_Accessible *const ao)
+ {
+ return ao;
+ }
+}
UCL_DECLARE_REF_ALIASES(EdjeWidget);
+ /**
+ * @brief Base class for all widgets that has Edje theme
+ */
class EdjeWidget : public ElmWidget {
public:
+ /**
+ * @brief Sets text to default part
+ * @param[in] value Translatable text value to set
+ */
void setText(const TString &value);
+
+ /**
+ * @brief Sets text to specific part
+ * @param[in] value Translatable text value to set
+ * @param[in] part Destination Edje part
+ */
void setText(const TString &value, EdjePart part);
- TString getText() const;
- TString getText(EdjePart part) const;
+ /**
+ * @brief Gets text from default part
+ * @return Translated text from default part
+ */
+ std::string getText() const;
+
+ /**
+ * @brief Gets text from specific part
+ * @param[in] part Source Edje part
+ * @return Translated text from specific part
+ */
+ std::string getText(EdjePart part) const;
+
+ /**
+ * @brief Sets content to default part
+ * @param[in] content Content widget
+ */
+ void setContent(Widget &content);
- void setContent(Evas_Object *content);
- void setContent(Evas_Object *content, EdjePart part);
+ /**
+ * @brief Sets content to specific part
+ * @param[in] content Content widget
+ * @param[in] part Destination Edje part
+ */
+ void setContent(Widget &content, EdjePart part);
+
+ /**
+ * @brief Unsets content from default part
+ * @return Content Evas object or NULL
+ */
Evas_Object *unsetContent();
+
+ /**
+ * @brief Unsets content from specific part
+ * @param[in] part Source Edje part
+ * @return content Evas object or NULL
+ */
Evas_Object *unsetContent(EdjePart part);
+ /**
+ * @brief Gets content from default part
+ * @return Content Evas object or NULL
+ */
Evas_Object *getContent() const;
+
+ /**
+ * @brief Gets content from specific part
+ * @param[in] part Source Edje part
+ * @return content Evas object or NULL
+ */
Evas_Object *getContent(EdjePart part) const;
+ /**
+ * @brief Emits signal to the widget's Edje theme
+ * @param[in] signal Emitted signal
+ * @param[in] signal Emitted signal source (optional)
+ */
void emit(EdjeSignal signal, EdjeSignalSrc source =
EdjeSignalSrc(""));
protected:
+ /**
+ * @brief Constructor
+ * @param[in] rc Pointer to IRefCountObj (passed automatically)
+ * @param[in] eo Underlying Evas object of the widget
+ * @param[in] isOwner Evas object ownership flag (optional: true)
+ */
EdjeWidget(IRefCountObj *rc, Evas_Object *eo, bool isOwner = true);
};
}
{
}
- inline TString EdjeWidget::getText() const
+ inline std::string EdjeWidget::getText() const
{
return elm_object_text_get(getEo());
}
- inline TString EdjeWidget::getText(const EdjePart part) const
+ inline std::string EdjeWidget::getText(const EdjePart part) const
{
return elm_object_part_text_get(getEo(), part.name);
}
- inline void EdjeWidget::setContent(Evas_Object *const content)
+ inline void EdjeWidget::setContent(Widget &content)
{
- elm_object_content_set(getEo(), content);
+ elm_object_content_set(getEo(), as_eo(content));
}
- inline void EdjeWidget::setContent(Evas_Object *const content,
+ inline void EdjeWidget::setContent(Widget &content,
const EdjePart part)
{
- elm_object_part_content_set(getEo(), part.name, content);
+ elm_object_part_content_set(getEo(), part.name, as_eo(content));
}
inline Evas_Object *EdjeWidget::unsetContent()
#define __UCL_GUI_ELM_WIDGET_H__
#include "Widget.h"
-
-#define UCL_SMART_FWD_ATSPI UCL_SMART_FWD "atspi,"
+#include "Atspi.h"
namespace ucl {
- constexpr SmartEvent ATSPI_ON_GESTURE {UCL_SMART_FWD_ATSPI "gesture"};
-
class Window;
UCL_DECLARE_REF_ALIASES(ElmWidget);
+ /**
+ * @brief Represents Elementary widget and serves as base class for more
+ * concrete widget types
+ */
class ElmWidget : public Widget {
public:
- explicit ElmWidget(Evas_Object *eo, bool isOwner = true);
- virtual ~ElmWidget();
-
+ using Widget::Widget;
+
+ /**
+ * @brief Gets Atspi of this widget
+ * @return Reference to the Atspi object
+ */
+ Atspi &getAtspi();
+
+ /**
+ * @brief Gets Atspi of this widget (constant version)
+ * @return Reference to the constant Atspi object
+ */
+ Atspi &getAtspi() const;
+
+ /**
+ * @brief Sets enabled state of the widget
+ * @param[in] value New state
+ */
void setEnabled(bool value);
- bool isEnabled() const;
- void setFocusAlowed(bool value);
- bool isFocusAlowed() const;
+ /**
+ * @brief Gets enabled state of the widget
+ * @return true if enabled, false if disabled
+ */
+ bool isEnabled() const;
+ /**
+ * @brief Sets if key-input focus is allowed for the widget
+ * @param[in] value New state
+ */
+ void setFocusAllowed(bool value);
+
+ /**
+ * @brief Gets if key-input focus is allowed for the widget
+ * @return true if allowed, false if not allowed
+ */
+ bool isFocusAllowed() const;
+
+ /**
+ * @brief Sets theme object to the widget
+ * @details This function does not affect look of this widget directly,
+ * instead it makes all styles from Theme visible to this
+ * widget and all it's children.
+ * @param[in] th Theme object to set
+ */
void setTheme(Elm_Theme *th);
+
+ /**
+ * @brief Gets theme object that assigned to the widget
+ * @return Assigned Theme object
+ */
Elm_Theme *getTheme();
+ /**
+ * @brief Gets top level parent of the widget
+ * @return Top level Evas object
+ */
Evas_Object *getTopWidget() const;
+
+ /**
+ * @brief Tries to get top level parent of the widget as Window widget
+ * @return Window widget or NULL
+ */
Window *getWindow() const;
protected:
- friend class ReffedObj<ElmWidget>;
- ElmWidget(IRefCountObj *rc, Evas_Object *eo, bool isOwner = true);
+ // Widget //
virtual void setFocusedImpl(bool value) final override;
virtual bool isFocusedImpl() const final override;
- virtual bool ensureFwdEvent(SmartEvent fwdEvent) override;
private:
- Eina_Bool onAtspiGesture(Elm_Atspi_Gesture_Info gestureInfo,
- Evas_Object *obj);
+ void ensureAtspi();
private:
- bool m_isAtspiGestureCbSet;
+ AtspiSRef m_atspi;
+
+ friend class ReffedObj<ElmWidget>;
};
// Non-member functions //
+ /**
+ * @brief Gets corresponding Access object
+ * @param[in] widget Reference to target widget
+ * @return Pointer to the corresponding Access object
+ */
+ Elm_Interface_Atspi_Accessible *as_ao(ElmWidget &widget);
+
+ /**
+ * @brief Gets corresponding constant Access object
+ * @param[in] widget Constant reference to target widget
+ * @return Pointer to the corresponding constant Access object
+ */
+ const Elm_Interface_Atspi_Accessible *as_ao(const ElmWidget &widget);
+
+ /**
+ * @brief Sets widget to enabled state
+ * @details This is equivalent to: widget.setEnabled(true);
+ * @param[in] widget Reference to target widget
+ */
void enable(ElmWidget &widget);
+
+ /**
+ * @brief Sets widget to disabled state
+ * @details This is equivalent to: widget.setEnabled(false);
+ * @param[in] widget Reference to target widget
+ */
void disable(ElmWidget &widget);
}
namespace ucl {
- inline ElmWidget::ElmWidget(Evas_Object *const eo, const bool isOwner) :
- ElmWidget(nullptr, eo, isOwner)
+ inline Atspi &ElmWidget::getAtspi()
{
+ ensureAtspi();
+ return *m_atspi;
+ }
+
+ inline Atspi &ElmWidget::getAtspi() const
+ {
+ // Need cast for lazy initialization. Can't use mutable.
+ const_cast<ElmWidget *>(this)->ensureAtspi();
+ return *m_atspi;
+ }
+
+ inline void ElmWidget::ensureAtspi()
+ {
+ if (!m_atspi) {
+ m_atspi = makeShared<Atspi>(getEo());
+ }
}
inline void ElmWidget::setEnabled(const bool value)
return !elm_object_disabled_get(getEo());
}
- inline void ElmWidget::setFocusAlowed(const bool value)
+ inline void ElmWidget::setFocusAllowed(const bool value)
{
elm_object_focus_allow_set(getEo(), toEina(value));
}
- inline bool ElmWidget::isFocusAlowed() const
+ inline bool ElmWidget::isFocusAllowed() const
{
return elm_object_focus_allow_get(getEo());
}
// Non-member functions //
+ inline Elm_Interface_Atspi_Accessible *as_ao(ElmWidget &widget)
+ {
+ return as_ao(widget.getAtspi());
+ }
+
+ inline const Elm_Interface_Atspi_Accessible *as_ao(const ElmWidget &widget)
+ {
+ return as_ao(widget.getAtspi());
+ }
+
inline void enable(ElmWidget &widget)
{
widget.setEnabled(true);
UCL_DECLARE_REF_ALIASES(Layout);
+ /**
+ * @brief Represents Elementary Layout widget
+ */
class Layout : public EdjeWidget {
public:
+ /**
+ * @brief Builder of Layout objects
+ */
class Builder final {
public:
+ /**
+ * @brief Constructor
+ */
Builder();
+
+ /**
+ * @brief Sets layout theme of the future object
+ * @details EdjeFile property takes precedence over this property
+ * if both are set.
+ * @param[in] value Layout of the future object
+ * @return Reference to this builder
+ */
Builder &setTheme(const LayoutTheme &value);
+
+ /**
+ * @brief Sets edje file and group of the future object
+ * @details This property takes precedence over Theme property
+ * if both are set.
+ * @param[in] filePath Path to the Edje file
+ * @param[in] group Edje group to apply to the future object
+ * @return Reference to this builder
+ */
Builder &setEdjeFile(std::string filePath, EdjeGroup group);
+
+ /**
+ * @brief Sets Evas object ownership flag of the future object
+ * @param[in] value true if owner, false - otherwise
+ * @return Reference to this builder
+ */
Builder &setIsOwner(bool value);
+
+ /**
+ * @brief Sets if future object needs to be bind to it's Evas object
+ * @param[in] value true if need to bind, false - otherwise
+ * @return Reference to this builder
+ */
Builder &setNeedBindToEo(bool value);
+
+ /**
+ * @brief Creates new Layout object using current parameters
+ * @param[in] parent Reference to parent widget
+ * @return Shared reference to new Layout object or NULL
+ */
LayoutSRef build(ElmWidget &parent) const;
+
private:
LayoutTheme m_theme;
std::string m_edjeFilePath;
};
public:
- friend class ReffedObj<Layout>;
- using EdjeWidget::EdjeWidget;
+ using ElmWidget::setTheme;
+
+ /**
+ * @brief Constructor
+ * @param[in] eo Underlying Elementary Layout Evas object
+ * @param[in] isOwner Evas object ownership flag (optional: true)
+ */
explicit Layout(Evas_Object *eo, bool isOwner = true);
+ /**
+ * @brief Applies LayoutTheme to the layout
+ * @param[in] theme LayoutTheme to apply
+ * @return true on success, false on failure
+ */
bool setTheme(const LayoutTheme &theme);
+
+ /**
+ * @brief Applies edje file and group to the layout
+ * @param[in] filePath Path to the Edje file
+ * @param[in] group Edje group to apply to the layout
+ * @return true on success, false on failure
+ */
bool setEdjeFile(const std::string &filePath, EdjeGroup group);
+ /**
+ * @brief Gets data from Edje theme applied to the layout
+ * @param[in] key Edje data key of the data
+ * @return TYPE_STRING Variant value of the Edje data,
+ * or TYPE_NIL if not found
+ */
Variant getData(EdjeDataKey key);
+
+ protected:
+ using EdjeWidget::EdjeWidget;
+
+ private:
+ friend class ReffedObj<Layout>;
};
}
namespace ucl {
+ /**
+ * @brief Represents Elementary Naviframe widget item
+ * @details This class has semantic of a pointer and therefore does not
+ * manage lifetime of the item. Pointer is always point to the non
+ * constant Naviframe item. Most of the methods marked as const
+ * because pointer is not changed in these method calls.
+ */
class NaviItem final : public WidgetItem {
public:
+ /**
+ * @brief Delegate for handling naviframe item pop event
+ */
using PopHandler = Delegate<Eina_Bool(Elm_Object_Item *)>;
public:
using WidgetItem::WidgetItem;
- void setPopHandler(const PopHandler &handler) const;
+ /**
+ * @brief Registers item pop handler
+ * @param[in] handler Handler delegate
+ */
+ void setPopHandler(PopHandler handler) const;
+ /**
+ * @brief Pops all items of the naviframe state to this item
+ */
void popTo() const;
+
+ /**
+ * @brief Moves this naviframe item to the top of the naviframe stack
+ */
void promote() const;
+ /**
+ * @brief Sets naviframe item tile visibility state
+ * @param[in] value Visibility state. true - visible, false - invisible
+ * @param[in] useTransition Title show/hide transition animation flag.
+ * true - use transition animation, false - no transition.
+ */
void setTitleEnabled(bool value, bool useTransition = false) const;
+
+ /**
+ * @brief Gets naviframe item tile visibility state
+ * @retrun Visibility state. true - visible, false - invisible
+ */
bool isTitleEnabled() const;
+ /**
+ * @brief Sets naviframe item tile text
+ * @param[in] title Translatable text to use as a title
+ */
void setTitle(const TString &title) const;
};
}
namespace ucl {
- inline void NaviItem::setPopHandler(const PopHandler &handler) const
+ inline void NaviItem::setPopHandler(const PopHandler handler) const
{
elm_naviframe_item_pop_cb_set(getIt(),
handler.getStubA(), handler.getData());
inline void NaviItem::setTitle(const TString &title) const
{
- if (isEmpty(title)) {
- setTitleEnabled(false);
- } else {
- setText(title);
- setTitleEnabled(true);
- }
+ setText(title);
}
}
UCL_DECLARE_REF_ALIASES(Naviframe);
+ /**
+ * @brief Represents Elementary Naviframe widget
+ */
class Naviframe final : public StyledWidget {
public:
+ /**
+ * @brief Builder of Naviframe objects
+ */
class Builder final {
public:
+ /**
+ * @brief Constructor
+ */
Builder();
+
+ /**
+ * @brief Sets style of the future object
+ * @param[in] style Style of the future object
+ * @return Reference to this builder
+ */
Builder &setStyle(ElmStyle value);
+
+ /**
+ * @brief Sets if future object needs to be bind to it's Evas object
+ * @param[in] value true if need to bind, false - otherwise
+ * @return Reference to this builder
+ */
Builder &setNeedBindToEo(bool value);
+
+ /**
+ * @brief Creates new Naviframe object using current parameters
+ * @param[in] parent Reference to parent widget
+ * @return Shared reference to new Naviframe object or NULL
+ */
NaviframeSRef build(ElmWidget &parent) const;
+
private:
ElmStyle m_style;
bool m_needBindToEo;
};
public:
+ /**
+ * @brief Sets transition state of naviframe
+ * @details Warning! It is workaround function for internal use only.
+ * TODO Need to remove when page manager will be implemented.
+ * @param[in] inTransition true if in transition, false - otherwise
+ */
void setInTransition(bool inTransition);
+
+ /**
+ * @brief Gets current transition state of naviframe
+ * @details Warning! It is workaround function for internal use only.
+ * TODO Need to remove when page manager will be implemented.
+ * @return true if in transition, false - otherwise
+ */
bool isInTransition() const;
+ /**
+ * @brief Sets if back button should be automatically created in
+ * items on push
+ * @param[in] value true if need create, false - otherwise
+ */
void setAutoBackBtn(bool value);
+
+ /**
+ * @brief Gets if back button will be automatically created in
+ * items on push
+ * @return true if will be created, false - otherwise
+ */
bool isAutoBackBtn() const;
+ /**
+ * @brief Sets if item content should be preserved on pop
+ * @param[in] value true if need preserve, false - otherwise
+ */
void setPreservePop(bool value);
+
+ /**
+ * @brief Gets if item content will be preserved on pop
+ * @return true if will be preserve, false - otherwise
+ */
bool isPreservePop() const;
+ /**
+ * @brief Sets if events should be processed by naviframe
+ * on item transition
+ * @param[in] value true if need to process events, false - otherwise
+ */
void setEventsEnabledOnTransition(bool value);
+
+ /**
+ * @brief Gets if events will be processed by naviframe
+ * on item transition
+ * @return true if will be process events, false - otherwise
+ */
bool isEventsEnabledOnTransition() const;
+ /**
+ * @brief Pops and then deletes topmost item from stack with transition
+ * @return Preserved content of the popped item or NULL
+ */
Evas_Object *pop();
- NaviItem push(const TString &title,
- Evas_Object *backBtn, Evas_Object *moreBtn,
- Evas_Object *content, ElmStyle style = nullptr);
- NaviItem push(const TString &title,
- Evas_Object *content, ElmStyle style = nullptr);
- NaviItem push(Evas_Object *content, ElmStyle style = nullptr);
+ /**
+ * @brief Pushes new item to the naviframe stack
+ * @param[in] title Translatable item title (may be empty)
+ * @param[in] content Content of the item
+ * @param[in] backBtn Back button widget pointer (may be NULL)
+ * @param[in] moreBtn More button widget pointer (may be NULL)
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
+ NaviItem push(const TString &title, Widget &content,
+ Widget *backBtn, Widget *moreBtn,
+ ElmStyle style = nullptr);
+
+ /**
+ * @brief Pushes new item to the naviframe stack
+ * @param[in] title Translatable item title (may be empty)
+ * @param[in] content Content of the item
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
+ NaviItem push(const TString &title, Widget &content,
+ ElmStyle style = nullptr);
+
+ /**
+ * @brief Pushes new item to the naviframe stack
+ * @param[in] content Content of the item
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
+ NaviItem push(Widget &content, ElmStyle style = nullptr);
+ /**
+ * @brief Pushes new item to the naviframe stack
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
+ NaviItem push(ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack after specific item
+ * @param[in] after Item after which future item will be inserted
+ * @param[in] title Translatable item title (may be empty)
+ * @param[in] content Content of the item
+ * @param[in] backBtn Back button widget pointer (may be NULL)
+ * @param[in] moreBtn More button widget pointer (may be NULL)
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
NaviItem insertAfter(NaviItem after, const TString &title,
- Evas_Object *backBtn, Evas_Object *moreBtn,
- Evas_Object *content, ElmStyle style = nullptr);
+ Widget &content, Widget *backBtn, Widget *moreBtn,
+ ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack after specific item
+ * @param[in] after Item after which future item will be inserted
+ * @param[in] title Translatable item title (may be empty)
+ * @param[in] content Content of the item
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
NaviItem insertAfter(NaviItem after, const TString &title,
- Evas_Object *content, ElmStyle style = nullptr);
+ Widget &content, ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack after specific item
+ * @param[in] after Item after which future item will be inserted
+ * @param[in] content Content of the item
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
NaviItem insertAfter(NaviItem after,
- Evas_Object *content, ElmStyle style = nullptr);
+ Widget &content, ElmStyle style = nullptr);
+ /**
+ * @brief Inserts new item to the naviframe stack after specific item
+ * @param[in] after Item after which future item will be inserted
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
+ NaviItem insertAfter(NaviItem after, ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack before specific item
+ * @param[in] before Item before which future item will be inserted
+ * @param[in] title Translatable item title (may be empty)
+ * @param[in] content Content of the item
+ * @param[in] backBtn Back button widget pointer (may be NULL)
+ * @param[in] moreBtn More button widget pointer (may be NULL)
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
NaviItem insertBefore(NaviItem before, const TString &title,
- Evas_Object *backBtn, Evas_Object *moreBtn,
- Evas_Object *content, ElmStyle style = nullptr);
+ Widget &content, Widget *backBtn, Widget *moreBtn,
+ ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack before specific item
+ * @param[in] before Item before which future item will be inserted
+ * @param[in] title Translatable item title (may be empty)
+ * @param[in] content Content of the item
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
NaviItem insertBefore(NaviItem before, const TString &title,
- Evas_Object *content, ElmStyle style = nullptr);
+ Widget &content, ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack before specific item
+ * @param[in] before Item before which future item will be inserted
+ * @param[in] content Content of the item
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
NaviItem insertBefore(NaviItem before,
- Evas_Object *content, ElmStyle style = nullptr);
+ Widget &content, ElmStyle style = nullptr);
+
+ /**
+ * @brief Inserts new item to the naviframe stack before specific item
+ * @param[in] before Item before which future item will be inserted
+ * @param[in] style Elm style of the item (optional)
+ * @return New item
+ */
+ NaviItem insertBefore(NaviItem before, ElmStyle style = nullptr);
+ /**
+ * @brief Gets top item of the naviframe stack
+ * @return Top item
+ */
NaviItem getTopItem()const;
+
+ /**
+ * @brief Gets bottom item of the naviframe stack
+ * @return Bottom item
+ */
NaviItem getBottomItem() const;
+
+ /**
+ * @brief Gets all items of the naviframe stack
+ * @return Items vector
+ */
std::vector<NaviItem> getItems() const;
private:
- friend class ReffedObj<Naviframe>;
- Naviframe(IRefCountObj &rc, Evas_Object *eo);
+ Naviframe(IRefCountObj &rc, Evas_Object *eo, Private);
+
+ NaviItem push(const TString &title,
+ Widget *content, Widget *backBtn, Widget *moreBtn,
+ ElmStyle style);
+
+ NaviItem insertAfter(NaviItem after, const TString &title,
+ Widget *content, Widget *backBtn, Widget *moreBtn,
+ ElmStyle style);
+
+ NaviItem insertBefore(NaviItem before, const TString &title,
+ Widget *content, Widget *backBtn, Widget *moreBtn,
+ ElmStyle style);
void onTransitionFinished(Widget &widget, void *eventInfo);
private:
bool m_isInTransition;
+
+ friend class ReffedObj<Naviframe>;
};
}
* limitations under the License.
*/
+namespace ucl { namespace himpl {
+
+ inline void initItemTitle(const NaviItem item, const TString &title)
+ {
+ if (isEmpty(title)) {
+ item.setTitleEnabled(false);
+ } else {
+ item.setTitle(title);
+ item.setTitleEnabled(true);
+ }
+ }
+}}
+
namespace ucl {
// Naviframe::Builder //
return result;
}
- inline NaviItem Naviframe::push(const TString &title,
- Evas_Object *const backBtn, Evas_Object *const moreBtn,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::push(const TString &title, Widget *const content,
+ Widget *const backBtn, Widget *const moreBtn,
+ const ElmStyle style)
{
auto result = NaviItem(elm_naviframe_item_push(getEo(),
- nullptr, backBtn, moreBtn, content, style.name));
- result.setTitle(title);
+ nullptr, as_eo(backBtn), as_eo(moreBtn),
+ as_eo(content), style.name));
+ himpl::initItemTitle(result, title);
if (result != getBottomItem()) {
setInTransition(true);
}
return result;
}
- inline NaviItem Naviframe::push(const TString &title,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::push(const TString &title, Widget &content,
+ Widget *const backBtn, Widget *const moreBtn,
+ const ElmStyle style)
+ {
+ return push(title, &content, backBtn, moreBtn, style);
+ }
+
+ inline NaviItem Naviframe::push(const TString &title, Widget &content,
+ const ElmStyle style)
+ {
+ return push(title, &content, nullptr, nullptr, style);
+ }
+
+ inline NaviItem Naviframe::push(Widget &content, const ElmStyle style)
{
- return push(title, nullptr, nullptr, content, style);
+ return push(nullptr, &content, nullptr, nullptr, style);
}
- inline NaviItem Naviframe::push(
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::push(const ElmStyle style)
{
- return push(nullptr, nullptr, nullptr, content, style);
+ return push(nullptr, nullptr, nullptr, nullptr, style);
}
- inline NaviItem Naviframe::insertAfter(NaviItem after,
- const TString &title,
- Evas_Object *const backBtn, Evas_Object *const moreBtn,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::insertAfter(const NaviItem after,
+ const TString &title, Widget *const content,
+ Widget *const backBtn, Widget *const moreBtn,
+ const ElmStyle style)
{
auto result = NaviItem(elm_naviframe_item_insert_after(getEo(),
- after, nullptr, backBtn, moreBtn, content, style.name));
- result.setTitle(title);
+ after, nullptr, as_eo(backBtn), as_eo(moreBtn),
+ as_eo(content), style.name));
+ himpl::initItemTitle(result, title);
return result;
}
- inline NaviItem Naviframe::insertAfter(NaviItem after,
- const TString &title,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::insertAfter(const NaviItem after,
+ const TString &title, Widget &content,
+ Widget *const backBtn, Widget *const moreBtn,
+ const ElmStyle style)
{
- return insertAfter(after, title, nullptr, nullptr, content, style);
+ return insertAfter(after, title, &content, backBtn, moreBtn, style);
}
- inline NaviItem Naviframe::insertAfter(NaviItem after,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::insertAfter(const NaviItem after,
+ const TString &title, Widget &content,
+ const ElmStyle style)
{
- return insertAfter(after, nullptr, nullptr, nullptr, content, style);
+ return insertAfter(after, title, &content, nullptr, nullptr, style);
}
- inline NaviItem Naviframe::insertBefore(NaviItem before,
- const TString &title,
- Evas_Object *const backBtn, Evas_Object *const moreBtn,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::insertAfter(const NaviItem after,
+ Widget &content, const ElmStyle style)
+ {
+ return insertAfter(after, nullptr, &content, nullptr, nullptr, style);
+ }
+
+ inline NaviItem Naviframe::insertAfter(const NaviItem after,
+ const ElmStyle style)
+ {
+ return insertAfter(after, nullptr, nullptr, nullptr, nullptr, style);
+ }
+
+ inline NaviItem Naviframe::insertBefore(const NaviItem before,
+ const TString &title, Widget *const content,
+ Widget *const backBtn, Widget *const moreBtn,
+ const ElmStyle style)
{
auto result = NaviItem(elm_naviframe_item_insert_before(getEo(),
- before, nullptr, backBtn, moreBtn, content, style.name));
- result.setTitle(title);
+ before, nullptr, as_eo(backBtn), as_eo(moreBtn),
+ as_eo(content), style.name));
+ himpl::initItemTitle(result, title);
return result;
}
- inline NaviItem Naviframe::insertBefore(NaviItem before,
- const TString &title,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::insertBefore(const NaviItem before,
+ const TString &title, Widget &content,
+ Widget *const backBtn, Widget *const moreBtn,
+ const ElmStyle style)
+ {
+ return insertAfter(before, title, &content, backBtn, moreBtn, style);
+ }
+
+ inline NaviItem Naviframe::insertBefore(const NaviItem before,
+ const TString &title, Widget &content,
+ const ElmStyle style)
+ {
+ return insertAfter(before, title, &content, nullptr, nullptr, style);
+ }
+
+ inline NaviItem Naviframe::insertBefore(const NaviItem before,
+ Widget &content, const ElmStyle style)
{
- return insertAfter(before, title, nullptr, nullptr, content, style);
+ return insertAfter(before, nullptr, &content, nullptr, nullptr, style);
}
- inline NaviItem Naviframe::insertBefore(NaviItem before,
- Evas_Object *const content, const ElmStyle style)
+ inline NaviItem Naviframe::insertBefore(const NaviItem before,
+ const ElmStyle style)
{
- return insertAfter(before, nullptr, nullptr, nullptr, content, style);
+ return insertAfter(before, nullptr, nullptr, nullptr, nullptr, style);
}
inline NaviItem Naviframe::getTopItem()const
UCL_DECLARE_REF_ALIASES(StyledWidget);
+ /**
+ * @brief Represents Elementary widget which can apply ElmStyle
+ * and serves as base class for more concrete widget types
+ */
class StyledWidget : public EdjeWidget {
public:
- friend class ReffedObj<StyledWidget>;
using EdjeWidget::EdjeWidget;
+
+ /**
+ * @brief Constructor
+ * @param[in] eo Underlying Evas object of the widget
+ * @param[in] isOwner Evas object ownership flag (optional: true)
+ */
explicit StyledWidget(Evas_Object *eo, bool isOwner = true);
+ /**
+ * @brief Applies style to the widget
+ * @param[in] style Style to apply
+ */
void setStyle(ElmStyle style);
+
+ private:
+ friend class ReffedObj<StyledWidget>;
};
}
namespace ucl {
+ /**
+ * @brief Represents Elementary theme object that can be assigned to
+ * any Elementary widget.
+ * @see ElmWidget::setTheme
+ */
class Theme final : NonCopyable {
public:
+ /**
+ * @brief Creates new Theme object that refers default theme
+ * @return New Theme object (may not valid)
+ */
static Theme create();
+ /**
+ * @brief Swaps Theme objects with each other
+ * @param[in/out] x First theme object
+ * @param[in/out] y Second theme object
+ */
friend void swap(Theme &x, Theme &y);
public:
+ /**
+ * @brief Default constructor
+ * @details Constructs empty non valid theme
+ */
Theme();
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
Theme(std::nullptr_t);
+
+ /**
+ * @brief Constructor
+ * @details Wraps native Elementary theme object. Native Elementary
+ * theme objet will be deleted if Theme object is owner.
+ * @param[in] th Native Elementary theme object
+ * @param[in] isOwner Elementary theme object ownership
+ * flag (optional: false)
+ */
explicit Theme(Elm_Theme *th, bool isOwner = false);
+
+ /**
+ * @brief Move constructor
+ * @param[in] tmp Source temporary Theme object
+ */
Theme(Theme &&tmp);
- Theme &operator=(Theme &&tmp);
+
+ /**
+ * @brief Destructor
+ * @details Deletes native Elementary theme object if owner.
+ */
~Theme();
+ /**
+ * @brief Assigns one Them object to another
+ * @details Only move assignment is possible. Original will be deleted.
+ * @param[in] tmp Source Theme object
+ * @return Reference to this Theme object
+ */
+ Theme &operator=(Theme tmp);
+
+ /**
+ * @brief Gets native Elementary theme object
+ * @return Pointer to native Elementary theme object
+ */
Elm_Theme *getTh();
+
+ /**
+ * @brief Gets native Elementary theme object (constant version)
+ * @return Pointer to native constant Elementary theme object
+ */
const Elm_Theme *getTh() const;
+ /**
+ * @brief Implicitly casts to native Elementary theme object
+ * @return Pointer to native Elementary theme object
+ */
operator Elm_Theme *();
+
+ /**
+ * @brief Implicitly casts to native Elementary
+ * theme object (constant version)
+ * @return Pointer to native constant Elementary theme object
+ */
operator const Elm_Theme *() const;
+ /**
+ * @brief Adds specified Edje file as extension to this Theme object
+ * @details All Edje groups from the extension will be examined after
+ * all groups currently existing in this theme.
+ * @param[in] edjePath File path to Edje file with extension
+ */
void addExtension(const std::string edjePath);
+
+ /**
+ * @brief Adds specified Edje file as overlay to this Theme object
+ * @details All Edje groups from the overlay will be examined before
+ * all groups currently existing in this theme.
+ * @param[in] edjePath File path to Edje file with overlay
+ */
void addOverlay(const std::string edjePath);
private:
// Non-member functions //
- bool isValid(const Theme &item);
+ /**
+ * @brief Checks whether Theme object is valid
+ * @details This is equivalent to: item.getTh() != NULL;
+ * @param[in] theme Reference to target Theme object
+ * @return true if valid, false if not valid
+ */
+ bool isValid(const Theme &theme);
}
#include "Theme.hpp"
tmp.m_th = nullptr;
}
- inline Theme &Theme::operator=(Theme &&tmp)
- {
- swap(*this, tmp);
- return *this;
- }
-
inline Theme::~Theme()
{
if (m_isOwner && m_th) {
}
}
+ inline Theme &Theme::operator=(Theme tmp)
+ {
+ swap(*this, tmp);
+ return *this;
+ }
+
inline Elm_Theme *Theme::getTh()
{
return m_th;
// Non-member functions //
- inline bool isValid(const Theme &item)
+ inline bool isValid(const Theme &theme)
{
- return !!item.getTh();
+ return !!theme.getTh();
}
inline void swap(Theme &x, Theme &y)
UCL_DECLARE_REF_ALIASES(Widget);
+ /**
+ * @brief Represents Evas widget and serves as base class for more
+ * concrete widget types
+ */
class Widget : public RefCountAware {
public:
+ /**
+ * @brief Constant for setWeight() method
+ */
static constexpr auto EXPAND = EVAS_HINT_EXPAND;
+
+ /**
+ * @brief Constant for setAllign() method
+ */
static constexpr auto FILL = EVAS_HINT_FILL;
public:
+ /**
+ * @brief Gets the underlying Evas object
+ * @param[in] widget Reference to target widget
+ * @return Pointer to the underlying Evas object
+ */
+ friend Evas_Object *as_eo(Widget &widget);
+
+ /**
+ * @brief Gets the underlying constant Evas object
+ * @param[in] widget Constant reference to target widget
+ * @return Pointer to the underlying constant Evas object
+ */
+ friend const Evas_Object *as_eo(const Widget &widget);
+
+ public:
+ /**
+ * @brief Constructor
+ * @param[in] eo Underlying Evas object of the widget
+ * @param[in] isOwner Evas object ownership flag (optional: true)
+ */
explicit Widget(Evas_Object *eo, bool isOwner = true);
+
+ /**
+ * @brief Constructor
+ * @param[in] rc Pointer to IRefCountObj (passed automatically)
+ * @param[in] eo Underlying Evas object of the widget
+ * @param[in] isOwner Evas object ownership flag (optional: true)
+ */
+ Widget(IRefCountObj *rc, Evas_Object *eo, bool isOwner = true);
+
+ /**
+ * @brief Destructor
+ */
virtual ~Widget();
+ /**
+ * @brief Binds underlying Evas object to this widget
+ * @details When Evas object is bound it makes possible to convert
+ * Evas object pointer to Widget pointer. Only single
+ * Widget object may be bound same Evas object.
+ */
void bindToEo();
+
+ /**
+ * @brief Unbinds underlying Evas object from this widget
+ * @details Reverts the effect of bindToEo() function call. Use this
+ * function if you want to bind different Widget object to
+ * same Evas object (usefull when wrapping widgets).
+ */
void unbindFromEo();
+ /**
+ * @brief Sets ownership of Evas object flag to this widget
+ * @details In all cases:
+ * Evas object can't be destroyed while Widget object is alive.
+ * But it can still be marked for deletion.
+ *
+ * In all cases when ownership flag is true:
+ * Underlying Evas object is marked for deletion in the
+ * destructor of this Widget object. Otherwise...
+ *
+ * In case if Widget object is shared:
+ * While Evas object is alive Widget object is also remains
+ * alive even if all visible shared references destroyed.
+ * It is possible to create new shared reference to Widget
+ * from Evas object pointer.
+ *
+ * In case if Widget object is not shared:
+ * Underlying Evas object is not marked for deletion in the
+ * destructor of this Widget object
+ *
+ * @param[in] value Ownership flag. true - owner, false - not owner.
+ */
void setIsOwner(bool value);
- Evas_Object *getEo();
- const Evas_Object *getEo() const;
-
- operator Evas_Object *();
- operator const Evas_Object *() const;
-
+ /**
+ * @brief Gets Evas canvas on which underlying Evas object resides
+ * @return Pointer to the Evas canvas
+ */
Evas *getEvas() const;
+ /**
+ * @brief Assigns user data to this widget
+ * @param[in] key Name of the data key
+ * @param[in] data Pointer to the user data
+ */
void setData(EoDataKey key, void *data);
+
+ /**
+ * @brief Deletes user data from this widget
+ * @param[in] key Name of the data key
+ */
void delData(EoDataKey key);
+
+ /**
+ * @brief Gets user data from this widget
+ * @param[in] key Name of the data key
+ * @return Pointer to the user data or NULL if not found
+ */
void *getData(EoDataKey key) const;
+ /**
+ * @brief Registers standard widget event handler
+ * @param[in] event Value of the standart widget event enumeration
+ * @param[in] handler Handler of the event
+ */
void addEventHandler(WidgetEvent event, WidgetEventHandler handler);
- void addEventHandler(SmartEvent event, WidgetEventHandler handler);
- void delEventHandler(WidgetEvent event, WidgetEventHandler handler);
- void delEventHandler(SmartEvent event, WidgetEventHandler handler);
+ /**
+ * @brief Registers smart widget event handler
+ * @param[in] event Name of the smart widget event
+ * @param[in] handler Handler of the event
+ */
+ void addEventHandler(SmartEvent event, WidgetEventHandler handler);
+ /**
+ * @brief Deregisters standard widget event handler
+ * @param[in] event Value of the standart widget event enumeration
+ * @param[in] handler Handler of the event
+ */
+ void delEventHandler(WidgetEvent event,
+ WidgetEventHandler::CDRef handler);
+
+ /**
+ * @brief Deregisters smart widget event handler
+ * @param[in] event Name of the smart widget event
+ * @param[in] handler Handler of the event
+ */
+ void delEventHandler(SmartEvent event,
+ WidgetEventHandler::CDRef handler);
+
+ /**
+ * @brief Calls smart widget event on this widget
+ * @details All handler of this event on this widget will handle this
+ * event synchronously during call to this function.
+ * @param[in] event Name of the smart widget event
+ * @param[in] eventInfo Pointer to event info (optional)
+ */
void callEvent(SmartEvent event, void *eventInfo = nullptr);
+ /**
+ * @brief Marks underlying Evas object for deletion
+ * @details Evas object will be deleted when there is no Widget objects
+ * referencing it and no other references to it.
+ */
void markForDeletion();
+ /**
+ * @brief Sets visibility state of the widget
+ * @param[in] value New state
+ */
void setVisible(bool value);
+
+ /**
+ * @brief Gets visibility state of the widget
+ * @return true if visible, false if invisible
+ */
bool isVisible() const;
+ /**
+ * @brief Sets color to this widget
+ * @details Color component values must be premultiplied if alpha
+ * is not 255.
+ * @param[in] r Red component of the color [0-255]
+ * @param[in] g Green component of the color [0-255]
+ * @param[in] b Blue component of the color [0-255]
+ * @param[in] a Alpha transparency of the color [0-255] (optional: 255)
+ */
void setColor(int r, int g, int b, int a = 255);
+
+ /**
+ * @brief Sets gray color to this widget
+ * @param[in] l Luminosity of the color [0-255]
+ * @param[in] a Alpha transparency of the color [0-255] (optional: 255)
+ */
void setColor(int l, int a = 255);
+
+ /**
+ * @brief Gets color of this widget
+ * @param[out] r Reference to the red component of the color
+ * @param[out] g Reference to the green component of the color
+ * @param[out] b Reference to the blue component of the color
+ * @param[out] a Reference to the alpha
+ */
void getColor(int &r, int &g, int &b, int &a) const;
+ /**
+ * @brief Performs forced size calculations on the widget
+ */
void calculate();
+ /**
+ * @brief Sets geometry of this widget
+ * @param[in] x Top-left X coordinate of the widget
+ * @param[in] y Top-left Y coordinate of the widget
+ * @param[in] w New width of the widget
+ * @param[in] h New height of the widget
+ */
void setGeometry(int x, int y, int w, int h);
+
+ /**
+ * @brief Changes position of this widget
+ * @param[in] x Top-left X coordinate of the widget
+ * @param[in] y Top-left Y coordinate of the widget
+ */
void move(int x, int y);
+
+ /**
+ * @brief Changes size of this widget
+ * @param[in] w New width of the widget
+ * @param[in] h New height of the widget
+ */
void resize(int w, int h);
+ /**
+ * @brief Gets geometry of this widget
+ * @param[out] x Top-left X coordinate of the widget (may be NULL)
+ * @param[out] y Top-left Y coordinate of the widget (may be NULL)
+ * @param[out] w Width of the widget (may be NULL)
+ * @param[out] h Height of the widget (may be NULL)
+ */
void getGeometry(int *x, int *y, int *w, int *h) const;
- void setWeight(double w, double h);
- void setAlign(double w, double h);
+ /**
+ * @brief Sets weight size hints to the widget
+ * @details Use EXPAND to expand container to the parent size
+ * @param[in] x Weight of the widget along X axis
+ * @param[in] y Weight of the widget along Y axis
+ */
+ void setWeight(double x, double y);
+
+ /**
+ * @brief Sets align size hints to the widget
+ * @details Use FILL to streth to the size of the container
+ * @param[in] x Align of the widget along X axis [0.0-1.0]
+ * @param[in] y Align of the widget along Y axis [0.0-1.0]
+ */
+ void setAlign(double x, double y);
+
+ /**
+ * @brief Sets mimimum size hints to the widget
+ * @param[in] w Minimul allowed with of the widget
+ * @param[in] h Minimul allowed height of the widget
+ */
void setMin(int w, int h);
+
+ /**
+ * @brief Sets maximum size hints to the widget
+ * @details Use -1 for infinity.
+ * @param[in] w Maximum allowed with of the widget
+ * @param[in] h Maximum allowed height of the widget
+ */
void setMax(int w, int h);
- void getWeight(double *w, double *h) const;
- void getAlign(double *w, double *h) const;
+ /**
+ * @brief Gets weight size hints of the widget
+ * @param[out] x Weight of the widget along X axis (may be NULL)
+ * @param[out] y Weight of the widget along Y axis (may be NULL)
+ */
+ void getWeight(double *x, double *y) const;
+
+ /**
+ * @brief Gets align size hints of the widget
+ * @param[out] x Align of the widget along X axis (may be NULL)
+ * @param[out] y Align of the widget along Y axis (may be NULL)
+ */
+ void getAlign(double *x, double *y) const;
+
+ /**
+ * @brief Gets mimimum size hints of the widget
+ * @param[in] w Minimul allowed with of the widget (may be NULL)
+ * @param[in] h Minimul allowed height of the widget (may be NULL)
+ */
void getMin(int *w, int *h) const;
+
+ /**
+ * @brief Gets maximum size hints of the widget
+ * @param[in] w Maximum allowed with of the widget (may be NULL)
+ * @param[in] h Maximum allowed height of the widget (may be NULL)
+ */
void getMax(int *w, int *h) const;
+ /**
+ * @brief Sets aspect ratio size hints to the widget
+ * @param[in] arControl Type of aspect ration control
+ * @param[in] w Width aspect ration term
+ * @param[in] h Height aspect ration term
+ */
void setARHint(WidgetARHint arControl, int w, int h);
+
+ /**
+ * @brief Gets aspect ratio size hints of the widget
+ * @param[out] arControl Type of aspect ration control
+ * @param[out] w Width aspect ration term
+ * @param[out] h Height aspect ration term
+ */
void getARHint(WidgetARHint &arControl, int &w, int &h);
+ /**
+ * @brief Sets key-input focus state to the widget
+ * @param[in] value New state. true - to set focus, false - to unset
+ */
void setFocused(bool value);
+
+ /**
+ * @brief Gets key-input focus state of the widget
+ * @return true if focused, false id not focused
+ */
bool isFocused() const;
protected:
- friend class ReffedObj<Widget>;
- Widget(IRefCountObj *rc, Evas_Object *eo, bool isOwner = true);
+ /**
+ * @brief Gets the underlying Evas object
+ * @return Pointer to the underlying Evas object
+ */
+ Evas_Object *getEo();
+ /**
+ * @brief Gets the underlying Evas object (constant version)
+ * @return Pointer to the constant underlying Evas object
+ */
+ const Evas_Object *getEo() const;
+
+ /**
+ * @brief Actually sets key-input focus state to the widget
+ * @details May be overriden in subclasses to change behaviour
+ * @param[in] value New state. true - to set focus, false - to unset
+ */
virtual void setFocusedImpl(bool value);
+
+ /**
+ * @brief Actually gets key-input focus state of the widget
+ * @details May be overriden in subclasses to change behaviour
+ * @return true if focused, false id not focused
+ */
virtual bool isFocusedImpl() const;
+
+ /**
+ * @brief Setups all necessary state to handle forwarded smart events
+ * @details Called when a handler for UCL_SMART_FWD is added.
+ * @param[in] fwdEvent Smart event that needs to be forwarded
+ * @return true - if forwarded event is supported and necessary state
+ * was succesfully prepared, false - otherwise
+ */
virtual bool ensureFwdEvent(SmartEvent fwdEvent);
private:
bool m_isBoundToEo;
bool m_isEoRefKept;
bool m_isSelfRefUnique;
+
+ friend class ReffedObj<Widget>;
};
// Non-member functions //
+ /**
+ * @brief Gets Evas object from pointed object
+ * @param[in] ptr Target object pointer
+ * @return Pointer to Evas object or NULL
+ */
+ template <class T>
+ inline auto as_eo(const T &ptr) -> typename std::enable_if<
+ std::is_convertible<T, bool>::value, decltype(as_eo(*ptr))>::type
+ {
+ return (ptr ? as_eo(*ptr) : nullptr);
+ }
+
+ /**
+ * @brief Gets Evas object from iterator
+ * @param[in] iter Target object iterator
+ * @return Pointer to Evas object or NULL
+ */
+ template <class T>
+ inline auto as_eo(const T &iter) -> typename std::enable_if<
+ !std::is_convertible<T, bool>::value, decltype(as_eo(*iter))>::type
+ {
+ return as_eo(*iter);
+ }
+
+ /**
+ * @brief Passes through original Evas object pointer
+ * @param[in] eo Evas object pointer
+ * @return Evas object pointer
+ */
+ Evas_Object *as_eo(Evas_Object *eo);
+
+ /**
+ * @brief Passes through original constant Evas object pointer
+ * @param[in] eo Constant Evas object pointer
+ * @return Constant Evas object pointer
+ */
+ const Evas_Object *as_eo(const Evas_Object *eo);
+
+ /**
+ * @brief Gets position of the widget
+ * @param[in] widget Reference to target widget
+ * @param[out] x Top-left X coordinate of the widget (may be NULL)
+ * @param[out] y Top-left Y coordinate of the widget (may be NULL)
+ */
void getPosition(const Widget &widget, int *x, int *y);
+
+ /**
+ * @brief Gets size of the widget
+ * @param[in] widget Reference to target widget
+ * @param[out] w Width of the widget (may be NULL)
+ * @param[out] h Height of the widget (may be NULL)
+ */
void getSize(const Widget &widget, int *w, int *h);
+ /**
+ * @brief Makes the widget visible
+ * @details This is equivalent to: widget.setVisible(true);
+ * @param[in] widget Reference to target widget
+ */
void show(Widget &widget);
+
+ /**
+ * @brief Makes the widget invisible
+ * @details This is equivalent to: widget.setVisible(false);
+ * @param[in] widget Reference to target widget
+ */
void hide(Widget &widget);
+ /**
+ * @brief Makes the widget transparent
+ * @details This is equivalent to: widget.setColor(0, 0);
+ * @param[in] widget Reference to target widget
+ */
void makeTransparent(Widget &widget);
+
+ /**
+ * @brief Makes the widget color white
+ * @details This is equivalent to: widget.setColor(255);
+ * @param[in] widget Reference to target widget
+ */
void makeWhite(Widget &widget);
+ /**
+ * @brief Sets widget to focused state
+ * @details This is equivalent to: widget.setFocused(true);
+ * @param[in] widget Reference to target widget
+ */
void focus(Widget &widget);
+
+ /**
+ * @brief Sets widget to unfocused state
+ * @details This is equivalent to: widget.setFocused(false);
+ * @param[in] widget Reference to target widget
+ */
void unfocus(Widget &widget);
+ /**
+ * @brief Sets EXPAND weight size hits to the widget
+ * @details This is equivalent to:
+ * widget.setWight(Widget::EXPAND, Widget::EXPAND);
+ * @param[in] widget Reference to target widget
+ */
void expand(Widget &widget);
+
+ /**
+ * @brief Sets FILL align size hits to the widget
+ * @details This is equivalent to:
+ * widget.setAlign(Widget::FILL, Widget::FILL);
+ * @param[in] widget Reference to target widget
+ */
void fill(Widget &widget);
- void expandAndFill(Widget &widget);
- bool operator==(const Widget &lhs, const Widget &rhs);
- bool operator!=(const Widget &lhs, const Widget &rhs);
+ /**
+ * @brief Sets EXPAND weight and FILL align size hits to the widget
+ * @details This is equivalent to: expand(widget); fill(widget);
+ * @param[in] widget Reference to target widget
+ */
+ void expandAndFill(Widget &widget);
}
#include "Widget.hpp"
return m_eo;
}
- inline Widget::operator Evas_Object *()
- {
- return getEo();
- }
-
- inline Widget::operator const Evas_Object *() const
- {
- return getEo();
- }
-
inline Evas *Widget::getEvas() const
{
return evas_object_evas_get(getEo());
evas_object_geometry_get(getEo(), x, y, w, h);
}
- inline void Widget::setWeight(const double w, const double h)
+ inline void Widget::setWeight(const double x, const double y)
{
- evas_object_size_hint_weight_set(getEo(), w, h);
+ evas_object_size_hint_weight_set(getEo(), x, y);
}
- inline void Widget::setAlign(const double w, const double h)
+ inline void Widget::setAlign(const double x, const double y)
{
- evas_object_size_hint_align_set(getEo(), w, h);
+ evas_object_size_hint_align_set(getEo(), x, y);
}
inline void Widget::setMin(const int w, const int h)
evas_object_size_hint_max_set(getEo(), w, h);
}
- inline void Widget::getWeight(double *const w, double *const h) const
+ inline void Widget::getWeight(double *const x, double *const y) const
{
- evas_object_size_hint_weight_get(getEo(), w, h);
+ evas_object_size_hint_weight_get(getEo(), x, y);
}
- inline void Widget::getAlign(double *const w, double *const h) const
+ inline void Widget::getAlign(double *const x, double *const y) const
{
- evas_object_size_hint_align_get(getEo(), w, h);
+ evas_object_size_hint_align_get(getEo(), x, y);
}
inline void Widget::getMin(int *const w, int *const h) const
// Non-member functions //
+ inline Evas_Object *as_eo(Widget &widget)
+ {
+ return widget.m_eo;
+ }
+
+ inline const Evas_Object *as_eo(const Widget &widget)
+ {
+ return widget.m_eo;
+ }
+
+ inline Evas_Object *as_eo(Evas_Object *const eo)
+ {
+ return eo;
+ }
+
+ inline const Evas_Object *as_eo(const Evas_Object *const eo)
+ {
+ return eo;
+ }
+
inline void getPosition(const Widget &widget, int *x, int *y)
{
widget.getGeometry(x, y, nullptr, nullptr);
expand(widget);
fill(widget);
}
-
- inline bool operator==(const Widget &lhs, const Widget &rhs)
- {
- return (lhs.getEo() == rhs.getEo());
- }
-
- inline bool operator!=(const Widget &lhs, const Widget &rhs)
- {
- return (lhs.getEo() != rhs.getEo());
- }
}
namespace ucl {
+ /**
+ * @brief Represents generic Elementary widget item and serves as base
+ * class for more concrete widget item types
+ * @details This class has semantic of a pointer and therefore does not
+ * manage lifetime of the item. Pointer is always point to the non
+ * constant Genlist item. Most of the methods marked as const
+ * because pointer is not changed in these method calls.
+ */
class WidgetItem {
public:
+ /**
+ * @brief Default constructor
+ * @details Constructs NULL item
+ */
constexpr WidgetItem();
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
constexpr WidgetItem(std::nullptr_t);
+
+ /**
+ * @brief Constructor
+ * @details Wraps native Elementary widget item.
+ * @param[in] it Native Elementary widget item
+ */
explicit WidgetItem(Elm_Object_Item *it);
+ /**
+ * @brief Gets native Elementary widget item
+ * @return Pointer to native Elementary widget item
+ */
Elm_Object_Item *getIt() const;
+ /**
+ * @brief Implicitly casts to native Elementary widget item
+ * @return Pointer to native Elementary widget item
+ */
operator Elm_Object_Item *() const;
- operator bool() const;
+ /**
+ * @brief Explicitly casts to boolen type
+ * @return true if native item is not NULL, false - if NULL
+ */
+ explicit operator bool() const;
+
+ /**
+ * @brief Gets owning Evas object of this widget item
+ * @return Pointer to the owning Evas object
+ */
Evas_Object *getWidget() const;
+ /**
+ * @brief Sets widget item delete callback
+ * @details Callback is called when item is deleted.
+ * Data of the callback is set by setData() method.
+ * @param[in] cb Pointer to callback function
+ */
void setDelCallback(Evas_Smart_Cb cb) const;
+ /**
+ * Deletes this widget item and NULL the pointer
+ */
void del();
+ /**
+ * @brief Assigns user data to this widget item
+ * @param[in] data Pointer to the user data
+ */
void setData(void *data) const;
+
+ /**
+ * @brief Gets assigned user data to this widget item
+ * @return Pointer to the assigned user data or NULL
+ */
void *getData() const;
+ /**
+ * @brief Sets enabled state of the widget item
+ * @param[in] value New state
+ */
void setEnabled(bool value) const;
+
+ /**
+ * @brief Gets enabled state of the widget item
+ * @return true if enabled, false if disabled
+ */
bool isEnabled() const;
+ /**
+ * @brief Applies style to the widget item
+ * @param[in] style Style to apply
+ */
void setStyle(ElmStyle style) const;
+ /**
+ * @brief Sets text to default part of the widget item
+ * @param[in] value Translatable text value to set
+ */
void setText(const TString &value) const;
- void setText(const TString &value, EdjePart part) const;
- TString getText() const;
- TString getText(EdjePart part) const;
+ /**
+ * @brief Sets text to specific part of the widget item
+ * @param[in] value Translatable text value to set
+ * @param[in] part Destination Edje part
+ */
+ void setText(const TString &value, EdjePart part) const;
- void setContent(Evas_Object *content) const;
- void setContent(Evas_Object *content, EdjePart part) const;
+ /**
+ * @brief Gets text from default part of the widget item
+ * @return Translated text from default part
+ */
+ std::string getText() const;
+
+ /**
+ * @brief Gets text from specific part of the widget item
+ * @param[in] part Source Edje part
+ * @return Translated text from specific part
+ */
+ std::string getText(EdjePart part) const;
+
+ /**
+ * @brief Sets content to default part of the widget item
+ * @param[in] content Content widget
+ */
+ void setContent(Widget &content) const;
+
+ /**
+ * @brief Sets content to specific part of the widget item
+ * @param[in] content Content widget
+ * @param[in] part Destination Edje part
+ */
+ void setContent(Widget &content, EdjePart part) const;
+
+ /**
+ * @brief Unsets content from default part of the widget item
+ * @return Content Evas object or NULL
+ */
Evas_Object *unsetContent() const;
+
+ /**
+ * @brief Unsets content from specific part of the widget item
+ * @param[in] part Source Edje part
+ * @return content Evas object or NULL
+ */
Evas_Object *unsetContent(EdjePart part) const;
+ /**
+ * @brief Gets content from default part of the widget item
+ * @return Content Evas object or NULL
+ */
Evas_Object *getContent() const;
+
+ /**
+ * @brief Gets content from specific part of the widget item
+ * @param[in] part Source Edje part
+ * @return content Evas object or NULL
+ */
Evas_Object *getContent(EdjePart part) const;
+ /**
+ * @brief Emits signal to the widget item's Edje theme
+ * @param[in] signal Emitted signal
+ * @param[in] signal Emitted signal source (optional)
+ */
void emit(EdjeSignal signal, EdjeSignalSrc source =
EdjeSignalSrc("")) const;
// Non-member functions //
+ /**
+ * @brief Sets widget item to enabled state
+ * @details This is equivalent to: item.setEnabled(true);
+ * @param[in] item Reference to target widget item
+ */
void enable(WidgetItem item);
+
+ /**
+ * @brief Sets widget item to disabled state
+ * @details This is equivalent to: item.setEnabled(false);
+ * @param[in] item Reference to target widget item
+ */
void disable(WidgetItem item);
+ /**
+ * @brief Compares equals underlying item pointers of target widgets items
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ */
bool operator==(WidgetItem lhs, WidgetItem rhs);
+
+ /**
+ * @brief Compares unequals underlying item pointers of target widget items
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ */
bool operator!=(WidgetItem lhs, WidgetItem rhs);
}
elm_object_item_style_set(getIt(), style.name);
}
- inline TString WidgetItem::getText() const
+ inline std::string WidgetItem::getText() const
{
return elm_object_item_text_get(getIt());
}
- inline TString WidgetItem::getText(const EdjePart part) const
+ inline std::string WidgetItem::getText(const EdjePart part) const
{
return elm_object_item_part_text_get(getIt(), part.name);
}
- inline void WidgetItem::setContent(Evas_Object *const content) const
+ inline void WidgetItem::setContent(Widget &content) const
{
- elm_object_item_content_set(getIt(), content);
+ elm_object_item_content_set(getIt(), as_eo(content));
}
- inline void WidgetItem::setContent(Evas_Object *const content,
+ inline void WidgetItem::setContent(Widget &content,
const EdjePart part) const
{
- elm_object_item_part_content_set(getIt(), part.name, content);
+ elm_object_item_part_content_set(getIt(), part.name, as_eo(content));
}
inline Evas_Object *WidgetItem::unsetContent() const
UCL_DECLARE_REF_ALIASES(Window);
+ /**
+ * @brief Represents Elementary Window widget with Conformant
+ */
class Window final : public ElmWidget {
public:
+ /**
+ * @brief Enumeration of Window types
+ */
enum class Type {
BASIC = ELM_WIN_BASIC
};
+ /**
+ * @brief Builder of Window objects
+ */
class Builder final {
public:
+ /**
+ * @brief Constructor
+ */
Builder();
+ /**
+ * @brief Sets Evas object for the future window
+ * @details If Evas object is set builder will create wrapper
+ * Window object.
+ * @param[in] value Pointer to window Evas object
+ * @return Reference to this builder
+ */
Builder &setWinEo(Evas_Object *value);
+ /**
+ * @brief Sets type of the future window
+ * @details Ignored if WinEo is set.
+ * @param[in] type Type of the future window
+ * @return Reference to this builder
+ */
Builder &setType(Type type);
+
+ /**
+ * @brief Sets name of the future window
+ * @details Ignored if WinEo is set or used as title (if not set).
+ * @param[in] value Name of the future window
+ * @return Reference to this builder
+ */
Builder &setName(std::string value);
+ /**
+ * @brief Sets title of the future window
+ * @details Name is used if not set.
+ * @param[in] value Title of the future window
+ * @return Reference to this builder
+ */
Builder &setTitle(std::string value);
+
+ /**
+ * @brief Sets indicator visibility state of the future window
+ * @param[in] value Indicator visibility state of the future window
+ * @return Reference to this builder
+ */
Builder &setIndicatorVisible(bool value);
+
+ /**
+ * @brief Sets supported rotations by the future window
+ * @param[in] value Rotations supported by the future window
+ * @return Reference to this builder
+ */
Builder &setRotations(std::vector<int> value);
+ /**
+ * @brief Sets Evas object ownership flag of the future object
+ * @details If not set and WinEo is also not IsOwner
+ * is true by default, otherwise - false.
+ * @param[in] value true if owner, false - otherwise
+ * @return Reference to this builder
+ */
Builder &setIsOwner(bool value);
+
+ /**
+ * @brief Sets if future object needs to be bind to it's Evas object
+ * @param[in] value true if need to bind, false - otherwise
+ * @return Reference to this builder
+ */
Builder &setNeedBindToEo(bool value);
+ /**
+ * @brief Creates new Window object using current parameters
+ * @param[in] parent Reference to parent widget
+ * @return Shared reference to new Window object or NULL
+ */
WindowSRef build() const;
+
private:
std::string m_name;
std::string m_title;
};
public:
+ /**
+ * @brief Gets conformant of this Window
+ * @return Reference to Conformant widget
+ */
StyledWidget &getConformant();
+
+ /**
+ * @brief Gets conformant of this Window (constant version)
+ * @return Reference to constant Conformant widget
+ */
const StyledWidget &getConformant() const;
+ /**
+ * @brief Gets screen size of the window
+ * @param[out] w Width of the screen (may be NULL)
+ * @param[out] h Height of the screen (may be NULL)
+ */
void getScreenSize(int *w, int *h) const;
+ /**
+ * @brief Sets title of the window
+ * @param[in] value Title of the window
+ */
void setTitle(const std::string &title);
+
+ /**
+ * @brief Gets title of the window
+ * @return Title of the window
+ */
std::string getTitle() const;
+ /**
+ * Sets window indicator visibility state
+ * @param[in] value Visibility state. true - visible, false - invisible
+ */
void setIndicatorVisible(bool value);
+
+ /**
+ * Gets window indicator visibility state
+ * @retrun Visibility state. true - visible, false - invisible
+ */
bool isIndicatorVisible() const;
+ /**
+ * Gets window rotations support status
+ * @retrun true - rotation supported, false - no supported
+ */
bool isRotationsSupported() const;
+
+ /**
+ * @brief Sets supported rotations to the window
+ * @param[in] value Rotations supported by the window
+ */
void setRotations(const std::vector<int> &value);
+ /**
+ * @brief Resizes the window to fill whole screen
+ */
void resizeToScreen();
+
+ /**
+ * @brief Moves window to foreground
+ */
void lower();
private:
- friend class ReffedObj<Window>;
Window(IRefCountObj *rc, Evas_Object *eo,
- bool isOwner, Evas_Object *conform);
+ bool isOwner, Evas_Object *conform, Private);
private:
StyledWidget m_conform;
+
+ friend class ReffedObj<Window>;
};
// Non-member functions //
// Window //
+ /**
+ * @brief Makes the window indicator visible
+ * @details This is equivalent to: win.setIndicatorVisible(true);
+ * @param[in] win Reference to target window
+ */
void showIndicator(Window &win);
+
+ /**
+ * @brief Makes the window indicator invisible
+ * @details This is equivalent to: win.setIndicatorVisible(false);
+ * @param[in] win Reference to target window
+ */
void hideIndicator(Window &win);
// Window::Type //
+ /**
+ * @brief Checks validity of window type value
+ * @param[in] winType Window type value to validate
+ * @return true - if window type valid, false - otherwise
+ */
bool isValid(Window::Type winType);
}
// Window //
inline Window::Window(IRefCountObj *const rc, Evas_Object *const eo,
- const bool isOwner, Evas_Object *const conform) :
+ const bool isOwner, Evas_Object *const conform, Private) :
ElmWidget(rc, eo, isOwner),
m_conform(conform)
{
// Converts Evas_Object to Widget pointer //
+ /**
+ * @brief Converts Evas object pointer to Widget pointer
+ * @details Widget::bindToEo() must be called on widget object in order
+ * for this function to work.
+ * @return Pointer to the corresponding Widget object or NULL
+ */
Widget *asWidget(Evas_Object *eo);
+
+ /**
+ * @brief Converts pointer to constant Evas object to pointer
+ * to constant Widget
+ * @details Widget::bindToEo() must be called on widget object in order
+ * for this function to work.
+ * @return Pointer to the corresponding Widget object or NULL
+ */
const Widget *asWidget(const Evas_Object *eo);
// Widget casting functions from Evas_Object //
+ /**
+ * @brief Statically casts Evas object pointer to WIDGET_TYPE pointer
+ * @details This function performs static_cast<WIDGET_TYPE *> on
+ * the result of asWidget() function call.
+ * @return Pointer to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto staticWidgetCast(Evas_Object *eo) ->
decltype(static_cast<WIDGET_TYPE *>(asWidget(eo)))
return static_cast<WIDGET_TYPE *>(asWidget(eo));
}
+ /**
+ * @brief Statically casts pointer to constant Evas object to pointer
+ * to constant WIDGET_TYPE
+ * @details This function performs static_cast<const WIDGET_TYPE *> on
+ * the result of asWidget() function call.
+ * Do not need to add const to WIDGET_TYPE.
+ * @return Pointer to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto staticWidgetCast(const Evas_Object *eo) ->
- decltype(static_cast<WIDGET_TYPE *>(asWidget(eo)))
+ decltype(static_cast<const WIDGET_TYPE *>(asWidget(eo)))
{
- return static_cast<WIDGET_TYPE *>(asWidget(eo));
+ return static_cast<const WIDGET_TYPE *>(asWidget(eo));
}
+ /**
+ * @brief Dynamically casts Evas object pointer to WIDGET_TYPE pointer
+ * @details This function performs dynamic_cast<WIDGET_TYPE *> on
+ * the result of asWidget() function call.
+ * @return Pointer to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto dynamicWidgetCast(Evas_Object *eo) ->
decltype(dynamic_cast<WIDGET_TYPE *>(asWidget(eo)))
return dynamic_cast<WIDGET_TYPE *>(asWidget(eo));
}
+ /**
+ * @brief Dynamically casts pointer to constant Evas object to pointer
+ * to constant WIDGET_TYPE
+ * @details This function performs dynamic_cast<const WIDGET_TYPE *>
+ * on the result of asWidget() function call.
+ * Do not need to add const to WIDGET_TYPE.
+ * @return Pointer to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto dynamicWidgetCast(const Evas_Object *eo) ->
- decltype(dynamic_cast<WIDGET_TYPE *>(asWidget(eo)))
+ decltype(dynamic_cast<const WIDGET_TYPE *>(asWidget(eo)))
{
- return dynamic_cast<WIDGET_TYPE *>(asWidget(eo));
+ return dynamic_cast<const WIDGET_TYPE *>(asWidget(eo));
}
+ /**
+ * @brief Statically casts Evas object pointer to SharedRef<WIDGET_TYPE>
+ * @details This function calls asShared() on the result of
+ * staticWidgetCast<WIDGET_TYPE>() function call.
+ * @return Shared reference to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto staticWidgetRefCast(Evas_Object *eo) ->
decltype(asShared(staticWidgetCast<WIDGET_TYPE>(eo)))
return asShared(staticWidgetCast<WIDGET_TYPE>(eo));
}
+ /**
+ * @brief Statically casts pointer to constant Evas object
+ * to SharedRef<const WIDGET_TYPE>
+ * @details This function calls asShared() on the result of
+ * staticWidgetCast<WIDGET_TYPE>() function call.
+ * @return Shared reference to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto staticWidgetRefCast(const Evas_Object *eo) ->
decltype(asShared(staticWidgetCast<WIDGET_TYPE>(eo)))
return asShared(staticWidgetCast<WIDGET_TYPE>(eo));
}
+ /**
+ * @brief Dynamically casts Evas object pointer to SharedRef<WIDGET_TYPE>
+ * @details This function calls asShared() on the result of
+ * dynamicWidgetCast<WIDGET_TYPE>() function call.
+ * @return Shared reference to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto dynamicWidgetRefCast(Evas_Object *eo) ->
decltype(asShared(dynamicWidgetCast<WIDGET_TYPE>(eo)))
return asShared(dynamicWidgetCast<WIDGET_TYPE>(eo));
}
+ /**
+ * @brief Dynamically casts pointer to constant Evas object
+ * to SharedRef<const WIDGET_TYPE>
+ * @details This function calls asShared() on the result of
+ * dynamicWidgetCast<WIDGET_TYPE>() function call.
+ * @return Shared reference to the corresponding WIDGET_TYPE object or NULL
+ */
template <class WIDGET_TYPE>
inline auto dynamicWidgetRefCast(const Evas_Object *eo) ->
decltype(asShared(dynamicWidgetCast<WIDGET_TYPE>(eo)))
// Styles //
+ /**
+ * @brief Style that is default for wide range of widgets
+ */
constexpr ElmStyle STYLE_DEFAULT {"default"};
// Parts //
+ /**
+ * @brief Default text part for wide range of widgets
+ */
constexpr EdjePart PART_TEXT {"elm.text"};
+
+ /**
+ * @brief Default title text part for wide range of widgets
+ */
constexpr EdjePart PART_TITLE {"elm.text.title"};
+ /**
+ * @brief Default content part for wide range of widgets
+ */
constexpr EdjePart PART_CONTENT {"elm.swallow.content"};
+
+ /**
+ * @brief Default icon part for wide range of widgets
+ */
constexpr EdjePart PART_ICON {"elm.swallow.icon"};
+
+ /**
+ * @brief Default button part for wide range of widgets
+ */
constexpr EdjePart PART_BUTTON {"elm.swallow.button"};
}
namespace ucl {
+ /**
+ * @brief Application default layout theme
+ */
constexpr LayoutTheme LAYOUT_DEFAULT {"layout", "application", "default"};
+ /**
+ * @brief No contents layout theme
+ */
constexpr LayoutTheme LAYOUT_NO_CONTENTS
{"layout", "nocontents", "default"};
}
namespace ucl {
+ /**
+ * @brief Empty naviframe style (only with content part)
+ */
constexpr ElmStyle NAVIFRAME_EMPTY {"empty"};
}
// Aspects //
+ /**
+ * @brief Represent Edje part name
+ */
struct EdjePart : Aspect<EdjePart> { using Aspect::Aspect; };
+
+ /**
+ * @brief Represent Edje group name
+ */
struct EdjeGroup : Aspect<EdjeGroup> { using Aspect::Aspect; };
+
+ /**
+ * @brief Represent Edje data key name
+ */
struct EdjeDataKey : Aspect<EdjeDataKey> { using Aspect::Aspect; };
+ /**
+ * @brief Represent Edje signal name
+ */
struct EdjeSignal : Aspect<EdjeSignal> { using Aspect::Aspect; };
+
+ /**
+ * @brief Represent Edje signal source name
+ */
struct EdjeSignalSrc : Aspect<EdjeSignalSrc> { using Aspect::Aspect; };
+ /**
+ * @brief Represent Elementary widget style name
+ */
struct ElmStyle : Aspect<ElmStyle> { using Aspect::Aspect; };
+ /**
+ * @brief Represent Evas object smart callback name
+ */
struct SmartEvent : Aspect<SmartEvent> { using Aspect::Aspect; };
+ /**
+ * @brief Represent Evas object data key name
+ */
struct EoDataKey : Aspect<EoDataKey> { using Aspect::Aspect; };
// Delegates //
+ /**
+ * @brief Handler for events with the Evas object smart callback signature
+ */
using SmartCbHandler = Delegate<void(Evas_Object *obj, void *eventInfo)>;
// WidgetEventHandler //
class Widget;
+ /**
+ * @brief Handler for Widget standard/smart events
+ */
using WidgetEventHandler =
WeakDelegate<void(Widget &widget, void *eventInfo)>;
// WidgetEvent //
+ /**
+ * @brief Enumeration of Widget standard events
+ */
enum class WidgetEvent {
- DEL = EVAS_CALLBACK_DEL,
+ DEL = EVAS_CALLBACK_DEL,
MOUSE_IN = EVAS_CALLBACK_MOUSE_IN,
MOUSE_OUT = EVAS_CALLBACK_MOUSE_OUT,
// AtspiGestureEventInfo //
+ class Atspi;
+
+ /**
+ * @brief Event info data for ATSPI gesture smart event
+ */
struct AtspiGestureEventInfo final {
Elm_Atspi_Gesture_Info gestureInfo;
bool preventDefault;
bool stopPropagation;
};
+ /**
+ * @brief Handler for Atspi gesture events
+ */
+ using AtspiGestureHandler = WeakDelegate<void(Atspi &atspi,
+ AtspiGestureEventInfo &eventInfo)>;
+
+ /**
+ * @brief Callback for Atspi string requesting functions (name, description)
+ */
+ using AtspiStringCb = WeakDelegate<CString(Atspi &atspi)>;
+
// WidgetARHint //
- enum class WidgetARHint
- {
+ /**
+ * @brief Enumeration of widget aspect ration hints
+ */
+ enum class WidgetARHint {
NEITHER = EVAS_ASPECT_CONTROL_NEITHER,
HORIZONTAL = EVAS_ASPECT_CONTROL_HORIZONTAL,
VERTICAL = EVAS_ASPECT_CONTROL_VERTICAL,
// LayoutTheme //
+ /**
+ * @brief Represents Layout theme description
+ */
struct LayoutTheme final {
+ /**
+ * @brief Name of the widget class
+ */
const char *klass;
+
+ /**
+ * @brief Name of the group
+ */
const char *group;
+
+ /**
+ * @brief Name of the style
+ */
const char *style;
+ /**
+ * @brief Default constructor
+ * @details Constructs empty non valid LayoutTheme
+ */
constexpr LayoutTheme();
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
constexpr LayoutTheme(std::nullptr_t);
+
+ /**
+ * @brief Constructor
+ * @param[in] klass Name of the widget class
+ * @param[in] group Name of the group
+ * @param[in] style Name of the style
+ */
constexpr LayoutTheme(const char *klass,
const char *group, const char *style);
};
// LayoutTheme non-member functions //
+ /**
+ * @brief Checks whether LayoutTheme object is valid
+ * @param[in] value Reference to target LayoutTheme object
+ * @return true if valid, false if not valid
+ */
constexpr bool isValid(const LayoutTheme &value);
}
namespace ucl {
+ /**
+ * @brief Implementation for CHILD aspect
+ * @details CHILD class must inherit from this template to implement
+ * specific aspect
+ */
template <class CHILD>
struct Aspect {
+ /**
+ * @brief Name of the aspect
+ */
const char *name;
+ /**
+ * @brief Default constructor
+ * @details Initializes "name" to NULL.
+ */
constexpr Aspect();
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
constexpr Aspect(std::nullptr_t);
+
+ /**
+ * @brief Constructor
+ * @param[in] name Name for the new aspect or NULL
+ */
explicit constexpr Aspect(const char *name);
+ /**
+ * @brief Returns name of the aspect
+ */
constexpr operator const char *() const;
+ /**
+ * @brief Custom hash functor for Aspect<CHILD>
+ */
struct Hash final {
size_t operator()(const Aspect &key) const;
};
// Non-member functions //
+ /**
+ * @brief Checks validity of the Aspect<CHILD> (name is not NULL)
+ * @param[in] aspect Target aspect
+ * @return Validity status. true - valid, false - not valid
+ */
template <class CHILD>
constexpr bool isValid(Aspect<CHILD> aspect);
+ /**
+ * @brief Compares equals names of target aspects
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
template <class CHILD>
constexpr bool operator==(Aspect<CHILD> lhs, Aspect<CHILD> rhs);
+
+ /**
+ * @brief Compares unequals names of target aspects
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
template <class CHILD>
constexpr bool operator!=(Aspect<CHILD> lhs, Aspect<CHILD> rhs);
}
+++ /dev/null
-/*
- * Copyright 2017 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __UCL_MISC_AUTO_HANDLE_H__
-#define __UCL_MISC_AUTO_HANDLE_H__
-
-#include "ucl/util/types.h"
-
-namespace ucl {
-
- template <class HANDLE, class DEL_RET, DEL_RET(*DEL_FUNC)(HANDLE)>
- struct AutoHandle final : ucl::NonCopyable {
- using Handle = HANDLE;
-
- HANDLE value;
-
- AutoHandle() :
- value()
- {
- }
-
- AutoHandle(std::nullptr_t) :
- AutoHandle()
- {
- }
-
- AutoHandle(HANDLE value) :
- value(value)
- {
- }
-
- ~AutoHandle()
- {
- if (value) {
- DEL_FUNC(value);
- }
- }
-
- AutoHandle(AutoHandle &&src) :
- value(src.value)
- {
- src.value = nullptr;
- }
-
- AutoHandle &operator=(AutoHandle src)
- {
- swap(*this, src);
- return *this;
- }
-
- AutoHandle &operator=(HANDLE value)
- {
- AutoHandle src{value};
- swap(*this, src);
- return *this;
- }
-
- HANDLE *operator&()
- {
- return &value;
- }
-
- operator HANDLE()
- {
- return value;
- }
- };
-
- // Non-member functions //
-
- template <class HANDLE, class DEL_RET, DEL_RET(*DEL_FUNC)(HANDLE)>
- inline void swap(AutoHandle<HANDLE, DEL_RET, DEL_FUNC> &x,
- AutoHandle<HANDLE, DEL_RET, DEL_FUNC> &y) noexcept
- {
- std::swap(x.value, y.value);
- }
-}
-
-#endif // __UCL_MISC_AUTO_HANDLE_H__
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UCL_MISC_AUTO_OBJECT_H__
+#define __UCL_MISC_AUTO_OBJECT_H__
+
+#include "ucl/util/types.h"
+
+namespace ucl {
+
+ /**
+ * @brief Resource wrapper for automatically deallocate OBJ_TYPE
+ * using DEL_FUNC in destructor
+ */
+ template <class OBJ_TYPE, class DEL_RET, DEL_RET(*DEL_FUNC)(OBJ_TYPE)>
+ struct AutoObject final : ucl::NonCopyable {
+ /**
+ * @brief Type of the wrapped object
+ */
+ using ObjType = OBJ_TYPE;
+
+ /**
+ * @brief Value of the object
+ */
+ OBJ_TYPE obj;
+
+ /**
+ * @brief Default constructor
+ * @details Initializes "obj" using value initialization
+ */
+ AutoObject() :
+ obj{}
+ {
+ }
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
+ AutoObject(std::nullptr_t) :
+ AutoObject()
+ {
+ }
+
+ /**
+ * @brief Constructor
+ * @param[in] obj Source object to wrap
+ */
+ AutoObject(const OBJ_TYPE &obj) :
+ obj{obj}
+ {
+ }
+
+ /**
+ * @brief Destructor
+ * @details Calls DEL_FUNC on the object if it explicitly
+ * casts to "true"
+ */
+ ~AutoObject()
+ {
+ if (obj) {
+ DEL_FUNC(obj);
+ }
+ }
+
+ /**
+ * @brief Move constructor
+ * @details Source will be in the default constructed state
+ * @param[in] src Source of the move
+ */
+ AutoObject(AutoObject &&src) :
+ obj{src.obj}
+ {
+ src.obj = {};
+ }
+
+ /**
+ * @brief Assigns one AutoObject to another
+ * @details Only move assignment is possible. Original will be deleted.
+ * @param[in] src Source AutoObject
+ * @return Reference to this AutoObject
+ */
+ AutoObject &operator=(AutoObject src)
+ {
+ swap(*this, src);
+ return *this;
+ }
+
+ /**
+ * @brief Returns pointer to "obj" member
+ * @datails This is unsafe function, avoid using it. May use in
+ * templates to get the underlying object type.
+ */
+ OBJ_TYPE *operator&()
+ {
+ return &obj;
+ }
+
+ /**
+ * @brief Returns constant reference to "obj"
+ */
+ operator const OBJ_TYPE &() const
+ {
+ return obj;
+ }
+ };
+
+ // Non-member functions //
+
+ /**
+ * @brief Swaps AutoObject objects with each other
+ * @param[in/out] x First AutoObject
+ * @param[in/out] y Second AutoObject
+ */
+ template <class OBJ_TYPE, class DEL_RET, DEL_RET(*DEL_FUNC)(OBJ_TYPE)>
+ inline void swap(AutoObject<OBJ_TYPE, DEL_RET, DEL_FUNC> &x,
+ AutoObject<OBJ_TYPE, DEL_RET, DEL_FUNC> &y) noexcept
+ {
+ using std::swap;
+ swap(x.obj, y.obj);
+ }
+}
+
+#endif // __UCL_MISC_AUTO_HANDLE_H__
namespace ucl {
- class CString final : public NonCopyable {
+ /**
+ * @brief Represents managed mutable C-String
+ */
+ class CString final : protected NonCopyable {
public:
+ /**
+ * @brief Swaps CString objects with each other
+ * @param[in/out] x First theme object
+ * @param[in/out] y Second theme object
+ */
friend void swap(CString &x, CString &y) noexcept;
+ /**
+ * @brief Creates new CString object by duplicating source C-String
+ * @param[in] ptr Pointer to source C-String
+ * @details New C-String will be freed in destructor.
+ */
static CString dup(const char *ptr);
+
+ /**
+ * @brief Creates new CString object by taking over source C-String
+ * @param[in] ptr Pointer to source C-String
+ * @details Source C-String will be freed in destructor.
+ */
static CString takeover(char *ptr) noexcept;
+ /**
+ * @brief Defatult constructor
+ * @details Creates NULL CString object
+ */
CString() noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
CString(std::nullptr_t) noexcept;
+
+ /**
+ * @brief Move constructor
+ * @details Transfers ownership from source to the new object.
+ * Source string pointer will become NULL.
+ * @param[in] s Source CString object
+ */
CString(CString &&s) noexcept;
+
+ /**
+ * @brief Converting constructor
+ * @details Duplicates source std::string if it is not empty.
+ * If std::string is empty NULL CString object will be created.
+ * @param[in] s Source std::string object
+ */
CString(const std::string &s);
+
+ /**
+ * @brief Destructor
+ * @details Frees C-String pointer if not NULL
+ */
~CString() noexcept;
+ /**
+ * @brief Assigns one CString object to another
+ * @details Only move assignment is possible. Original will be deleted.
+ * @param[in] s Source CString object
+ * @return Reference to this CString object
+ */
CString &operator=(CString s) noexcept;
- bool isEmpty() const;
-
+ /**
+ * @brief Releases this CString object from C-String ownership
+ * @details This CString object will become NULL
+ * @return Pointer to underlying C-String
+ */
char *release() noexcept;
+ /**
+ * @brief Gets underlying C-String pointer;
+ * @return Pointer to underlying C-String
+ */
char *get() const noexcept;
private:
private:
char *m_ptr;
};
+
+ /**
+ * @brief Checks whether string is empty
+ * @details This is equivalent to: isEmpty(s.get());
+ * @param[in] s Reference to target CString object
+ * @return true if empty, false if not empty
+ */
+ bool isEmpty(const CString &s);
}
#include "CString.hpp"
return *this;
}
- inline bool CString::isEmpty() const
- {
- return !m_ptr;
- }
-
inline char *CString::release() noexcept
{
char *const result = m_ptr;
{
std::swap(x.m_ptr, y.m_ptr);
}
+
+ inline bool isEmpty(const CString &s)
+ {
+ return isEmpty(s.get());
+ }
}
namespace ucl {
- class ConstCString final : public NonCopyable {
+ /**
+ * @brief Represents managed constant C-String
+ */
+ class ConstCString final : protected NonCopyable {
public:
+ /**
+ * @brief Swaps ConstCString objects with each other
+ * @param[in/out] x First theme object
+ * @param[in/out] y Second theme object
+ */
friend void swap(ConstCString &x, ConstCString &y) noexcept;
+ /**
+ * @brief Creates new ConstCString object by wrapping source C-String
+ * @param[in] ptr Pointer to source C-String
+ * @details Source C-String will not be freed in destructor.
+ * Ownership can be transferred only using move constructors.
+ */
static ConstCString wrap(const char *ptr) noexcept;
+ /**
+ * @brief Defatult constructor
+ * @details Creates NULL ConstCString object
+ */
ConstCString() noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
ConstCString(std::nullptr_t) noexcept;
+
+ /**
+ * @brief Move constructor
+ * @details Transfers ownership from source to the new object.
+ * Source string pointer will not change.
+ * @param[in] s Source ConstCString object
+ */
ConstCString(ConstCString &&s) noexcept;
+
+ /**
+ * @brief Move constructor
+ * @details Transfers ownership from source to the new object.
+ * Source string pointer will become NULL.
+ * @param[in] s Source CString object
+ */
ConstCString(CString &&s) noexcept;
+
+ /**
+ * @brief Destructor
+ * @details Frees C-String pointer if owner
+ */
~ConstCString() noexcept;
+ /**
+ * @brief Assigns one ConstCString object to another
+ * @details Only move assignment is possible. Original will be deleted.
+ * @param[in] s Source ConstCString object
+ * @return Reference to this ConstCString object
+ */
ConstCString &operator=(ConstCString s) noexcept;
- bool isEmpty() const;
-
+ /**
+ * @brief Gets underlying C-String pointer;
+ * @return Pointer to underlying C-String
+ */
const char *get() const noexcept;
private:
const char *m_ptr;
bool m_isOwner;
};
+
+ /**
+ * @brief Checks whether string is empty
+ * @details This is equivalent to: isEmpty(s.get());
+ * @param[in] s Reference to target ConstCString object
+ * @return true if empty, false if not empty
+ */
+ bool isEmpty(const ConstCString &s);
}
#include "ConstCString.hpp"
return *this;
}
- inline bool ConstCString::isEmpty() const
- {
- return !m_ptr;
- }
-
inline const char *ConstCString::get() const noexcept
{
return m_ptr;
std::swap(x.m_ptr, y.m_ptr);
std::swap(x.m_isOwner, y.m_isOwner);
}
+
+ inline bool isEmpty(const ConstCString &s)
+ {
+ return isEmpty(s.get());
+ }
}
namespace ucl {
+ /**
+ * @brief Implements event dispatching using specified DELEGATE class
+ */
template <class DELEGATE>
class Event final {
public:
+ /**
+ * @brief Default constructor
+ */
Event();
+ /**
+ * @brief Adds new delegate to the delegate list
+ * @param[in] delegate Delagate object to add.
+ * DELEGATE2 must be convertible to DELEGATE
+ */
template <class DELEGATE2>
void operator+=(DELEGATE2 &&delegate);
+
+ /**
+ * @brief Removes existing delegate from the delegate list
+ * @param[in] delegate Delagate object to add.
+ * DELEGATE2 must be comparable with DELEGATE
+ */
template <class DELEGATE2>
void operator-=(const DELEGATE2 &delegate);
+ /**
+ * @brief Checks if the delegate list is empty
+ * @return true - the delegate list is empty, false - not empty
+ */
bool isEmpty() const;
+ /**
+ * @brief Dispatches event on delegates in list
+ * @details Delegates are called in order from old to new. If new
+ * delegates will be added in the dispatch process they will
+ * be ignored until next dispatch. It is possible to remove
+ * existing delegate from list. Removed delagate will not be
+ * invoked.
+ * @param[in] args Event dispatch arguments
+ */
template <class ...ARGS>
void dispatch(ARGS &&...args);
+
+ /**
+ * @brief Dispatches event on delegates using canceling predecate
+ * @details Same as dispatch() but with canceling predecate. Predicate
+ * is called on each delegate invoke with the return result of
+ * this invoke as single argument or no arguments if return
+ * type is void. Predicate must return true if dispatch should
+ * continue or false if it should stop. Result type of the
+ * predicate may be any object convertible to bool.
+ * @param[in] args Event dispatch arguments
+ */
template <class PREDICATE, class ...ARGS>
void dispatchPred(PREDICATE &&pred, ARGS &&...args);
void Event<DELEGATE>::operator-=(const DELEGATE2 &delegate)
{
const auto it = std::find(
- m_delegates.begin(), m_delegates.end(), delegate);
- if (it != m_delegates.end()) {
+ m_delegates.rbegin(), m_delegates.rend(), delegate);
+ if (it != m_delegates.rend()) {
if (isLocked()) {
*it = {};
m_isFragmented = true;
} else {
- m_delegates.erase(it);
+ m_delegates.erase(it.base() - 1);
}
}
}
void Event<DELEGATE>::dispatch(ARGS &&...args)
{
dispatchImpl(
- [](const DELEGATE &delegate, ARGS &&...args)
+ [](const typename DELEGATE::LockDelegate &delegate, ARGS &&...args)
{
delegate(std::forward<ARGS>(args)...);
return true;
void Event<DELEGATE>::dispatchPred(PREDICATE &&pred, ARGS &&...args)
{
dispatchImpl(
- [&pred](const DELEGATE &delegate, ARGS &&...args)
+ [&pred](const typename DELEGATE::LockDelegate &delegate,
+ ARGS &&...args)
{
return impl::doInvokePred(std::forward<PREDICATE>(pred),
delegate, std::forward<ARGS>(args)...);
lock();
const auto size = m_delegates.size();
for (size_t i = 0; i < size; ++i) {
- const auto &delegate = m_delegates[i];
- if (delegate) {
+ if (const auto delegate = m_delegates[i].lock()) {
if (!doInvoke(delegate, std::forward<ARGS>(args)...)) {
break;
}
using VarDict = Dict<Variant>;
+ /**
+ * @brief Represents simple to use HashMap collection
+ * @details Enumerations are supported as KEY type. Custom hashing function
+ * may be specified for KEY using nested KEY::Hash functor.
+ */
template <class KEY, class VALUE>
class HashMap final {
public:
+ /**
+ * @brief Sets value with specified key to the map
+ * @details Overrides existing values
+ * @param[in] key Key of the value
+ * @param[in] value Value
+ * @return Reference to this hashMap object
+ */
template <class VALUE2>
HashMap &set(const KEY &key, VALUE2 &&value);
+
+ /**
+ * @brief Unsets value with specified key from the map
+ * @details Removes existing value or do nothing
+ * @param[in] key Key of the value
+ * @return Reference to this hashMap object
+ */
HashMap &unset(const KEY &key);
+ /**
+ * @brief Gets value with specified key from the map
+ * @param[in] key Key of the value
+ * @param[out] value Existing value if exists
+ * @return true - if value with key exists, false - not exists
+ */
template <class VALUE2>
bool get(const KEY &key, VALUE2 &value) const;
+
+ /**
+ * @brief Gets value with specified key from the map
+ * @param[in] key Key of the value
+ * @return Existing value if exists, or {} if not exists
+ */
VALUE get(const KEY &key) const;
+ /**
+ * @brief Removes all values from the map
+ */
void clear();
private:
UCL_DECLARE_REF_ALIASES(RefCountAware);
- class RefCountAware : public Polymorphic {
+ /**
+ * @brief Base class for objects that aware if they are shared or not
+ */
+ class RefCountAware : protected NonCopyable {
public:
+ /**
+ * @brief Returns shared state of the object
+ * @return true - object is shared, false - no shared
+ */
bool isShared() const;
+
+ /**
+ * @brief Returns count of shared references to this object if shared
+ * @return Count of shared references (0 on error)
+ */
UInt getUseCount() const;
+
+ /**
+ * @brief Gets pointer to the allocated storage of this object
+ * @details Matches "this" of the instance's class.
+ * @return Pointer to the allocated storage of this object
+ */
const void *getObjPtr() const;
+ /**
+ * @brief Creates shared reference to T from "this" pointer
+ * @param[in] thisAlias Pointer to "this" implicitly converted to "T *"
+ * @return Shared reference to T
+ */
template <class T>
SharedRef<T> asSharedThis(T *thisAlias) const;
+ /**
+ * @brief Creates weak reference to T from "this" pointer
+ * @param[in] thisAlias Pointer to "this" implicitly converted to "T *"
+ * @return Weak reference to T
+ */
template <class T>
WeakRef<T> asWeakThis(T *thisAlias) const;
protected:
+ /**
+ * @brief Constructor
+ * @param[in] rc Pointer to IRefCountObj (may be NULL)
+ */
RefCountAware(IRefCountObj *rc);
- virtual ~RefCountAware() = default;
+
+ /**
+ * @brief Destructor
+ */
+ ~RefCountAware() = default;
+
+ private:
+ virtual void polymorphismEnabler() final {}
public:
// This section MUST be public!
// Non-member functions //
+ /**
+ * @brief Creates shared reference to specified object
+ * @param[in] obj Reference to target object
+ * @return Shared reference to specified object or NULL
+ */
template <class T>
SharedRef<T> asShared(T &obj);
+
+ /**
+ * @brief Creates shared reference to specified object
+ * @param[in] obj Pointer to target object
+ * @return Shared reference to specified object or NULL
+ */
template <class T>
SharedRef<T> asShared(T *obj);
+ /**
+ * @brief Creates weak reference to specified object
+ * @param[in] obj Reference to target object
+ * @return Weak reference to specified object or NULL
+ */
template <class T>
WeakRef<T> asWeak(T &obj);
+
+ /**
+ * @brief Creates weak reference to specified object
+ * @param[in] obj Pointer to target object
+ * @return Weak reference to specified object or NULL
+ */
template <class T>
WeakRef<T> asWeak(T *obj);
+ /**
+ * @brief Creates shared reference to T from specified object
+ * @param[in] obj Reference to target object
+ * @return Shared reference to specified object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, U>::value>::type>
SharedRef<T> asShared(U &obj);
+
+ /**
+ * @brief Creates shared reference to T from specified object
+ * @param[in] obj Pointer to target object
+ * @return Shared reference to specified object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, U>::value>::type>
SharedRef<T> asShared(U *obj);
+ /**
+ * @brief Creates weak reference to T from specified object
+ * @param[in] obj Reference to target object
+ * @return Weak reference to specified object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, U>::value>::type>
WeakRef<T> asWeak(U &obj);
+
+ /**
+ * @brief Creates weak reference to T from specified object
+ * @param[in] obj Pointer to target object
+ * @return Weak reference to specified object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, U>::value>::type>
WeakRef<T> asWeak(U *obj);
+ /**
+ * @brief Creates shared reference to T from specified constant object
+ * @param[in] obj Reference to target constant object
+ * @return Shared reference to specified constant object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, const U>::value>::type>
SharedRef<const T> asShared(const U &obj);
+
+ /**
+ * @brief Creates shared reference to T from specified constant object
+ * @param[in] obj Pointer to target constant object
+ * @return Shared reference to specified constant object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, const U>::value>::type>
SharedRef<const T> asShared(const U *obj);
+ /**
+ * @brief Creates weak reference to T from specified constant object
+ * @param[in] obj Reference to target constant object
+ * @return Weak reference to specified constant object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, const U>::value>::type>
WeakRef<const T> asWeak(const U &obj);
+
+ /**
+ * @brief Creates weak reference to T from specified constant object
+ * @param[in] obj Pointer to target constant object
+ * @return Weak reference to specified constant object as T
+ */
template <class T, class U, class = typename
std::enable_if<!std::is_same<T, const U>::value>::type>
WeakRef<const T> asWeak(const U *obj);
namespace ucl {
+ /**
+ * @brief Represents translatable string
+ */
class TString final {
public:
+ /**
+ * @brief Default constructor
+ * @datails Creates empty string
+ */
TString();
/**
- * Constructs TString from std::string and domain
- *
- * @param str Text string or string id if translatable.
- * @param domain Valid domain name or "" for default domain,
- * nullptr - if string is not translatable
+ * @brief Constructor
+ * @details Constructs TString from std::string and domain
+ * @param[in] str Text string or string id if translatable
+ * @param[in] domain Valid domain name or "" for default domain,
+ * NULL - if string is not translatable
*/
TString(const std::string &str, const char *domain);
+
+ /**
+ * @brief Constructor
+ * @details Constructs TString from std::string
+ * @param[in] str Text string or string id if translatable.
+ * @param[in] translatable true - translate using default domain,
+ * false - if string is not translatable
+ */
TString(const std::string &str, bool translatable = false);
+ /**
+ * @brief Constructor
+ * @details Constructs TString from temporrary std::string and domain
+ * @param[in] str Temporrary text string or string id if translatable
+ * @param[in] domain Valid domain name or "" for default domain,
+ * NULL - if string is not translatable
+ */
TString(std::string &&str, const char *domain);
+
+ /**
+ * @brief Constructor
+ * @details Constructs TString from temporrary std::string
+ * @param[in] str Temporrary text string or string id if translatable.
+ * @param[in] translatable true - translate using default domain,
+ * false - if string is not translatable
+ */
TString(std::string &&str, bool translatable = false);
+ /**
+ * @brief Constructor
+ * @details Constructs TString from C-String and domain
+ * @param[in] str Text string or string id if translatable
+ * @param[in] domain Valid domain name or "" for default domain,
+ * NULL - if string is not translatable
+ */
TString(const char *str, const char *domain);
+
+ /**
+ * @brief Constructor
+ * @details Constructs TString from C-String
+ * @param[in] str Text string or string id if translatable.
+ * @param[in] translatable true - translate using default domain,
+ * false - if string is not translatable
+ */
TString(const char *str, bool translatable = false);
+ /**
+ * @brief Checks if string is empty
+ * @return true - if empty, false - if not empty
+ */
bool isEmpty() const;
+ /**
+ * @brief Gets translatable state of the string
+ * @return true - if translatable, false - if not translateable
+ */
bool isTranslatable() const;
+
+ /**
+ * @brief Checks if string has translatable domain
+ * @return true - if has domain, false - otherwise (domain is NULL)
+ */
bool hasDomain() const;
+
+ /**
+ * @brief Gets translatable domain of the string
+ * @return Translatable domain of the string,
+ * "" - default,
+ * NULL - not translatable
+ */
const char *getDomain() const;
+ /**
+ * @brief Gets underlying std::string of the string
+ * @return Constant reference to the underlying std::string
+ */
const std::string &getStr() const;
+
+ /**
+ * @brief Casts to underlying std::string of the string
+ * @return Constant reference to the underlying std::string
+ */
operator const std::string &() const;
+ /**
+ * @brief Gets C-String of the underlying std::string
+ * @return Underlying C-String of the underlying std::string
+ */
const char *getCStr() const;
+
+ /**
+ * @brief Casts to C-String of the underlying std::string
+ * @return Underlying C-String of the underlying std::string
+ */
operator const char *() const;
+ /**
+ * @brief Translates the string if translatable
+ * @return Translated string or original if not translated
+ */
const char *translate() const;
+ /**
+ * @brief Formats translation (if translatable) of the string
+ * @param[in] args Format arguments
+ * @return Formatted translation (if translatable) of the string
+ */
template <typename ...ARGS>
std::string format(ARGS ...args) const;
UCL_DECLARE_REF_ALIASES(Timeout);
- class Timeout final : public NonCopyable {
+ /**
+ * @brief Eecutes specific action after specified timeout
+ */
+ class Timeout final : protected NonCopyable {
public:
+ /**
+ * @brief Delegate of the timeout action
+ */
using TimeoutHandler = WeakDelegate<void(Timeout *sender)>;
public:
- static TimeoutSRef create(double timeoutSec,
- const TimeoutHandler &handler);
+ /**
+ * @brief Creates new Timeout object
+ * @param[in] timeoutSec Timeout value in seconds
+ * @param[in] handler Action of the timeout
+ * @return Shared reference to new Timeout object
+ */
+ static TimeoutSRef create(double timeoutSec, TimeoutHandler handler);
+ /**
+ * @brief Gets expiration status of the timeout
+ * @return true - timeout is already expired, false - in progress
+ */
bool isExpired() const;
private:
- friend class ReffedObj<Timeout>;
- Timeout(const TimeoutHandler &handler);
+ Timeout(TimeoutHandler handler, Private);
~Timeout();
Result prepare(double timeoutSec);
Eina_Bool onTimer();
private:
+ const TimeoutHandler m_handler;
Ecore_Timer *m_timer;
- TimeoutHandler m_handler;
+
+ friend class ReffedObj<Timeout>;
};
}
template <size_t N>
using VarArray = std::array<Variant, N>;
- struct VarInitList final {
- VarInitList(const std::initializer_list<Variant> &il) : il(il) {}
- const std::initializer_list<Variant> &il;
- };
-
+ /**
+ * @brief Represents value with dynamic type
+ */
class Variant final {
public:
+ /**
+ * @brief Enumeration of possible value types
+ */
enum Type {
TYPE_NIL,
TYPE_BOOLEAN,
};
public:
+ /**
+ * @brief Swaps Variant objects with each other
+ * @param[in/out] x First theme object
+ * @param[in/out] y Second theme object
+ */
friend void swap(Variant &x, Variant &y) noexcept;
+ /**
+ * @brief Compares equals two Variant objects by value
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
friend bool operator==(const Variant &lhs, const Variant &rhs) noexcept;
+
+ /**
+ * @brief Compares unequals two Variant objects by value
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
friend bool operator!=(const Variant &lhs, const Variant &rhs) noexcept;
public:
+ /**
+ * @brief Default constructor
+ * @details Creates TYPE_NIL value
+ */
Variant() noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Same as deafult constructor
+ */
Variant(std::nullptr_t) noexcept;
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_BOOLEAN value
+ * @param[in] aBool Source value
+ */
Variant(bool aBool) noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_INTEGER value
+ * @param[in] anInt Source value
+ */
Variant(int anInt) noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_FLOAT value
+ * @param[in] aFloat Source value
+ */
Variant(float aFloat) noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_DOUBLE value
+ * @param[in] aDouble Source value
+ */
Variant(double aDouble) noexcept;
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_STRING value
+ * @param[in] aString NULL-terminated source value
+ */
Variant(const char *aString);
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_STRING value
+ * @param[in] aString Source value
+ * @param[in] length Length of the string
+ */
Variant(const char *aString, int length);
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_STRING value
+ * @param[in] aString Source value
+ */
Variant(const std::string &aString);
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_ARRAY value
+ * @param[in] <std::nullptr_t> nullptr for all TYPE_NIL elements
+ * @param[in] arrayLength Length of the array
+ */
Variant(std::nullptr_t, int arrayLength);
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_ARRAY value
+ * @param[in] anArray Source Variant C-Array
+ * @param[in] length Length of the array
+ */
Variant(const Variant *anArray, int length);
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_ARRAY value
+ * @param[in] anArray Source std::vector<Variant>
+ */
Variant(const VarVector &anArray);
+
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_ARRAY value
+ * @param[in] anArray Source std::array<Variant, N>
+ */
template <size_t N>
Variant(const VarArray<N> &anArray);
- Variant(const VarInitList &anArray);
+ /**
+ * @brief Constructor
+ * @details Creates TYPE_ARRAY value
+ * @param[in] anArray Source std::initializer_list<Variant>
+ */
+ Variant(std::initializer_list<Variant> anArray);
+
+ /**
+ * @brief Destructor
+ */
~Variant();
+ /**
+ * @brief Copy constructor
+ * @param[in] v Source value
+ */
Variant(const Variant &v);
+
+ /**
+ * @brief Move constructor
+ * @param[in] v Source value
+ */
Variant(Variant &&v) noexcept;
+ /**
+ * @brief Assigns one Variant object to another
+ * @param[in] v Source value
+ * @return Reference to this Variant object
+ */
Variant &operator=(Variant v);
+ /**
+ * @brief Gets type of the variant value
+ * @return Type of the value
+ */
Type getType() const noexcept;
+
+ /**
+ * @brief Gets lengths of the value
+ * @return Lengths of string/array, 1 for other types and 0 for TYPE_NIL
+ */
int getLength() const noexcept;
+
+ /**
+ * @brief Checks whether variant is empty
+ * @details This is equivalent to: (getLength() == 0);
+ * @return true if empty, false if not empty
+ */
bool isEmpty() const noexcept;
+ /**
+ * @brief Reads current variant value as bool
+ * @return Value of the variant converted to bool:
+ * as is - for boolean;
+ * true - (numeric values != 0);
+ * true - string in case insensitive
+ * ("true", "yes", "ok", "on", "1");
+ * true - (array length != 0);
+ * false - otherwise
+ */
bool asBool() const noexcept;
+
+ /**
+ * @brief Reads current variant value as int
+ * @return Value of the variant converted to int:
+ * static_cast<int>() - all numeric values;
+ * std::atoi() - for string;
+ * length - for array;
+ * 0 - otherwise
+ */
int asInt() const noexcept;
+
+ /**
+ * @brief Reads current variant value as float
+ * @return Value of the variant converted to float:
+ * static_cast<float>() - all numeric values;
+ * static_cast<float>(std::atof()) - for string;
+ * static_cast<float>(length) - for array;
+ * 0.0f - otherwise
+ */
float asFloat() const noexcept;
+
+ /**
+ * @brief Reads current variant value as double
+ * @return Value of the variant converted to double:
+ * static_cast<double>() - all numeric values;
+ * std::atof() - for string;
+ * static_cast<double>(length) - for array;
+ * 0.0 - otherwise
+ */
double asDouble() const noexcept;
+ /**
+ * @brief Reads current variant value as string
+ * @return Value of the variant converted to string:
+ * as is - for string
+ * "true"|"false" - for boolean;
+ * printf("%d") - integer, array length;
+ * printf("%f") - float and double;
+ * "" - otherwise
+ */
ConstCString asString() const noexcept;
+ /**
+ * @brief Reads current variant value as Variant C-Array
+ * @return Value of the variant converted as Variant C-Array
+ * as is - for array
+ * this - for simple value
+ */
Variant *asArray() noexcept;
+
+ /**
+ * @brief Reads current variant value as constant Variant C-Array
+ * @return Value of the variant converted as constant Variant C-Array
+ * as is - for array
+ * this - for simple value
+ */
const Variant *asArray() const noexcept;
+ /**
+ * @brief Gets begin iterator of this variant as an array
+ * @return Begin iterator
+ */
Variant *begin() noexcept;
+
+ /**
+ * @brief Gets end iterator of this variant as an array
+ * @return End iterator
+ */
Variant *end() noexcept;
+
+ /**
+ * @brief Gets begin constant iterator of this variant as an array
+ * @return Begin constant iterator
+ */
const Variant *begin() const noexcept;
+
+ /**
+ * @brief Gets end constant iterator of this variant as an array
+ * @return End constant iterator
+ */
const Variant *end() const noexcept;
+ /**
+ * @brief Gets indexed element of this variant as an array
+ * @param[in] index Index of the element
+ * @return Reference to indexed element
+ */
Variant &operator[](int index) noexcept;
+
+ /**
+ * @brief Gets indexed constant element of this variant as an array
+ * @param[in] index Index of the element
+ * @return Reference to indexed constant element
+ */
const Variant &operator[](int index) const noexcept;
+ /**
+ * @brief Explicitly casts to bool
+ * @details Same as asBool()
+ * @return Value of the variant converted to bool
+ */
explicit operator bool() const noexcept;
+
+ /**
+ * @brief Explicitly casts to int
+ * @details Same as asInt()
+ * @return Value of the variant converted to int
+ */
explicit operator int() const noexcept;
+
+ /**
+ * @brief Explicitly casts to float
+ * @details Same as asFloat()
+ * @return Value of the variant converted to float
+ */
explicit operator float() const noexcept;
+
+ /**
+ * @brief Explicitly casts to double
+ * @details Same as asDouble()
+ * @return Value of the variant converted to double
+ */
explicit operator double() const noexcept;
+ /**
+ * @brief Compares equals Variant object type with other type
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
bool operator==(Variant::Type rhs) const noexcept;
+
+ /**
+ * @brief Compares unequals Variant object type with other type
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
bool operator!=(Variant::Type rhs) const noexcept;
private:
const char *getStr() const noexcept;
- public:
+ private:
union {
uint8_t m_type;
struct {
{
}
- inline Variant::Variant(const VarInitList &anArray) :
- Variant(anArray.il.begin(), anArray.il.size())
+ inline Variant::Variant(std::initializer_list<Variant> anArray) :
+ Variant(anArray.begin(), anArray.size())
{
}
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UCL_MISC_TYPES_H__
+#define __UCL_MISC_TYPES_H__
+
+#include "ucl/util/smartDelegation.h"
+
+namespace ucl {
+
+ /**
+ * @brief Represents delegate to handle simple notification events
+ */
+ using NotiHandler = WeakDelegate<void()>;
+}
+
+#endif // __UCL_MISC_TYPES_H__
UCL_DECLARE_REF_ALIASES(GuiPresenter);
+ /**
+ * @brief Base class for presenters with GUI
+ */
class GuiPresenter : public RefCountAware {
public:
+ /**
+ * @brief Information about deactivator that used in events
+ */
struct DeactivatorInfo final {
+ /**
+ * @brief Deactivator pointer
+ */
const void *deactivator;
+ /**
+ * @brief true - deactivator was broadcasted, false - otherwise
+ */
bool isBroadcast;
};
public:
+ /**
+ * @brief Gets activation status
+ * @return true - if presenter is active, false - if not active
+ */
bool isActive() const;
+
+ /**
+ * @brief Checks whether this presenter is deactivated
+ * by specific deactivator
+ * @param[in] deactivator Pointer to the target deactivator
+ * @return true - if deactivated by the deactivator, false - otherwise
+ */
bool isDeactivatedBy(const void *deactivator) const;
+ /**
+ * @brief Activates the presenter by specific deactivator
+ * @details If this presenter was not deactivated by the deactivator
+ * this function has no effect, otherwise deactivation
+ * imposed by the deactivator is lifted. Deactivator exception
+ * does not affect this function.
+ * @param[in] deactivator Pointer to the target deactivator
+ */
void activateBy(const void *deactivator);
+
+ /**
+ * @brief Deactivates the presenter by specific deactivator
+ * @details If this presenter is already deactivated by the deactivator
+ * or listed in the deactivator exception list this function
+ * has no effect, otherwise this presenter becomes deactivated
+ * by the deactivator.
+ * @param[in] deactivator Pointer to the target deactivator
+ */
void deactivateBy(const void *deactivator);
+ /**
+ * @brief Registers specific widget as a deactivator source
+ * @details This presenter will be automatically activated/deactivated
+ * by the events send by the widget. These events may be send
+ * directly by the call to sendActivate()/sendDeactivate()
+ * methods or through parant's deactivator sink.
+ * @param[in] source Reference to the deactivator source widget
+ */
void addDeactivatorSource(Widget &source);
+
+ /**
+ * @brief Deregisters specific widget as a deactivator source
+ * @param[in] source Reference to the deactivator source widget
+ */
void delDeactivatorSource(Widget &source);
protected:
+ /**
+ * @brief Enumeration of preparation flags
+ */
enum {
+ /**
+ * @brief Indicates that new presenter needs to be automatically
+ * activated/deactivated by it's parent or broadcast events
+ * @details This flag is needed for all presenters that needs to use
+ * isActive() property, which should be all presenters
+ * processing user events. Presenters that only display
+ * information (PASSIVE) does not require this flag.
+ */
PF_ADD_DEACTIVATOR_SOURCES = 1,
+
+ /**
+ * @brief Indicates that new presenter needs to add self to the
+ * deactivator exception list
+ * @details This flag is needed for all presenters that emit
+ * activate/deactivate events (DEACTIVATORs) because there
+ * is a big chance that this events may return to the
+ * calling presenter and cause undesired effect.
+ */
PF_ADD_SELF_EXCEPT = 2,
+ /**
+ * @brief Helper flag set to use for PASSIVE presenters
+ */
PF_PASSIVE = 0,
+
+ /**
+ * @brief Helper flag set to use for DEACTIVATOR presenters
+ */
PF_DEACTIVATOR = (PF_ADD_DEACTIVATOR_SOURCES | PF_ADD_SELF_EXCEPT),
+
+ /**
+ * @brief Helper flag set to use for not PASSIVE not DEACTIVATOR
+ * presenters
+ */
PF_DEFAULT = PF_ADD_DEACTIVATOR_SOURCES
};
protected:
+ /**
+ * @brief Constructor
+ * @param[in] rc Pointer to IRefCountObj (passed automatically)
+ */
GuiPresenter(IRefCountObj &rc);
- virtual ~GuiPresenter();
+ /**
+ * @brief Destructor
+ */
+ ~GuiPresenter();
+
+ /**
+ * @brief Prepares this presenter instance as a root presenter
+ * @details Specified widget must have a Window as a top level parent.
+ * @param[in] widget Any widget to which tree this presenter
+ * should belong
+ * @param[in] flags Preparation flags (optional: PF_DEFAULT)
+ * @retrun RES_OK on success, error otherwise
+ */
Result prepare(ElmWidget &widget, int flags = PF_DEFAULT);
+
+ /**
+ * @brief Prepares this presenter instance as a child presenter
+ * @details Parent presenter must have deactivator sink registered
+ * unless this presenter does not specify
+ * PF_ADD_DEACTIVATOR_SOURCES flag.
+ * @param[in] parent Reference to the parent presenter
+ * @param[in] flags Preparation flags (optional: PF_DEFAULT)
+ * @retrun RES_OK on success, error otherwise
+ */
Result prepare(GuiPresenter &parent, int flags = PF_DEFAULT);
+ /**
+ * @brief Gets reference to the Window widget
+ * @details If Window was not initialized application will terminate
+ * with assertion.
+ */
Window &getWindow();
- bool isWindowReady() const;
+ /**
+ * @brief Gets shared reference to the Window widget
+ * @details Use in destructor and check for NULL, because destructor
+ * is always called event after prepare() failure
+ * (Window may be not initialized yet).
+ */
+ WindowSRef getWindowRef();
+
+ /**
+ * @brief Adds specific deactivator as exception
+ * @details All deactivating functionality will ignore specified
+ * deactivator. Note however that this does not cancel any
+ * deactivation effect that was imposed by this deactivator
+ * before adding exception. Therefore, activation functionality
+ * will work fo this deactivator.
+ * @param[in] deactivator Pointer to the target deactivator
+ */
void addDeactivatorException(const void *deactivator);
+
+ /**
+ * @brief Sets specified widget as deactivator sink fo this presenter
+ * @details All activate/deactivate actions that occurs on this
+ * presenter will be send as events on this widget. This
+ * function needs to be called if this presenter may be a
+ * parent for other presenters. This will enable propagation of
+ * activate/deactivate actions from parent to children.
+ * @param[in] sink Shared reference to the event sink widget
+ */
void setDeactivatorSink(const WidgetSRef &sink);
+ /**
+ * @brief Gets deactivator that can be used for self deactivation
+ * @details Self deactivator pointer is garanteed to be unique and
+ * unknown for external code. So it is not possible to
+ * accidentally deactivate this presenter by this deactivator
+ * from external code.
+ * @return Pointer to the deactivator
+ */
+ const void *getSelfDeactivator() const;
+
+ /**
+ * @brief Activates self using self deactivator
+ */
+ void activateSelf();
+
+ /**
+ * @brief Deactivates self using self deactivator
+ */
+ void deactivateSelf();
+
+ /**
+ * @brief Sends activation event using specified widget sender
+ * @details All presenters that added this widget as a deactivator
+ * source will be activate by this event.
+ * @param[in] sender Reference to sender widgets
+ */
void sendActivate(Widget &sender);
+
+ /**
+ * @brief Sends deactivation event using specified widget sender
+ * @details All presenters that added this widget as a deactivator
+ * source will be deactivated by this event.
+ * @param[in] sender Reference to sender widgets
+ */
void sendDeactivate(Widget &sender);
+ /**
+ * @brief Broadcasts activation event
+ * @details All root presenters with PF_ADD_DEACTIVATOR_SOURCES flag
+ * will be activate by this event.
+ */
void broadcastActivate();
+
+ /**
+ * @brief Broadcasts deactivation event
+ * @details All root presenters with PF_ADD_DEACTIVATOR_SOURCES flag
+ * will be deactivated by this event.
+ */
void broadcastDeactivate();
+ /**
+ * @brief Occurs when this presenter becomes active
+ * @details This event occurs after onActivateBy().
+ */
virtual void onActivate();
+
+ /**
+ * @brief Occurs when this presenter becomes inactive
+ * @details This event occurs after onDeactivateBy().
+ */
virtual void onDeactivate();
+
+ /**
+ * @brief Occurs when this presenter is first time activated by
+ * specific deactivator
+ * @details This event occurs after processing the deactivator sink.
+ * @param[in] info Deactivator info of the deactivator
+ */
virtual void onActivateBy(const DeactivatorInfo &info);
+
+ /**
+ * @brief Occurs when this presenter is first time deactivated by
+ * specific deactivator
+ * @details This event occurs after processing the deactivator sink.
+ * @param[in] info Deactivator info of the deactivator
+ */
virtual void onDeactivateBy(const DeactivatorInfo &info);
private:
private:
std::unordered_set<const void *> m_deactivatorExceptions;
std::unordered_set<const void *> m_deactivators;
- WindowSRef m_window;
+ WindowWRef m_window;
WidgetSRef m_sink;
WidgetWRef m_parentSink;
bool m_hasBuildInSources;
template <class FUNC_SIG, class DATA>
class BaseDelegate2;
+ /**
+ * @brief Base class for implementing delegates with 1 function stub
+ */
template <class R, class ...ARGS, class DATA>
class BaseDelegate<R(ARGS...), DATA> {
public:
+ /**
+ * @brief Callback of this delegate
+ */
using Cb = Callback<R(ARGS...)>;
+
+ /**
+ * @brief StubA function pointer type of this delegate
+ */
using StubA = typename Cb::StubA;
public:
+ /**
+ * @brief Default constructor
+ * @details Creates NULL delegate
+ */
constexpr BaseDelegate() noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Safe as default constructor
+ */
constexpr BaseDelegate(std::nullptr_t) noexcept;
+ /**
+ * @brief Conversion constructor from BaseDelegate2
+ * @param[in] d Source delegate
+ */
template <class FUNC_SIG>
BaseDelegate(const BaseDelegate2<FUNC_SIG, DATA> &d) noexcept;
+
+ /**
+ * @brief Conversion move constructor from BaseDelegate2
+ * @param[in] d Source delegate
+ */
template <class FUNC_SIG>
BaseDelegate(BaseDelegate2<FUNC_SIG, DATA> &&d) noexcept;
+ /**
+ * @brief Resets this delegate to NULL
+ */
void reset() noexcept;
+ /**
+ * @brief Gets bound object data pointer
+ * @details May be used to invoke this delegate from C code.
+ * @return Bound object data pointer
+ */
const DATA &getData() const noexcept;
+
+ /**
+ * @brief Gets bound StubA function pointer
+ * @details May be used to invoke this delegate from C code.
+ * @return Pointer to bound StubA function
+ */
StubA getStubA() const noexcept;
- operator bool() const noexcept;
+
+ /**
+ * @brief Checks if this delegate is not NULL
+ * @return true - if not NULL, false - if NULL
+ */
+ explicit operator bool() const noexcept;
protected:
- BaseDelegate(const DATA &data, StubA stubA) noexcept;
+ /**
+ * @brief Constructor
+ * @param[in] data Object data pointer
+ * @param[in] stubA StubA function pointer
+ */
+ BaseDelegate(DATA data, StubA stubA) noexcept;
+
+ /**
+ * @brief Destructor
+ */
+ ~BaseDelegate() = default;
protected:
+ /**
+ * @brief Bound object data pointer
+ */
DATA m_data;
+
+ /**
+ * @brief Bound StubA function pointer
+ */
StubA m_stubA;
};
}
template <class R, class ...ARGS, class DATA>
inline BaseDelegate<R(ARGS...), DATA>::
- BaseDelegate(const DATA &data, StubA stubA) noexcept :
- m_data(data),
+ BaseDelegate(DATA data, StubA stubA) noexcept :
+ m_data(std::move(data)),
m_stubA(stubA)
{
}
template <class FUNC_SIG, class DATA>
class BaseDelegate2;
+ /**
+ * @brief Base class for implementing delegates with 2 function stub
+ */
template <class R, class ...ARGS, class DATA>
class BaseDelegate2<R(ARGS...), DATA> :
public BaseDelegate<R(ARGS...), DATA> {
public:
+ /**
+ * @brief Callback of this delegate
+ */
using Cb = typename BaseDelegate2::Cb;
+
+ /**
+ * @brief StubA function pointer type of this delegate
+ */
using StubA = typename Cb::StubA;
+
+ /**
+ * @brief StubB function pointer type of this delegate
+ */
using StubB = typename Cb::StubB;
public:
using BaseDelegate<R(ARGS...), DATA>::BaseDelegate;
+ /**
+ * @brief Gets bound StubB function pointer
+ * @details May be used to invoke this delegate from C code.
+ * @return Pointer to bound StubB function
+ */
StubB getStubB() const noexcept;
protected:
- BaseDelegate2(const DATA &data, StubA stubA, StubB stubB) noexcept;
+ /**
+ * @brief Constructor
+ * @param[in] data Object data pointer
+ * @param[in] stubA StubA function pointer
+ * @param[in] stubB StubB function pointer
+ */
+ BaseDelegate2(DATA data, StubA stubA, StubB stubB) noexcept;
+
+ /**
+ * @brief Destructor
+ */
+ ~BaseDelegate2() = default;
private:
+ /**
+ * @brief Bound StubB function pointer
+ */
StubB m_stubB;
};
}
template <class R, class ...ARGS, class DATA>
inline BaseDelegate2<R(ARGS...), DATA>::
- BaseDelegate2(const DATA &data, StubA stubA, StubB stubB) noexcept :
- BaseDelegate<R(ARGS...), DATA>(data, stubA),
+ BaseDelegate2(DATA data, StubA stubA, StubB stubB) noexcept :
+ BaseDelegate<R(ARGS...), DATA>(std::move(data), stubA),
m_stubB(stubB)
{
}
template <class FUNC_SIG>
class Callback;
+ /**
+ * @brief Generates function stubs to use in callbacks and delegates
+ */
template <class R, class ...ARGS>
class Callback<R(ARGS...)> {
public:
+ /**
+ * @brief StubA function pointer type
+ * @details This function takes data argument as first parameter
+ */
using StubA = R(*)(void *, ARGS...);
+
+ /**
+ * @brief StubB function pointer type
+ * @details This function takes data argument as last parameter
+ */
using StubB = R(*)(ARGS..., void *);
public:
+ /**
+ * @brief Wraps instance method as StubA
+ * @param[in] data This pointer of the instance
+ * @param[in] args Method arguments
+ * @return R Result of the method call
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
static R stubA(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps instance method as StubB
+ * @param[in] args Method arguments
+ * @param[in] data This pointer of the instance
+ * @return R Result of the method call
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
static R stubB(ARGS ...args, void *data);
+ /**
+ * @brief Wraps constant instance method as StubA
+ * @param[in] data This pointer of the instance
+ * @param[in] args Method arguments
+ * @return R Result of the method call
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
static R stubA(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps constant instance method as StubB
+ * @param[in] args Method arguments
+ * @param[in] data This pointer of the instance
+ * @return R Result of the method call
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
static R stubB(ARGS ...args, void *data);
+ /**
+ * @brief Wraps StubA-style function taking object as StubA
+ * @param[in] data Pointer of the object
+ * @param[in] args Function arguments
+ * @return R Result of the function call
+ */
template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
static R stubA2A(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps StubA-style function taking object as StubB
+ * @param[in] args Function arguments
+ * @param[in] data Pointer of the object
+ * @return R Result of the function call
+ */
template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
static R stubB2A(ARGS ...args, void *data);
+ /**
+ * @brief Wraps StubB-style function taking object as StubA
+ * @param[in] data Pointer of the object
+ * @param[in] args Function arguments
+ * @return R Result of the function call
+ */
template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
static R stubA2B(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps StubB-style function taking object as StubB
+ * @param[in] args Function arguments
+ * @param[in] data Pointer of the object
+ * @return R Result of the function call
+ */
template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
static R stubB2B(ARGS ...args, void *data);
+ /**
+ * @brief Wraps StubA-style function taking object handle as StubA
+ * @param[in] data Handle of the object
+ * @param[in] args Function arguments
+ * @return R Result of the function call
+ */
template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
static R stubA2A(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps StubA-style function taking object handle as StubB
+ * @param[in] args Function arguments
+ * @param[in] data Handle of the object
+ * @return R Result of the function call
+ */
template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
static R stubB2A(ARGS ...args, void *data);
+ /**
+ * @brief Wraps StubB-style function taking object handle as StubA
+ * @param[in] data Handle of the object
+ * @param[in] args Function arguments
+ * @return R Result of the function call
+ */
template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
static R stubA2B(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps StubB-style function taking object handle as StubB
+ * @param[in] args Function arguments
+ * @param[in] data Handle of the object
+ * @return R Result of the function call
+ */
template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
static R stubB2B(ARGS ...args, void *data);
+ /**
+ * @brief Wraps static function as StubA
+ * @param[in] data Not used
+ * @param[in] args Function arguments
+ * @return R Result of the function call
+ */
template <R(*FUNC)(ARGS...)>
static R stubA2V(void *data, ARGS ...args);
+
+ /**
+ * @brief Wraps static function as StubB
+ * @param[in] args Function arguments
+ * @param[in] data Not used
+ * @return R Result of the function call
+ */
template <R(*FUNC)(ARGS...)>
static R stubB2V(ARGS ...args, void *data);
+
+ private:
+ Callback() = delete;
};
}
template <class FUNC_SIG>
class Delegate;
+ /**
+ * @brief Delegate that uses "void *" as data pointer
+ */
template <class R, class ...ARGS>
class Delegate<R(ARGS...)> : public BaseDelegate<R(ARGS...), void *> {
+ public:
+ /**
+ * @brief Result delegate of the lock() method
+ */
+ using LockDelegate = Delegate;
+
public:
using BaseDelegate<R(ARGS...), void *>::BaseDelegate;
+ /**
+ * @brief Locks this delegate before further invoke
+ * @details This function simply returns copy of this delegate.
+ * Provided for interface compatibility with other delegate
+ * types.
+ * @return Lock delegate
+ */
+ LockDelegate lock() const;
+
+ /**
+ * @brief Invokes this delegate
+ * @details Delgates must be checked for NULL before invoke.
+ * @params[in] args Arguments of the invoke
+ * @return Result of the invoke
+ */
R operator()(ARGS ...args) const;
+ /**
+ * @brief Creates delegate to instance method
+ * @param[in] data This pointer of the instance
+ * @return Created delegate
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
static Delegate make(CLASS *data) noexcept;
+
+ /**
+ * @brief Creates delegate to constant instance method
+ * @param[in] data Constant this pointer of the instance
+ * @return Created delegate
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
static Delegate make(const CLASS *data) noexcept;
+ /**
+ * @brief Creates delegate to StubA-style function taking object
+ * @param[in] data Pointer of the object
+ * @return Created delegate
+ */
template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
- static Delegate makeA(CLASS &data) noexcept;
+ static Delegate makeA(CLASS *data) noexcept;
+
+ /**
+ * @brief Creates delegate to StubB-style function taking object
+ * @param[in] data Pointer of the object
+ * @return Created delegate
+ */
template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
- static Delegate makeB(CLASS &data) noexcept;
+ static Delegate makeB(CLASS *data) noexcept;
+ /**
+ * @brief Creates delegate to StubA-style function taking object handle
+ * @param[in] data Handle of the object
+ * @return Created delegate
+ */
template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
static Delegate makeA(HANDLE data) noexcept;
+
+ /**
+ * @brief Creates delegate to StubB-style function taking object handle
+ * @param[in] data Handle of the object
+ * @return Created delegate
+ */
template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
static Delegate makeB(HANDLE data) noexcept;
+ /**
+ * @brief Creates delegate to static function
+ * @return Created delegate
+ */
template <R(*FUNC)(ARGS...)>
static Delegate make() noexcept;
};
namespace ucl {
+ template <class R, class ...ARGS>
+ inline typename Delegate<R(ARGS...)>::LockDelegate
+ Delegate<R(ARGS...)>::lock() const
+ {
+ return *this;
+ }
+
template <class R, class ...ARGS>
inline R Delegate<R(ARGS...)>::operator()(ARGS ...args) const
{
template <class R, class ...ARGS>
template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
inline Delegate<R(ARGS...)>
- Delegate<R(ARGS...)>::makeA(CLASS &data) noexcept
+ Delegate<R(ARGS...)>::makeA(CLASS *data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(&data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate::Cb::template stubA2A<CLASS, FUNC>};
}
template <class R, class ...ARGS>
template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
inline Delegate<R(ARGS...)>
- Delegate<R(ARGS...)>::makeB(CLASS &data) noexcept
+ Delegate<R(ARGS...)>::makeB(CLASS *data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(&data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate::Cb::template stubA2B<CLASS, FUNC>};
}
inline Delegate<R(ARGS...)>
Delegate<R(ARGS...)>::makeA(const HANDLE data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate::Cb::template stubA2A<HANDLE, FUNC>};
}
inline Delegate<R(ARGS...)>
Delegate<R(ARGS...)>::makeB(const HANDLE data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate::Cb::template stubA2B<HANDLE, FUNC>};
}
inline Delegate<R(ARGS...)>
Delegate<R(ARGS...)>::make() noexcept
{
- return {nullptr, Delegate::Cb::template stubA2V<FUNC>};
+ const auto fakeData = reinterpret_cast<void *>(1);
+ return {fakeData, Delegate::Cb::template stubA2V<FUNC>};
}
}
template <class FUNC_SIG>
class Delegate2;
+ /**
+ * @brief Delegate2 that uses "void *" as data pointer
+ */
template <class R, class ...ARGS>
class Delegate2<R(ARGS...)> : public BaseDelegate2<R(ARGS...), void *> {
+ public:
+ /**
+ * @brief Result delegate of the lock() method
+ */
+ using LockDelegate = Delegate2;
+
public:
using BaseDelegate2<R(ARGS...), void *>::BaseDelegate2;
+ /**
+ * @brief Locks this delegate before further invoke
+ * @details This function simply returns copy of this delegate.
+ * Provided for interface compatibility with other delegate
+ * types.
+ * @return Lock delegate
+ */
+ LockDelegate lock() const;
+
+ /**
+ * @brief Invokes this delegate
+ * @details Delgates must be checked for NULL before invoke.
+ * @params[in] args Arguments of the invoke
+ * @return Result of the invoke
+ */
R operator()(ARGS ...args) const;
+ /**
+ * @brief Creates delegate to instance method
+ * @param[in] data This pointer of the instance
+ * @return Created delegate
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
static Delegate2 make(CLASS *data) noexcept;
+
+ /**
+ * @brief Creates delegate to constant instance method
+ * @param[in] data Constant this pointer of the instance
+ * @return Created delegate
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
static Delegate2 make(const CLASS *data) noexcept;
+ /**
+ * @brief Creates delegate to StubA-style function taking object
+ * @param[in] data Pointer of the object
+ * @return Created delegate
+ */
template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
- static Delegate2 makeA(CLASS &data) noexcept;
+ static Delegate2 makeA(CLASS *data) noexcept;
+
+ /**
+ * @brief Creates delegate to StubB-style function taking object
+ * @param[in] data Pointer of the object
+ * @return Created delegate
+ */
template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
- static Delegate2 makeB(CLASS &data) noexcept;
+ static Delegate2 makeB(CLASS *data) noexcept;
+ /**
+ * @brief Creates delegate to StubA-style function taking object handle
+ * @param[in] data Handle of the object
+ * @return Created delegate
+ */
template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
static Delegate2 makeA(HANDLE data) noexcept;
+
+ /**
+ * @brief Creates delegate to StubB-style function taking object handle
+ * @param[in] data Handle of the object
+ * @return Created delegate
+ */
template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
static Delegate2 makeB(HANDLE data) noexcept;
+ /**
+ * @brief Creates delegate to static function
+ * @return Created delegate
+ */
template <R(*FUNC)(ARGS...)>
static Delegate2 make() noexcept;
};
namespace ucl {
+ template <class R, class ...ARGS>
+ inline typename Delegate2<R(ARGS...)>::LockDelegate
+ Delegate2<R(ARGS...)>::lock() const
+ {
+ return *this;
+ }
+
template <class R, class ...ARGS>
inline R Delegate2<R(ARGS...)>::operator()(ARGS ...args) const
{
template <class R, class ...ARGS>
template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
inline Delegate2<R(ARGS...)>
- Delegate2<R(ARGS...)>::makeA(CLASS &data) noexcept
+ Delegate2<R(ARGS...)>::makeA(CLASS *data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(&data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate2::Cb::template stubA2A<CLASS, FUNC>,
Delegate2::Cb::template stubB2A<CLASS, FUNC>};
}
template <class R, class ...ARGS>
template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
inline Delegate2<R(ARGS...)>
- Delegate2<R(ARGS...)>::makeB(CLASS &data) noexcept
+ Delegate2<R(ARGS...)>::makeB(CLASS *data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(&data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate2::Cb::template stubA2B<CLASS, FUNC>,
Delegate2::Cb::template stubB2B<CLASS, FUNC>};
}
inline Delegate2<R(ARGS...)>
Delegate2<R(ARGS...)>::makeA(const HANDLE data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate2::Cb::template stubA2A<HANDLE, FUNC>,
Delegate2::Cb::template stubB2A<HANDLE, FUNC>};
}
inline Delegate2<R(ARGS...)>
Delegate2<R(ARGS...)>::makeB(const HANDLE data) noexcept
{
- return {const_cast<void *>(static_cast<const void *>(data)),
+ return {const_cast<void *>(static_cast<const volatile void *>(data)),
Delegate2::Cb::template stubA2B<HANDLE, FUNC>,
Delegate2::Cb::template stubB2B<HANDLE, FUNC>};
}
inline Delegate2<R(ARGS...)>
Delegate2<R(ARGS...)>::make() noexcept
{
- return {nullptr,
+ const auto fakeData = reinterpret_cast<void *>(1);
+ return {fakeData,
Delegate2::Cb::template stubA2V<FUNC>,
Delegate2::Cb::template stubB2V<FUNC>};
}
namespace ucl {
- // Automatic function signature detection for a specific type //
-
- template <template <typename ...> class T, class TAG, class FUNC>
- struct AutoFuncSig;
-
- template <template <typename ...> class T,
- class R, class CLASS, class ...ARGS>
- struct AutoFuncSig<T, void *, R(CLASS::*)(ARGS...)> {
- using Data = CLASS;
- using Type = T<R(ARGS...)>;
- };
-
- template <template <typename ...> class T,
- class CLASS, class R, class ...ARGS>
- struct AutoFuncSig<T, void *, R(CLASS::*)(ARGS...) const> {
- using Data = CLASS;
- using Type = T<R(ARGS...)>;
- };
-
- template <template <typename ...> class T,
- class CLASS, class R, class ...ARGS>
- struct AutoFuncSig<T, void *, R(*)(CLASS &, ARGS...)> {
- using Data = CLASS;
- using Type = T<R(ARGS...)>;
- };
-
- template <template <typename ...> class T,
- class HANDLE, class R, class ...ARGS>
- struct AutoFuncSig<T, void *, R(*)(HANDLE, ARGS...)> {
- using Data = HANDLE;
- using Type = T<R(ARGS...)>;
- };
-
- template <template <typename ...> class T,
- class R, class ...ARGS>
- struct AutoFuncSig<T, void, R(*)(ARGS...)> {
- using Type = T<R(ARGS...)>;
- };
-
// Relation operators //
+ /**
+ * @brief Compares equals target delegates
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
template <class R, class ...ARGS, class DATA1, class DATA2>
inline bool operator==(const BaseDelegate<R(ARGS...), DATA1> &lhs,
const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
lhs.getData() == rhs.getData()));
}
+ /**
+ * @brief Compares unequals target delegates
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
template <class R, class ...ARGS, class DATA1, class DATA2>
inline bool operator!=(const BaseDelegate<R(ARGS...), DATA1> &lhs,
const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
lhs.getData() != rhs.getData()));
}
+ /**
+ * @brief Compares less target delegates
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is less than right, false - otherwise
+ */
template <class R, class ...ARGS, class DATA1, class DATA2>
inline bool operator<(const BaseDelegate<R(ARGS...), DATA1> &lhs,
const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
lhs.getData() < rhs.getData())));
}
+ /**
+ * @brief Compares less or equals target delegates
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is less or equals to right, false - otherwise
+ */
template <class R, class ...ARGS, class DATA1, class DATA2>
inline bool operator<=(const BaseDelegate<R(ARGS...), DATA1> &lhs,
const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
lhs.getData() <= rhs.getData())));
}
+ /**
+ * @brief Compares greater target delegates
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is greater than right, false - otherwise
+ */
template <class R, class ...ARGS, class DATA1, class DATA2>
inline bool operator>(const BaseDelegate<R(ARGS...), DATA1> &lhs,
const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
lhs.getData() > rhs.getData())));
}
+ /**
+ * @brief Compares greater or equals target delegates
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is greater or equals to right, false - otherwise
+ */
template <class R, class ...ARGS, class DATA1, class DATA2>
inline bool operator>=(const BaseDelegate<R(ARGS...), DATA1> &lhs,
const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UCL_UTIL_DELEGATION_INTERNAL_H__
+#define __UCL_UTIL_DELEGATION_INTERNAL_H__
+
+namespace ucl { namespace himpl {
+
+ // Automatic function signature detection for a specific type //
+
+ template <template <typename ...> class T, class FUNC>
+ struct AutoFuncSig;
+
+ template <template <typename ...> class T,
+ class R, class CLASS, class ...ARGS>
+ struct AutoFuncSig<T, R(CLASS::*)(ARGS...)> {
+ using Data = CLASS;
+ using Type = T<R(ARGS...)>;
+
+ template <R(CLASS::*METHOD)(ARGS...), class DATA>
+ static Type makeDelegate(DATA &&data) noexcept
+ {
+ return Type::template make<CLASS, METHOD>(std::forward<DATA>(data));
+ }
+ };
+
+ template <template <typename ...> class T,
+ class CLASS, class R, class ...ARGS>
+ struct AutoFuncSig<T, R(CLASS::*)(ARGS...) const> {
+ using Data = CLASS;
+ using Type = T<R(ARGS...)>;
+
+ template <R(CLASS::*METHOD)(ARGS...) const, class DATA>
+ static Type makeDelegate(DATA &&data) noexcept
+ {
+ return Type::template make<CLASS, METHOD>(std::forward<DATA>(data));
+ }
+ };
+
+ template <template <typename ...> class T,
+ class CLASS, class R, class ...ARGS>
+ struct AutoFuncSig<T, R(*)(CLASS &, ARGS...)> {
+ using Data = CLASS;
+ using Type = T<R(ARGS...)>;
+
+ template <R(*FUNC)(CLASS &, ARGS...), class DATA>
+ static Type makeDelegate(DATA &&data) noexcept
+ {
+ return Type::template makeA<CLASS, FUNC>(std::forward<DATA>(data));
+ }
+ };
+
+ template <template <typename ...> class T,
+ class HANDLE, class R, class ...ARGS>
+ struct AutoFuncSig<T, R(*)(HANDLE, ARGS...)> {
+ using Data = HANDLE;
+ using Type = T<R(ARGS...)>;
+ using TypeV = T<R(HANDLE, ARGS...)>;
+
+ template <R(*FUNC)(HANDLE, ARGS...), class DATA>
+ static Type makeDelegate(DATA &&data) noexcept
+ {
+ return Type::template makeA<HANDLE, FUNC>(std::forward<DATA>(data));
+ }
+
+ template <R(*FUNC)(HANDLE, ARGS...)>
+ static TypeV makeDelegate() noexcept
+ {
+ return TypeV::template make<FUNC>();
+ }
+ };
+
+ template <template <typename ...> class T, class R>
+ struct AutoFuncSig<T, R(*)()> {
+ using TypeV = T<R()>;
+
+ template <R(*FUNC)()>
+ static TypeV makeDelegate() noexcept
+ {
+ return TypeV::template make<FUNC>();
+ }
+ };
+}}
+
+#endif // __UCL_UTIL_DELEGATION_INTERNAL_H__
#ifndef __UCL_UTIL_DELEGATION_MACRO_H__
#define __UCL_UTIL_DELEGATION_MACRO_H__
+#include "internal.h"
+
// Helper macro to simplify use of AutoFuncSig template
#define _UCL_AFS(DELEGATE, FUNC) \
- ::ucl::AutoFuncSig<DELEGATE, void *, decltype(&FUNC)>
+ ::ucl::himpl::AutoFuncSig<DELEGATE, decltype(&FUNC)>
// Helper macro to automatically generate different delegate objects //
-#define _UCL_DELEGATE(DELEGATE, FUNC, DATA) (_UCL_AFS(DELEGATE, FUNC):: \
- Type::make<_UCL_AFS(DELEGATE, FUNC)::Data, &FUNC>(DATA))
-
-#define _UCL_DELEGATE_A(DELEGATE, FUNC, DATA) (_UCL_AFS(DELEGATE, FUNC):: \
- Type::makeA<_UCL_AFS(DELEGATE, FUNC)::Data, &FUNC>(DATA))
-
-#define _UCL_DELEGATE_V(DELEGATE, FUNC) \
- (::ucl::AutoFuncSig<DELEGATE, void, decltype(&FUNC)>::\
- Type::make<&FUNC>())
+#define _UCL_DELEGATE(DELEGATE, FUNC, DATA...) \
+ _UCL_AFS(DELEGATE, FUNC)::template makeDelegate<&FUNC>(DATA)
// Helper macro to automatically generate Delegate objects //
-#define UCL_DELEGATE(FUNC, DATA) _UCL_DELEGATE(::ucl::Delegate, FUNC, DATA)
-#define UCL_DELEGATE_A(FUNC, DATA) _UCL_DELEGATE_A(::ucl::Delegate, FUNC, DATA)
-#define UCL_DELEGATE_V(FUNC) _UCL_DELEGATE_V(::ucl::Delegate, FUNC)
+/**
+ * @brief Creates Delegate<auto> to specified function
+ * @param FUNC Function for the delegate without &
+ * @param DATA Data for the delegate (optional)
+ * @return Created delegate
+ */
+#define UCL_DELEGATE(FUNC, DATA...) _UCL_DELEGATE( \
+ ::ucl::Delegate, FUNC, ##DATA)
+
+/**
+ * @brief Creates Delegate<auto> to "this" instance method
+ * @param FUNC_NAME name of the function of the "this" class
+ * @return Created delegate
+ */
+#define UCL_DELEGATE_THIS(FUNC_NAME) UCL_DELEGATE( \
+ std::remove_pointer<decltype(this)>::type::FUNC_NAME, this)
// Helper macro to automatically generate Delegate2 objects //
-#define UCL_DELEGATE2(FUNC, DATA) _UCL_DELEGATE(::ucl::Delegate2, FUNC, DATA)
-#define UCL_DELEGATE2_A(FUNC, DATA) \
- _UCL_DELEGATE_A(::ucl::Delegate2, FUNC, DATA)
-#define UCL_DELEGATE2_V(FUNC) _UCL_DELEGATE_V(::ucl::Delegate2, FUNC)
+/**
+ * @brief Creates Delegate2<auto> to specified function
+ * @param FUNC Function for the delegate without &
+ * @param DATA Data for the delegate (optional)
+ * @return Created delegate
+ */
+#define UCL_DELEGATE2(FUNC, DATA...) _UCL_DELEGATE( \
+ ::ucl::Delegate2, FUNC, ##DATA)
+
+/**
+ * @brief Creates Delegate2<auto> to "this" instance method
+ * @param FUNC_NAME name of the function of the "this" class
+ * @return Created delegate
+ */
+#define UCL_DELEGATE2_THIS(FUNC_NAME) UCL_DELEGATE2( \
+ std::remove_pointer<decltype(this)>::type::FUNC_NAME, this)
// Helper macro to automatically generate Callback stubs //
-#define UCL_CALLBACK_A(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC):: \
- Type::stubA<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
-#define UCL_CALLBACK_B(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC):: \
- Type::stubB<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
+/**
+ * @brief Returns Callback<auto>::stubA to specified function
+ * @param FUNC Function for the callback without &
+ * @return Pointer to the stab function
+ */
+#define UCL_CALLBACK_A(FUNC) &_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
+ template stubA<typename _UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>
-#define UCL_CALLBACK_A2A(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
- stubA2A<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
-#define UCL_CALLBACK_B2A(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
- stubB2A<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
+/**
+ * @brief Returns Callback<auto>::stubB to specified function
+ * @param FUNC Function for the callback without &
+ * @return Pointer to the stab function
+ */
+#define UCL_CALLBACK_B(FUNC) &_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
+ template stubB<typename _UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>
-#define UCL_CALLBACK_A2V(FUNC) (&::ucl::AutoFuncSig<::ucl::Callback, void, \
- decltype(&FUNC)>::Type::stubA2V<&FUNC>)
-#define UCL_CALLBACK_B2V(FUNC) (&::ucl::AutoFuncSig<::ucl::Callback, void, \
- decltype(&FUNC)>::Type::stubB2V<&FUNC>)
+/**
+ * @brief Returns Callback<auto>::stubA2A to specified function
+ * @param FUNC Function for the callback without &
+ * @return Pointer to the stab function
+ */
+#define UCL_CALLBACK_A2A(FUNC) &_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
+ template stubA2A<typename _UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>
+
+/**
+ * @brief Returns Callback<auto>::stubB2A to specified function
+ * @param FUNC Function for the callback without &
+ * @return Pointer to the stab function
+ */
+#define UCL_CALLBACK_B2A(FUNC) &_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
+ template stubB2A<typename _UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>
+
+/**
+ * @brief Returns Callback<auto>::stubA2V to specified function
+ * @param FUNC Function for the callback without &
+ * @return Pointer to the stab function
+ */
+#define UCL_CALLBACK_A2V(FUNC) &_UCL_AFS(::ucl::Callback, FUNC)::TypeV:: \
+ template stubA2V<&FUNC>
+
+/**
+ * @brief Returns Callback<auto>::stubB2V to specified function
+ * @param FUNC Function for the callback without &
+ * @return Pointer to the stab function
+ */
+#define UCL_CALLBACK_B2V(FUNC) &_UCL_AFS(::ucl::Callback, FUNC)::TypeV:: \
+ template stubB2V<&FUNC>
#endif // __UCL_UTIL_DELEGATION_MACRO_H__
// Helper macro to automatically generate Delegate objects //
-#define DELEGATE(FUNC, DATA) UCL_DELEGATE(FUNC, DATA)
-#define DELEGATE_A(FUNC, DATA) UCL_DELEGATE_A(FUNC, DATA)
-#define DELEGATE_V(FUNC) UCL_DELEGATE_V(FUNC)
+#define DELEGATE(FUNC, DATA...) UCL_DELEGATE(FUNC, ##DATA)
+
+#define DELEGATE_THIS(FUNC_NAME) UCL_DELEGATE_THIS(FUNC_NAME)
// Helper macro to automatically generate Delegate2 objects //
-#define DELEGATE2(FUNC, DATA) UCL_DELEGATE2(FUNC, DATA)
-#define DELEGATE2_A(FUNC, DATA) UCL_DELEGATE2_A(FUNC, DATA)
-#define DELEGATE2_V(FUNC) UCL_DELEGATE2_V(FUNC)
+#define DELEGATE2(FUNC, DATA...) UCL_DELEGATE2(FUNC, ##DATA)
+
+#define DELEGATE2_THIS(FUNC_NAME) UCL_DELEGATE2_THIS(FUNC_NAME)
// Helper macro to automatically generate Callback stubs //
namespace ucl {
+ /**
+ * @brief Converts a value to corresponding Eina type
+ * @param[in] value Original bool value
+ * @return Corresponding Eina_Bool value
+ */
constexpr Eina_Bool toEina(bool value);
- // "nz()" - "Not Zero" functions
- // return "zValue" if "!value" is true
+ /**
+ * @brief Returns "zValue" if source is NULL
+ * @param[in] value Source C-String
+ * @param[in] zValue Value to return when "value" is NULL (optional: "")
+ * @return "value" - if not NULL, "zValue" - otherwise
+ */
constexpr const char *nz(const char *value, const char *zValue = "");
- // "ne()" - "Not Empty" functions
- // return "eValue" if "isEmpty(value)" is true
+ /**
+ * @brief Returns "eValue" if source is empty string
+ * @param[in] value Source C-String
+ * @param[in] eValue Value to return when "value" is NULL (optional: NULL)
+ * @return "value" - if not empty, "eValue" - otherwise
+ */
constexpr const char *ne(const char *value, const char *eValue = nullptr);
+ /**
+ * @brief Checks C-String for emptiness
+ * @param[in] value Source C-String
+ * @return true - if empty (NULL or ""), false - otherwise
+ */
constexpr bool isEmpty(const char *value);
+ /**
+ * @brief Checks T object for emptiness
+ * @details Works by wrapping object's empty() method if exists
+ * @param[in] value Source object
+ * @return true - if empty, false - otherwise
+ */
template <class T>
constexpr auto isEmpty(const T &value) -> decltype(value.empty())
{
return value.empty();
}
+ /**
+ * @brief Checks T object for emptiness
+ * @details Works by wrapping object's isEmpty() method if exists
+ * @param[in] value Source object
+ * @return true - if empty, false - otherwise
+ */
template <class T>
constexpr auto isEmpty(const T &value) -> decltype(value.isEmpty())
{
return value.isEmpty();
}
+ /**
+ * @brief Checks T object passed by pointer for emptiness
+ * @details Uses isEmpty() function on dereferenced value if not NULL.
+ * @param[in] value Source object pointer
+ * @return true - if empty or NULL, false - otherwise
+ */
template <class T>
constexpr auto isEmpty(const T &value) -> decltype(isEmpty(*value))
{
return (!value || isEmpty(*value));
}
+ /**
+ * @brief Checks T object for validity
+ * @details Works by wrapping object's valid() method if exists
+ * @param[in] value Source object
+ * @return true - if valid, false - otherwise
+ */
+ template <class T>
+ constexpr auto isValid(const T &value) -> decltype(value.valid())
+ {
+ return value.valid();
+ }
+
+ /**
+ * @brief Checks T object for validity
+ * @details Works by wrapping object's isValid() method if exists
+ * @param[in] value Source object
+ * @return true - if valid, false - otherwise
+ */
+ template <class T>
+ constexpr auto isValid(const T &value) -> decltype(value.isValid())
+ {
+ return value.isValid();
+ }
+
+ /**
+ * @brief Checks T object passed by pointer for validity
+ * @details Uses isValid() function on dereferenced value if not NULL.
+ * @param[in] value Source object pointer
+ * @return true - if valid, false - otherwise
+ */
+ template <class T>
+ constexpr auto isValid(const T &value) -> decltype(isValid(*value))
+ {
+ return (value && isValid(*value));
+ }
+
+ /**
+ * @brief Checks T object for not emptiness
+ * @details Works by negating isEmpty() function
+ * @param[in] value Source object
+ * @return true - if not empty, false - otherwise
+ */
template <class T>
constexpr bool isNotEmpty(T &&value);
+ /**
+ * @brief Checks T object for not validity
+ * @details Works by negating isValid() function
+ * @param[in] value Source object
+ * @return true - if not valid, false - otherwise
+ */
template <class T>
constexpr bool isNotValid(T &&value);
+ /**
+ * @brief Duplicates C-String with NULL check
+ * @param[in] value Source C-String
+ * @return Duplicated C-String or NULL
+ */
char *strDupSafe(const char *value);
+
+ /**
+ * @brief Compares C-String wrapped with nz() function
+ * @param[in] lhs Left hand side C-String
+ * @param[in] lhs Right hand side C-String
+ * @return 0 - equals, <0 - less, >0 - greater
+ */
int strCmpSafe(const char *lhs, const char *rhs);
+ /**
+ * @brief Dynamically casts an object
+ * @param[in] src Source object
+ * @return Result object
+ */
template <class T1, class T2>
inline auto dynamicCast(T2 &&src) -> decltype(
dynamic_cast<T1>(std::forward<T2>(src)))
return dynamic_cast<T1>(std::forward<T2>(src));
}
+ /**
+ * @brief Const casts an object
+ * @param[in] src Source object
+ * @return Result object
+ */
template <class T1, class T2>
inline auto constCast(T2 &&src) -> decltype(
const_cast<T1>(std::forward<T2>(src)))
return const_cast<T1>(std::forward<T2>(src));
}
+ /**
+ * @brief Calculates minimum from two values
+ * @param[in] a First value
+ * @param[in] b Second value
+ * @return Constant reference to minimum value
+ */
template <class T>
constexpr const T &min(const T &a, const T &b);
+ /**
+ * @brief Calculates maximum from two values
+ * @param[in] a First value
+ * @param[in] b Second value
+ * @return Constant reference to maximum value
+ */
template <class T>
constexpr const T &max(const T &a, const T &b);
+ /**
+ * @brief Checks if a value is a Power of Two
+ * @param[in] value Source value
+ * @return true - if value is POT, false - otherwise
+ */
template <class T>
constexpr bool isPot(T value)
{
return (((value - 1) & value) == 0);
}
+ /**
+ * @brief Divides integer T by MULTIPLE with ceiling
+ * @param[in] value Source value
+ * @return Ceiled result of the division
+ */
template <uint MULTIPLE, class T>
constexpr T ceilDiv(T value);
+ /**
+ * @brief Rounds integer T to not less value that is a multiple of MULTIPLE
+ * @details Optimized version for POT numbers
+ * @param[in] value Source value
+ * @return Result of the rounding
+ */
template <uint MULTIPLE, class T>
constexpr typename std::enable_if<isPot(MULTIPLE), T>::type
roundUp(T value)
return ((value + (MULTIPLE - 1)) & ~static_cast<T>(MULTIPLE - 1));
}
+ /**
+ * @brief Rounds integer T to not less value that is a multiple of MULTIPLE
+ * @details Version for not POT numbers
+ * @param[in] value Source value
+ * @return Result of the rounding
+ */
template <uint MULTIPLE, class T>
constexpr typename std::enable_if<!isPot(MULTIPLE), T>::type
roundUp(T value)
namespace ucl { namespace util {
+ /**
+ * @brief Wraps T object pointer with std::unique_ptr
+ * @param[in] p Source pointer
+ * @return Result std::unique_ptr
+ */
template <class T>
- std::unique_ptr<T> makeUnique(T *p);
+ std::unique_ptr<T> wrapUnique(T *p);
+
+ /**
+ * @brief Makes new instance of T and calls wrapUnique()
+ * @param[in] args Arguments for T constructor
+ * @return Result std::unique_ptr
+ */
+ template <class T, class ...ARGS>
+ std::unique_ptr<T> makeUnique(ARGS &&...args);
+ /**
+ * @brief Safely disposes object and NULLs pointer
+ * @param[in/out] p Target pointer
+ */
template <class T, class = typename std::enable_if<
std::is_convertible<T *, IDisposable *>::value>::type>
inline void dispose(T *&p) noexcept
namespace ucl { namespace util {
template <class T>
- inline std::unique_ptr<T> makeUnique(T *const p)
+ inline std::unique_ptr<T> wrapUnique(T *const p)
{
return std::unique_ptr<T>(p);
}
+
+ template <class T, class ...ARGS>
+ inline std::unique_ptr<T> makeUnique(ARGS &&...args)
+ {
+ return wrapUnique(new T(std::forward<ARGS>(args)...));
+ }
}}
#include "types/Result.h"
+/**
+ * @brief Gets result data for result codes defined in "ucl/types/Result.h"
+ * @param[in] result Result value
+ * @return Corresponding result data for the result value
+ */
::ucl::ResultData getUCLResultData(::ucl::Result result);
#ifndef UCL_LOG_LEVEL
namespace ucl {
+ /**
+ * @brief Base class for reference-counted pointers
+ */
template <class T>
class BaseRef {
public:
+ /**
+ * @brief Alias for "T"
+ */
using Type = T;
- template <class U>
- friend class BaseRef;
- template <class U>
- friend class SharedRef;
- template <class U>
- friend class WeakRef;
-
public:
+ /**
+ * @brief Gets use count of the pointed object (strong count)
+ */
UInt getUseCount() const noexcept;
protected:
+ /**
+ * @brief Default constructor
+ */
constexpr BaseRef() noexcept;
+
+ /**
+ * @brief Constructor
+ * @param[in] rc Pointer to reference-counted objet
+ * @param[in] ptr Pointed object pointer
+ */
BaseRef(IRefCountObj *rc, T *ptr) noexcept;
+
+ /**
+ * @brief Move constructor
+ * @param[in] r Source object
+ */
BaseRef(BaseRef<T> &&r) noexcept;
+
+ /**
+ * @brief Conversion move constructor
+ * @param[in] r Source object
+ */
template <class U>
BaseRef(BaseRef<U> &&r) noexcept;
protected:
+ /**
+ * @brief Reference counter-counted objet
+ */
IRefCountObj *m_rc;
+
+ /**
+ * @brief Pointed object pointer
+ */
T *m_ptr;
+
+ template <class U>
+ friend class BaseRef;
+ template <class U>
+ friend class SharedRef;
+ template <class U>
+ friend class WeakRef;
};
}
namespace ucl {
- class IRefCountObj : public Polymorphic {
+ /**
+ * @brief Interface for reference-counted object
+ */
+ class IRefCountObj : protected NonCopyable {
public:
+ /**
+ * @brief Increments use counter
+ */
virtual void ref() noexcept = 0;
+
+ /**
+ * @brief Decrements use counter
+ * @details When use count reches 0 object will be destroyed
+ */
virtual void unref() noexcept = 0;
+
+ /**
+ * @brief Increments use counter if it is not 0
+ */
virtual bool refNz() noexcept = 0;
+
+ /**
+ * @brief Increments weak counter
+ */
virtual void refWeak() noexcept = 0;
+
+ /**
+ * @brief Decrements weak counter
+ * @details When weak count reches 0 "delete this" will be called
+ */
virtual void unrefWeak() noexcept = 0;
+
+ /**
+ * @brief Gets use count (strong count)
+ * @return use count
+ */
virtual UInt getUseCount() const noexcept = 0;
+
+ /**
+ * @brief Gets pointer of the object
+ * @return Pointer of the object
+ */
virtual const void *getObjPtr() const noexcept = 0;
+
protected:
- virtual ~IRefCountObj() = default;
+ /**
+ * @brief Destructor
+ */
+ ~IRefCountObj() = default;
};
}
namespace ucl {
+ /**
+ * @brief Represents reference-counted object of type T and counter C
+ */
template <class T, class C>
class RefCountObj final : public IRefCountObj {
public:
+ /**
+ * @brief Constructor
+ * @param[in] args Arguments for T constructor
+ */
template <class ...ARGS>
RefCountObj(ARGS &&...args);
+ /**
+ * @brief Gets pointer of the object
+ * @return Pointer of the object
+ */
T *getObj() noexcept;
// IRefCountObj //
std::true_type {};
private:
- virtual ~RefCountObj() = default;
-
template <class T2, class ...ARGS, class =
typename std::enable_if<!IsRefCountAware<T2>::value>::type>
void createObj(const P<0> &, ARGS &&...args)
namespace ucl {
+ /**
+ * @brief Represents multithreaded reference counter
+ */
class RefCounterMT final {
public:
+ /**
+ * @brief Constructor
+ * @param[in] count Initial counter value
+ */
explicit RefCounterMT(const UInt count = 0) noexcept;
+ /**
+ * @brief Atomically increments counter
+ * @return New counter value
+ */
UInt ref() noexcept;
+
+ /**
+ * @brief Atomically decrements counter
+ * @return New counter value
+ */
UInt unref() noexcept;
+
+ /**
+ * @brief Atomically increments counter if not 0
+ * @return New counter value
+ */
UInt refNz() noexcept;
+ /**
+ * @brief Atomically gets current counter value
+ * @return Current counter value
+ */
UInt get() const noexcept;
private:
namespace ucl {
+ /**
+ * @brief Represents singlethreaded reference counter
+ */
class RefCounterST final {
public:
+ /**
+ * @brief Constructor
+ * @param[in] count Initial counter value
+ */
explicit RefCounterST(const UInt count = 0) noexcept;
+ /**
+ * @brief Increments counter
+ * @return New counter value
+ */
UInt ref() noexcept;
+
+ /**
+ * @brief Decrements counter
+ * @return New counter value
+ */
UInt unref() noexcept;
+
+ /**
+ * @brief Increments counter if not 0
+ * @return New counter value
+ */
UInt refNz() noexcept;
+ /**
+ * @brief Gets current counter value
+ * @return Current counter value
+ */
UInt get() const noexcept;
private:
template <class T, class C>
class RefCountObj;
+ /**
+ * @brief Helpers class to store object of type T for reference counting
+ * @details You need to friend ReffedObj<T> if constructor/destructor
+ * of T is not public
+ */
template <class T>
class ReffedObj final {
private:
- friend class RefCountObj<T, RefCounterST>;
- friend class RefCountObj<T, RefCounterMT>;
-
+ /**
+ * @brief Calls constructor of T
+ * @param[in] Arguments for T constructor
+ */
template <class ...ARGS>
void create(ARGS &&...args);
+
+ /**
+ * @brief Calls destructor of T
+ */
void destroy() noexcept;
+ /**
+ * @brief Gets pointer to T object
+ * @return Pointer to T object
+ */
T *get() noexcept;
+
+ /**
+ * @brief Gets pointer to constant T object
+ * @return Pointer to constant T object
+ */
const T *get() const noexcept;
+ /**
+ * @brief Calls "get()->onUniqueChanged()" on the T object
+ * @param[in] isUnique true - if use count is 1, false - otherwise
+ */
template <class T2>
void dispatchOnUniqueChanged(bool isUnique);
private:
typename std::aligned_storage<sizeof(T), alignof(T)>::type m_obj;
+
+ friend class RefCountObj<T, RefCounterST>;
+ friend class RefCountObj<T, RefCounterMT>;
};
}
namespace ucl {
+ /**
+ * @brief Implements shared reference (pointer) to T object
+ */
template <class T>
class SharedRef final : public BaseRef<T> {
public:
+ /**
+ * @brief Swaps SharedRef objects with each other
+ * @param[in/out] x First SharedRef
+ * @param[in/out] y Second SharedRef
+ */
template <class U>
friend void swap(SharedRef<U> &x, SharedRef<U> &y) noexcept;
+ /**
+ * @brief Statically casts SharedRef<U> to SharedRef<T2>
+ * @param[in] r Source shared reference
+ * @return Result shared reference
+ */
template <class T2, class U>
friend SharedRef<T2> staticRefCast(const SharedRef<U> &r) noexcept;
+
+ /**
+ * @brief Dynamically casts SharedRef<U> to SharedRef<T2>
+ * @param[in] r Source shared reference
+ * @return Result shared reference
+ */
template <class T2, class U>
friend SharedRef<T2> dynamicRefCast(const SharedRef<U> &r) noexcept;
public:
+ /**
+ * @brief Default constructor
+ * @details Creates empty reference
+ */
constexpr SharedRef() noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
constexpr SharedRef(std::nullptr_t) noexcept;
+ /**
+ * @brief Constructor
+ * @details Increments reference counter
+ * @param[in] rc Pointer to reference-counted objet
+ * @param[in] ptr Pointed object pointer
+ */
SharedRef(IRefCountObj *rc, T *ptr) noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Does not increment reference counter
+ * @param[in] rc Pointer to reference-counted objet
+ * @param[in] ptr Pointed object pointer
+ * @param[in] noRef Not used.
+ */
SharedRef(IRefCountObj *rc, T *ptr, bool noRef) noexcept;
+ /**
+ * @brief Copy constructor
+ * @param[in] r Source object
+ */
SharedRef(const SharedRef<T> &r) noexcept;
+
+ /**
+ * @brief Converting copy constructor
+ * @param[in] r Source object
+ */
template <class U>
SharedRef(const SharedRef<U> &r) noexcept;
+ /**
+ * @brief Move constructor
+ * @param[in] r Source object
+ */
SharedRef(SharedRef<T> &&r) noexcept;
+
+ /**
+ * @brief Converting move constructor
+ * @param[in] r Source object
+ */
template <class U>
SharedRef(SharedRef<U> &&r) noexcept;
+ /**
+ * @brief Destructor
+ * @details Decrements reference counter
+ */
~SharedRef();
+ /**
+ * @brief Assigns one SharedRef to another
+ * @param[in] r Source object
+ * @return Reference to this SharedRef
+ */
SharedRef<T> &operator=(SharedRef<T> r) noexcept;
+ /**
+ * @brief Makes this reference empty
+ */
void reset() noexcept;
+ /**
+ * @brief Gets pointed object pointer
+ * @return Pointer object pointer
+ */
T *get() const noexcept;
- operator bool() const noexcept;
+ /**
+ * @brief Explicitly casts to bool
+ * @return true - if not empty, false - otherwise
+ */
+ explicit operator bool() const noexcept;
+
+ /**
+ * @brief Gets pointed object pointer
+ * @return Pointer object pointer
+ */
T *operator->() const noexcept;
+
+ /**
+ * @brief Gets pointed object reference
+ * @return Pointer object reference
+ */
typename std::add_lvalue_reference<T>::type operator*() const noexcept;
+ /**
+ * @brief Implicitly casts to compatible SharedRef type
+ * @return Reference to this object as casted type
+ */
template <class U, class = typename std::enable_if<
std::is_convertible<T *, U *>::value && (
std::is_same<typename std::remove_cv<U>::type, void>::value ||
// Non-member functions //
+ /**
+ * @brief Makes new instance of T as shared object
+ * @param[in] args Arguments for T constructor
+ * @return Shared reference to new T
+ */
template <class T, class ...ARGS>
SharedRef<T> makeShared(ARGS &&...args);
+
+ /**
+ * @brief Makes new instance of T as shared object
+ * @details Multiple thread may refer to this object
+ * @param[in] args Arguments for T constructor
+ * @return Shared reference to new T
+ */
template <class T, class ...ARGS>
SharedRef<T> makeSharedMT(ARGS &&...args);
+ /**
+ * @brief Const casts SharedRef<U> to SharedRef<T>
+ * @param[in] r Source shared reference
+ * @return Result shared reference
+ */
template <class T, class U>
const SharedRef<T> &constRefCast(const SharedRef<U> &r) noexcept;
+
+ /**
+ * @brief Const casts SharedRef<U> to SharedRef<T>
+ * @param[in] r Source shared reference
+ * @return Result shared reference
+ */
template <class T, class U>
SharedRef<T> &&constRefCast(SharedRef<U> &&r) noexcept;
}
namespace ucl {
+ /**
+ * @brief Implements weak reference (pointer) to T object
+ */
template <class T>
class WeakRef final : public BaseRef<T> {
public:
+ /**
+ * @brief Swaps WeakRef objects with each other
+ * @param[in/out] x First WeakRef
+ * @param[in/out] y Second WeakRef
+ */
template <class U>
friend void swap(WeakRef<U> &x, WeakRef<U> &y) noexcept;
+ /**
+ * @brief Statically casts WeakRef<U> to WeakRef<T2>
+ * @param[in] r Source weak reference
+ * @return Result weak reference
+ */
template <class T2, class U>
friend WeakRef<T2> staticRefCast(const WeakRef<U> &r) noexcept;
+
+ /**
+ * @brief Dynamically casts WeakRef<U> to WeakRef<T2>
+ * @param[in] r Source weak reference
+ * @return Result weak reference
+ */
template <class T2, class U>
friend WeakRef<T2> dynamicRefCast(const WeakRef<U> &r) noexcept;
public:
+ /**
+ * @brief Default constructor
+ * @details Creates expired reference
+ */
constexpr WeakRef() noexcept;
+
+ /**
+ * @brief Constructor
+ * @details Same as default constructor
+ */
constexpr WeakRef(std::nullptr_t) noexcept;
+ /**
+ * @brief Constructor
+ * @details Increments weak reference counter
+ * @param[in] rc Pointer to reference-counted objet
+ * @param[in] ptr Pointed object pointer
+ */
WeakRef(IRefCountObj *rc, T *ptr) noexcept;
+ /**
+ * @brief Copy constructor
+ * @param[in] r Source object
+ */
WeakRef(const WeakRef<T> &r) noexcept;
+
+ /**
+ * @brief Converting copy constructor
+ * @param[in] r Source object
+ */
template <class U>
WeakRef(const BaseRef<U> &r) noexcept;
+ /**
+ * @brief Move constructor
+ * @param[in] r Source object
+ */
WeakRef(WeakRef<T> &&r) noexcept;
+
+ /**
+ * @brief Converting move constructor
+ * @param[in] r Source object
+ */
template <class U>
WeakRef(WeakRef<U> &&r) noexcept;
+ /**
+ * @brief Destructor
+ * @details Decrements weak reference counter
+ */
~WeakRef();
+ /**
+ * @brief Assigns one WeakRef to another
+ * @param[in] r Source object
+ * @return Reference to this WeakRef
+ */
WeakRef<T> &operator=(WeakRef<T> r) noexcept;
+ /**
+ * @brief Makes this reference empty
+ */
void reset() noexcept;
+ /**
+ * @brief Returns SharedRef for this weak reference
+ * @details Will return empty shared reference if expired
+ */
SharedRef<T> lock() const noexcept;
+ /**
+ * @brief Gets pointed object pointer
+ * @details Do not dereference. Use as ID for comparison.
+ * @return Pointer object pointer
+ */
T *getUnsafePtr() const noexcept;
- operator bool() const noexcept;
+ /**
+ * @brief Explicitly casts to bool
+ * @return true - if not empty/expired, false - otherwise
+ */
+ explicit operator bool() const noexcept;
+
+ /**
+ * @brief Implicitly casts to compatible WeakRef type
+ * @return Reference to this object as casted type
+ */
template <class U, class = typename std::enable_if<
std::is_convertible<T *, U *>::value && (
std::is_same<typename std::remove_cv<U>::type, void>::value ||
// Non-member functions //
+ /**
+ * @brief Makes weak reference for specific shared reference
+ * @param[in] r Source shared reference
+ * @return Result weak reference
+ */
template <class T>
WeakRef<T> makeWeak(const SharedRef<T> &r) noexcept;
+ /**
+ * @brief Const casts WeakRef<U> to WeakRef<T>
+ * @param[in] r Source weak reference
+ * @return Result weak reference
+ */
template <class T, class U>
const WeakRef<T> &constRefCast(const WeakRef<U> &r) noexcept;
+
+ /**
+ * @brief Const casts WeakRef<U> to WeakRef<T>
+ * @param[in] r Source weak reference
+ * @return Result weak reference
+ */
template <class T, class U>
WeakRef<T> &&constRefCast(WeakRef<U> &&r) noexcept;
}
template <class T>
inline T *WeakRef<T>::getUnsafePtr() const noexcept
{
- return (operator bool() ? this->m_ptr : nullptr);
+ return this->m_ptr;
}
template <class T>
namespace util {
+ /**
+ * @brief Safely disposes object and resets shared reference
+ * @param[in/out] r Target shared reference
+ */
template <class T, class = typename std::enable_if<
std::is_convertible<T *, IDisposable *>::value>::type>
inline void dispose(SharedRef<T> &r) noexcept
}
}
+ /**
+ * @brief Safely disposes object and resets weak reference
+ * @param[in/out] r Target weak reference
+ */
template <class T, class = typename std::enable_if<
std::is_convertible<T *, IDisposable *>::value>::type>
inline void dispose(WeakRef<T> &r) noexcept
// Generic casting functions //
+ /**
+ * @brief Dynamically casts reference objects
+ * @param[in] src Source reference object
+ * @return Result reference object
+ */
template <class T, class U>
inline auto dynamicCast(const U &src) noexcept -> decltype(
dynamicRefCast<typename T::Type>(src))
return dynamicRefCast<typename T::Type>(src);
}
+ /**
+ * @brief Const casts reference objects
+ * @param[in] src Source reference object
+ * @return Result reference object
+ */
template <class T, class U>
inline auto constCast(U &&src) noexcept -> decltype(
constRefCast<typename T::Type>(std::forward<U>(src)))
namespace himpl {
+ template <class T>
+ struct IsShared : std::false_type {};
+ template <class T>
+ struct IsShared<SharedRef<T>> : std::true_type {};
+ template <class T>
+ struct IsShared<WeakRef<T>> : std::true_type {};
+
template <class T, class = typename std::enable_if<
- !std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+ !IsShared<T>::value>::type>
inline const T &getCmpPtr(const T &ptr) noexcept
{
return ptr;
}
}
+ /**
+ * @brief Compares equals target pointers/references
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
template <class T, class U, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value ||
- std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+ himpl::IsShared<T>::value || himpl::IsShared<U>::value>::type>
inline bool operator==(const T &lhs, const U &rhs) noexcept
{
return (himpl::getCmpPtr(lhs) == himpl::getCmpPtr(rhs));
}
+ /**
+ * @brief Compares unequals target pointers/references
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
template <class T, class U, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value ||
- std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+ himpl::IsShared<T>::value || himpl::IsShared<U>::value>::type>
inline bool operator!=(const T &lhs, const U &rhs) noexcept
{
return (himpl::getCmpPtr(lhs) != himpl::getCmpPtr(rhs));
}
+ /**
+ * @brief Compares less target pointers/references
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is less than right, false - otherwise
+ */
template <class T, class U, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value ||
- std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+ himpl::IsShared<T>::value || himpl::IsShared<U>::value>::type>
inline bool operator<(const T &lhs, const U &rhs) noexcept
{
return (himpl::getCmpPtr(lhs) < himpl::getCmpPtr(rhs));
}
+ /**
+ * @brief Compares less or equals target pointers/references
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is less or equals to right, false - otherwise
+ */
template <class T, class U, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value ||
- std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+ himpl::IsShared<T>::value || himpl::IsShared<U>::value>::type>
inline bool operator<=(const T &lhs, const U &rhs) noexcept
{
return (himpl::getCmpPtr(lhs) <= himpl::getCmpPtr(rhs));
}
+ /**
+ * @brief Compares greater target pointers/references
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is greater than right, false - otherwise
+ */
template <class T, class U, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value ||
- std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+ himpl::IsShared<T>::value || himpl::IsShared<U>::value>::type>
inline bool operator>(const T &lhs, const U &rhs) noexcept
{
return (himpl::getCmpPtr(lhs) > himpl::getCmpPtr(rhs));
}
+ /**
+ * @brief Compares greater or equals target pointers/references
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if left is greater or equals to right, false - otherwise
+ */
template <class T, class U, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value ||
- std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+ himpl::IsShared<T>::value || himpl::IsShared<U>::value>::type>
inline bool operator>=(const T &lhs, const U &rhs) noexcept
{
return (himpl::getCmpPtr(lhs) >= himpl::getCmpPtr(rhs));
}
+ /**
+ * @brief Compares equals target reference and NULL
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs NULL
+ * @return true - if equal, false - not equal
+ */
template <class T, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+ himpl::IsShared<T>::value>::type>
inline bool operator==(const T &lhs, std::nullptr_t rhs) noexcept
{
return !lhs;
}
+ /**
+ * @brief Compares equals target reference and NULL
+ * @param[in] lhs NULL
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
template <class T, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+ himpl::IsShared<T>::value>::type>
bool operator==(std::nullptr_t lhs, const T &rhs) noexcept
{
return !rhs;
}
+ /**
+ * @brief Compares unequals target reference and NULL
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs NULL
+ * @return true - if not equal, false - equal
+ */
template <class T, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+ himpl::IsShared<T>::value>::type>
bool operator!=(const T &lhs, std::nullptr_t rhs) noexcept
{
return lhs;
}
+ /**
+ * @brief Compares unequals target reference and NULL
+ * @param[in] lhs NULL
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
template <class T, class = typename std::enable_if<
- std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+ himpl::IsShared<T>::value>::type>
bool operator!=(std::nullptr_t lhs, const T &rhs) noexcept
{
return rhs;
#ifndef __UCL_UTIL_MEMORY_MACRO_H__
#define __UCL_UTIL_MEMORY_MACRO_H__
+#define UCL_DECLARE_REF_ALIASES_NOFW(TYPE_NAME) \
+ using TYPE_NAME##SRef = ::ucl::SharedRef<TYPE_NAME>; \
+ using TYPE_NAME##WRef = ::ucl::WeakRef<TYPE_NAME>; \
+ using TYPE_NAME##SCRef = ::ucl::SharedRef<const TYPE_NAME>; \
+ using TYPE_NAME##WCRef = ::ucl::WeakRef<const TYPE_NAME>
+
#define UCL_DECLARE_REF_ALIASES(CLASS_NAME) \
class CLASS_NAME; \
- using CLASS_NAME##SRef = ::ucl::SharedRef<CLASS_NAME>; \
- using CLASS_NAME##WRef = ::ucl::WeakRef<CLASS_NAME>; \
- using CLASS_NAME##SCRef = ::ucl::SharedRef<const CLASS_NAME>; \
- using CLASS_NAME##WCRef = ::ucl::WeakRef<const CLASS_NAME>
+ UCL_DECLARE_REF_ALIASES_NOFW(CLASS_NAME)
#define UCL_USING_REF_ALIASES(CLASS_NAME) \
using CLASS_NAME; \
template <class FUNC_SIG>
class WeakDelegate;
+ /**
+ * @brief Delegate that uses WeakRef<void> as data pointer
+ */
template <class R, class ...ARGS>
class WeakDelegate<R(ARGS...)> :
public BaseDelegate<R(ARGS...), WeakRef<void>> {
+ public:
+ /**
+ * @brief Constant reference to regular Delegate with same signature
+ * @details Useful as unsubscribe delegate. Especially useful in
+ * destructors because asWeak(*this) will return NULL
+ * reference.
+ */
+ using CDRef = const Delegate<R(ARGS...)> &;
+
+ /**
+ * @brief Result delegate of the lock() method
+ */
+ class LockDelegate {
+ public:
+ /**
+ * @brief Checks if this delegate is not NULL
+ * @return true - if not NULL, false - if NULL
+ */
+ explicit operator bool() const noexcept;
+
+ /**
+ * @brief Invokes this delegate
+ * @details Delgates must be checked for NULL before invoke.
+ * @params[in] args Arguments of the invoke
+ * @return Result of the invoke
+ */
+ R operator()(ARGS ...args) const;
+
+ private:
+ LockDelegate(SharedRef<void> data,
+ typename WeakDelegate::StubA stubA) noexcept;
+ private:
+ SharedRef<void> m_data;
+ typename WeakDelegate::StubA m_stubA;
+ friend class WeakDelegate;
+ };
+
public:
using BaseDelegate<R(ARGS...), WeakRef<void>>::BaseDelegate;
- R operator()(ARGS ...args) const;
+ /**
+ * @brief Locks this delegate for further invoke
+ * @return Lock delegate
+ */
+ LockDelegate lock() const;
+ /**
+ * @brief Creates delegate to shared instance method
+ * @param[in] data This weak reference of the instance
+ * @return Created delegate
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
- static WeakDelegate make(const WeakRef<CLASS> &data) noexcept;
+ static WeakDelegate make(WeakRef<CLASS> data) noexcept;
+ /**
+ * @brief Creates delegate to constant shared instance method
+ * @param[in] data Constant this weak reference of the instance
+ * @return Created delegate
+ */
template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
- static WeakDelegate make(const WeakRef<const CLASS> &data) noexcept;
+ static WeakDelegate make(WeakRef<const CLASS> data) noexcept;
};
}
namespace ucl {
+ // WeakDelegate<R(ARGS...)>::Lock //
+
+ template <class R, class ...ARGS>
+ inline WeakDelegate<R(ARGS...)>::LockDelegate::LockDelegate(
+ SharedRef<void> data,
+ const typename WeakDelegate::StubA stubA) noexcept :
+ m_data(std::move(data)),
+ m_stubA(stubA)
+ {
+ }
+
template <class R, class ...ARGS>
- inline R WeakDelegate<R(ARGS...)>::operator()(ARGS ...args) const
+ inline WeakDelegate<R(ARGS...)>::LockDelegate::
+ operator bool() const noexcept
{
- const auto tmp = this->m_data.lock();
- if (tmp) {
- return this->m_stubA(tmp.get(), std::forward<ARGS>(args)...);
- }
- return R();
+ return !!m_data;
+ }
+
+ template <class R, class ...ARGS>
+ inline R WeakDelegate<R(ARGS...)>::LockDelegate::
+ operator()(ARGS ...args) const
+ {
+ return m_stubA(m_data.get(), std::forward<ARGS>(args)...);
+ }
+
+ // WeakDelegate<R(ARGS...)> //
+
+ template <class R, class ...ARGS>
+ typename WeakDelegate<R(ARGS...)>::LockDelegate
+ WeakDelegate<R(ARGS...)>::lock() const
+ {
+ return {this->m_data.lock(), this->m_stubA};
}
template <class R, class ...ARGS>
template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
inline WeakDelegate<R(ARGS...)> WeakDelegate<R(ARGS...)>::make(
- const WeakRef<CLASS> &data) noexcept
+ WeakRef<CLASS> data) noexcept
{
- return {data, WeakDelegate::Cb::template stubA<CLASS, METHOD>};
+ return {std::move(data),
+ WeakDelegate::Cb::template stubA<CLASS, METHOD>};
}
template <class R, class ...ARGS>
template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
inline WeakDelegate<R(ARGS...)> WeakDelegate<R(ARGS...)>::make(
- const WeakRef<const CLASS> &data) noexcept
+ WeakRef<const CLASS> data) noexcept
{
- return {constRefCast<CLASS>(data),
+ return {constRefCast<CLASS>(std::move(data)),
WeakDelegate::Cb::template stubA<CLASS, METHOD>};
}
}
#ifndef __UCL_UTIL_SMART_DELEGATION_MACRO_H__
#define __UCL_UTIL_SMART_DELEGATION_MACRO_H__
-#define UCL_WEAK_DELEGATE(FUNC, DATA) \
- _UCL_DELEGATE(::ucl::WeakDelegate, FUNC, DATA)
+/**
+ * @brief Creates WeakDelegate<auto> to specified shared instance method
+ * @param FUNC Function for the delegate without &
+ * @param DATA Weak reference of the instance
+ * @return Created delegate
+ */
+#define UCL_WEAK_DELEGATE(FUNC, DATA) _UCL_DELEGATE( \
+ ::ucl::WeakDelegate, FUNC, DATA)
+
+/**
+ * @brief Creates WeakDelegate<auto> to shared "this" instance method
+ * @param FUNC_NAME name of the function of the "this" class
+ * @return Created delegate
+ */
+#define UCL_WEAK_DELEGATE_THIS(FUNC_NAME) UCL_WEAK_DELEGATE( \
+ std::remove_pointer<decltype(this)>::type::FUNC_NAME, asWeak(*this))
#endif // __UCL_UTIL_SMART_DELEGATION_MACRO_H__
#define WEAK_DELEGATE(FUNC, DATA) UCL_WEAK_DELEGATE(FUNC, DATA)
+#define WEAK_DELEGATE_THIS(FUNC_NAME) UCL_WEAK_DELEGATE_THIS(FUNC_NAME)
+
#endif // __UCL_UTIL_SMART_DELEGATION_SHORT_MACRO_H__
namespace ucl {
- class CondVar final : public NonCopyable {
+ /**
+ * @brief Implements conditional variable
+ */
+ class CondVar final : private NonCopyable {
public:
+ /**
+ * @brief Constructor
+ */
CondVar();
+
+ /**
+ * @brief Destructor
+ */
~CondVar();
+
+ /**
+ * @brief Waits on MutexLock until notification
+ * @param[in] lock Target MutexLock object
+ */
void wait(MutexLock &lock);
+
+ /**
+ * @brief Notifies single waiter of this variable
+ */
void notify();
+
+ /**
+ * @brief Notifies all waiters of this variable
+ */
void notifyAll();
+
+ /**
+ * @brief Gets native pthread conditional variable
+ * @return Pointer to pthread conditional variable
+ */
pthread_cond_t *getHandle();
+
private:
pthread_cond_t m_cond;
};
namespace ucl {
- class Mutex final : public NonCopyable {
+ /**
+ * @brief Implements mutex
+ */
+ class Mutex final : protected NonCopyable {
public:
+ /**
+ * @brief Constructor
+ * @param[in] recursive Allow reentrancy for this mutex
+ */
Mutex(bool recursive = false);
+
+ /**
+ * @brief Destructor
+ */
~Mutex();
+
+ /**
+ * @brief Acquires lock for this mutex by calling thread
+ */
void lock();
+
+ /**
+ * @brief Releases lock for this mutex from calling thread
+ */
void unlock();
+
+ /**
+ * @brief Gets native pthread mutex
+ * @return Pointer to pthread mutex
+ */
pthread_mutex_t *getHandle();
+
private:
pthread_mutex_t m_mutex;
};
namespace ucl {
- class MutexLock final : public NonCopyable {
+ /**
+ * @brief Implements mutex lock
+ */
+ class MutexLock final : protected NonCopyable {
public:
+ /**
+ * @brief Constructor
+ * @details Locks target mutex
+ * @param[in] mutex Target mutex
+ */
MutexLock(Mutex &mutex);
+
+ /**
+ * @brief Destructor
+ * @details Unlocks locked mutex
+ */
~MutexLock();
+
+ /**
+ * @brief Gets locked mutex
+ * @return Reference to locked mutex
+ */
Mutex &getMutex();
+
private:
Mutex &m_mutex;
};
#ifndef __UCL_UTIL_THREADING_THREAD_H__
#define __UCL_UTIL_THREADING_THREAD_H__
-// Use pthread because Tizen 3.0 officially not support C++ 11
-// And there were problems with threading in C++ 11 and Tizen 3.0
+// Use pthread because Tizen officially not support C++ 11
+// And there were problems with threading in C++ 11 and Tizen
#include <pthread.h>
#include "ucl/util/types/classTypes.h"
namespace ucl {
- class Thread final : public NonCopyable {
+ /**
+ * @brief Implements executing thread
+ */
+ class Thread final : protected NonCopyable {
public:
+ /**
+ * @brief Constructor
+ * @details Creates idling thread
+ */
Thread();
+
+ /**
+ * @brief Constructor
+ * @details Creates running thread
+ * @param[in] func Function to call in new the thread
+ */
template <class FUNC>
explicit Thread(FUNC &&func);
+
+ /**
+ * @brief Destructor
+ * @details Joins if was started and not joined
+ */
~Thread();
+ /**
+ * @brief Gets started status of the thread
+ * @return true - if was started, false - otherwise
+ */
bool wasStarted() const;
+
+ /**
+ * @brief Gets joined status of the thread
+ * @return true - if was joined, false - otherwise
+ */
bool wasJoinded() const;
+ /**
+ * @brief Starts the thread
+ * @param[in] func Function to call in the new thread
+ * @return true - if was started, false - otherwise
+ */
template <class FUNC>
bool start(FUNC &&func);
+
+ /**
+ * @brief Joins with the thread
+ */
void join();
+ /**
+ * @brief Gets native pthread thread
+ * @return Pointer to pthread thread
+ */
pthread_t *getHandle();
private:
inline Thread::~Thread()
{
- if (!m_wasJoined) {
+ if (m_wasStarted && !m_wasJoined) {
join();
}
}
inline void Thread::join()
{
if (!m_wasStarted) {
- UCL_WLOG("Not stared started!");
+ UCL_WLOG("Not started!");
return;
}
if (m_wasJoined) {
// ResultData declaration //
+ /**
+ * @brief Data that for specific result code
+ */
struct ResultData final {
const char *name;
int logPrio;
// Result declaration //
+ /**
+ * @brief Type safe container for "int" result codes
+ */
struct Result final {
+ /**
+ * @brief Result code value
+ */
int value;
+ /**
+ * @brief Defaulted default constructor
+ */
Result() = default;
+ /**
+ * @brief Conversion constructor
+ * @details v Value of result. Can be any type convertible to "int"
+ * that has "_UCL_RESULT" constant as public member.
+ */
template <class VALUE, class = char(*)[VALUE::_UCL_RESULT * 0 + 1]>
constexpr Result(const VALUE &v) : value(v) {}
};
// Result non-member functions //
+ /**
+ * @brief Gets result data for specific result code
+ * @param[in] result Specific result code
+ * @return Reference to ResultData
+ */
const ResultData &getResultData(Result result);
+ /**
+ * @brief Checks if specific result code is good (>= 0)
+ * @param[in] result Specific result code
+ * @return true - if good, false - otherwise
+ */
constexpr bool isGood(Result result);
+
+ /**
+ * @brief Checks if specific result code is bad (< 0)
+ * @param[in] result Specific result code
+ * @return true - if bad, false - otherwise
+ */
constexpr bool isBad(Result result);
+ /**
+ * @brief Compares equals values of target results
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if equal, false - not equal
+ */
constexpr bool operator==(Result lhs, Result rhs);
+
+ /**
+ * @brief Compares unequals values of target results
+ * @param[in] lhs Left hand side operand
+ * @param[in] rhs Right hand side operand
+ * @return true - if not equal, false - equal
+ */
constexpr bool operator!=(Result lhs, Result rhs);
// Basic Result values //
+ /**
+ * @brief Enumeration of basic result codes
+ */
enum {
+ /**
+ * @brief Allows conversion to Result
+ */
_UCL_RESULT,
RES_OK = 0,
RES_FALSE = 1,
+
+ /**
+ * @brief Denotes past-end result code of the enumeration range
+ * @details Do not move this value around.
+ */
_RES_END,
RES_FAIL = -1,
RES_NOT_SUPPORTED = -6,
RES_INVALID_DATA = -7,
RES_FATAL = -8,
- // TODO MUST match previous item!
- _RES_BEGIN = RES_FATAL
+
+ /**
+ * @brief Denotes first result code of the enumeration range
+ * @details Must be last and match previous enumeration value
+ */
+ _RES_BEGIN = RES_FATAL
};
}
#include "ucl/config.h"
namespace ucl {
+
+ /**
+ * @brief Alias for "unsigned int"
+ */
using UInt = unsigned int;
}
namespace ucl {
+ /**
+ * @brief Base class for all non-copyable objects
+ */
class NonCopyable {
public:
+ /**
+ * @brief Deleted copy constructor
+ */
NonCopyable(const NonCopyable &) = delete;
+
+ /**
+ * @brief Deleted assignment operator
+ */
NonCopyable &operator=(const NonCopyable &) = delete;
+
+ private:
+ struct PrivateType {};
+
protected:
- NonCopyable() = default;
- ~NonCopyable() = default;
- };
+ /**
+ * @brief Tag-type for restricting non public access
+ */
+ using Private = const PrivateType &;
+
+ /**
+ * @brief Value for Private type to allow access
+ */
+ static const PrivateType PRIVATE;
- class Polymorphic : public NonCopyable {
protected:
- Polymorphic() = default;
- virtual ~Polymorphic() = default;
+ /**
+ * @brief Default constructor
+ */
+ NonCopyable() = default;
+
+ /**
+ * @brief Destructor
+ */
+ ~NonCopyable() = default;
};
- class IDisposable : public Polymorphic {
+ /**
+ * @brief Interface for object that cen be disposed (half destroyed)
+ */
+ class IDisposable : protected NonCopyable {
public:
+ /**
+ * @brief Disposes the object if not already disposed
+ */
virtual void dispose() = 0;
+
+ /**
+ * @brief Gets the dispose state
+ * @return true - if disposed, false - otherwise
+ */
virtual bool isDisposed() const = 0;
+
protected:
- virtual ~IDisposable() = default;
+ /**
+ * @brief Destructor
+ */
+ ~IDisposable() = default;
};
+ /**
+ * @brief Template interface for factory that builds IPRODUCT
+ */
template <class IPRODUCT>
- class IFactory : public Polymorphic {
+ class IFactory : protected NonCopyable {
public:
+ /**
+ * @brief Alias for "IPRODUCT"
+ */
using IProduct = IPRODUCT;
+
public:
+ /**
+ * @brief Creates new instance of type IPRODUCT
+ * @return Pointer to new instance of type IPRODUCT
+ */
virtual IPRODUCT *newInstance() const = 0;
+
protected:
- virtual ~IFactory() = default;
+ /**
+ * @brief Destructor
+ */
+ ~IFactory() = default;
};
+ /**
+ * @brief Template implementation of factory that builds PRODUCT
+ */
template <class PRODUCT, class IPRODUCT>
class Factory final : public IFactory<IPRODUCT> {
public:
+ /**
+ * @brief Alias for "PRODUCT"
+ */
using Product = PRODUCT;
+
public:
+ /**
+ * @brief Creates new instance of PRODUCT
+ * @return Pointer to new instance of PRODUCT as IPRODUCT
+ */
virtual IPRODUCT *newInstance() const final override
{
return new PRODUCT();
}
};
- // Priority selector for SFINAE functions
+ /**
+ * @brief Priority selector for SFINAE functions
+ * @details Main tamplate for N > 0
+ */
template <int N>
struct P : P<N - 1> {};
+
+ /**
+ * @brief Priority selector for SFINAE functions
+ * @details Breaks recursion for N = 0
+ */
template <>
struct P<0> {};
}
// SysEventProvider::EventProxy //
- class SysEventProvider::EventProxy : public NonCopyable {
+ class SysEventProvider::EventProxy : protected NonCopyable {
public:
EventProxy(SysEventProvider &provider,
const SysEvent sysEvent,
{
m_instance.reset();
m_instanceMgr.setSysEventProvider(nullptr);
- m_window.reset();
+ if (m_window) {
+ m_window->setIsOwner(false);
+ m_window->markForDeletion();
+ m_window.reset();
+ }
}
void UIApp::onPause()
elm_app_base_scale_set(baseScale);
}
- if (appParams.get(AppParam::ACCELERATION_PREFERENECE, paramValue)) {
+ if (appParams.get(AppParam::ACCELERATION_PREFERENCE, paramValue)) {
const auto accelPreference = paramValue.asString();
if (isEmpty(accelPreference)) {
LOG_RETURN(RES_INVALID_DATA,
- "Invalid parameter ACCELERATION_PREFERENECE: %s",
+ "Invalid parameter ACCELERATION_PREFERENCE: %s",
accelPreference.get());
}
elm_config_accel_preference_set(accelPreference.get());
void UIApp::initSysEventManager()
{
m_instanceMgr.setSysEventProvider(
- util::makeUnique(new SysEventProvider(
+ util::makeUnique<SysEventProvider>(
&ui_app_add_event_handler,
- &ui_app_remove_event_handler)));
+ &ui_app_remove_event_handler));
}
Result UIApp::createInstance()
}
const auto res = instance->onCreate(this);
- if (isBad(res)) {
+ if (res != RES_OK) {
LOG_RETURN(res, "instance->onCreate() failed!");
}
namespace ucl {
- ElmWidget::ElmWidget(IRefCountObj *rc, Evas_Object *eo, bool isOwner) :
- Widget(rc, eo, isOwner),
- m_isAtspiGestureCbSet(false)
- {
- }
-
- ElmWidget::~ElmWidget()
- {
- if (m_isAtspiGestureCbSet) {
- elm_atspi_accessible_gesture_cb_set(getEo(), nullptr, nullptr);
- }
- }
-
void ElmWidget::setFocusedImpl(const bool value)
{
elm_object_focus_set(getEo(), toEina(value));
return elm_object_focus_get(getEo());
}
- bool ElmWidget::ensureFwdEvent(const SmartEvent fwdEvent)
- {
- if (Widget::ensureFwdEvent(fwdEvent)) {
- return true;
- }
- if (fwdEvent == ATSPI_ON_GESTURE) {
- if (!m_isAtspiGestureCbSet) {
- m_isAtspiGestureCbSet = true;
- elm_atspi_accessible_gesture_cb_set(getEo(),
- CALLBACK_A(ElmWidget::onAtspiGesture), this);
- }
- return true;
- }
- return false;
- }
-
- Eina_Bool ElmWidget::onAtspiGesture(Elm_Atspi_Gesture_Info gestureInfo,
- Evas_Object *obj)
- {
- AtspiGestureEventInfo eventInfo{gestureInfo};
- callEvent(ATSPI_ON_GESTURE, &eventInfo);
- return toEina(eventInfo.preventDefault);
- }
-
Window *ElmWidget::getWindow() const
{
return dynamicWidgetCast<Window>(getTopWidget());
LayoutSRef Layout::Builder::build(ElmWidget &parent) const
{
- Evas_Object *const eo = elm_layout_add(parent);
+ Evas_Object *const eo = elm_layout_add(as_eo(parent));
if (!eo) {
LOG_RETURN_VALUE(RES_FAIL, {}, "elm_layout_add() failed!");
}
NaviframeSRef Naviframe::Builder::build(ElmWidget &parent) const
{
- Evas_Object *const eo = elm_naviframe_add(parent);
+ Evas_Object *const eo = elm_naviframe_add(as_eo(parent));
if (!eo) {
ELOG("elm_naviframe_add() failed!");
return {};
}
- auto result = makeShared<Naviframe>(eo);
+ auto result = makeShared<Naviframe>(eo, PRIVATE);
if (m_needBindToEo) {
result->bindToEo();
// Naviframe //
- Naviframe::Naviframe(IRefCountObj &rc, Evas_Object *eo) :
+ Naviframe::Naviframe(IRefCountObj &rc, Evas_Object *eo, Private) :
StyledWidget(&rc, eo),
m_isInTransition(false)
{
- addEventHandler(NAVI_TRANSITION_FINISHED, WEAK_DELEGATE(
- Naviframe::onTransitionFinished, asWeak(*this)));
+ addEventHandler(NAVI_TRANSITION_FINISHED,
+ WEAK_DELEGATE_THIS(onTransitionFinished));
}
void Naviframe::setInTransition(const bool inTransition)
// Widget::EventProxy //
- class Widget::EventProxy : public NonCopyable {
+ class Widget::EventProxy : protected NonCopyable {
public:
EventProxy(Widget &widget, const WidgetEvent event,
- const WidgetEventHandler handler) :
+ WidgetEventHandler handler) :
m_widget(widget),
- m_handler(handler),
+ m_handler(std::move(handler)),
m_type(static_cast<Evas_Callback_Type>(event))
{
- evas_object_event_callback_add(m_widget.getEo(),
+ evas_object_event_callback_add(as_eo(m_widget),
m_type, event_cb, this);
}
EventProxy(Widget &widget, const SmartEvent event,
- const WidgetEventHandler handler) :
+ WidgetEventHandler handler) :
m_widget(widget),
m_smartEvent(event),
- m_handler(handler),
+ m_handler(std::move(handler)),
m_type(impl::WIDGET_EVENT_SMART)
{
- evas_object_smart_callback_add(m_widget.getEo(),
+ evas_object_smart_callback_add(as_eo(m_widget),
m_smartEvent.c_str(), smart_cb, this);
}
~EventProxy()
{
if (m_type == impl::WIDGET_EVENT_SMART) {
- evas_object_smart_callback_del_full(m_widget.getEo(),
+ evas_object_smart_callback_del_full(as_eo(m_widget),
m_smartEvent.c_str(), smart_cb, this);
} else {
- evas_object_event_callback_del_full(m_widget.getEo(),
+ evas_object_event_callback_del_full(as_eo(m_widget),
m_type, event_cb, this);
}
}
m_selfIt = it;
}
- bool operator==(const std::pair<WidgetEvent, WidgetEventHandler> &rhs)
+ bool operator==(
+ const std::pair<WidgetEvent, WidgetEventHandler::CDRef> &rhs)
{
return ((m_type == static_cast<Evas_Callback_Type>(rhs.first)) &&
(m_handler == rhs.second));
}
- bool operator==(const std::pair<SmartEvent, WidgetEventHandler> &rhs)
+ bool operator==(
+ const std::pair<SmartEvent, WidgetEventHandler::CDRef> &rhs)
{
return ((m_type == impl::WIDGET_EVENT_SMART) &&
(m_handler == rhs.second) &&
void dispatchEvent(void *const event_info)
{
- if (m_handler) {
- m_handler(m_widget, event_info);
+ if (const auto handler = m_handler.lock()) {
+ handler(m_widget, event_info);
} else {
m_widget.delEventProxy(m_selfIt);
}
}
void Widget::addEventHandler(const WidgetEvent event,
- const WidgetEventHandler handler)
+ WidgetEventHandler handler)
{
- m_eventProxies.emplace_front(*this, event, handler);
+ m_eventProxies.emplace_front(*this, event, std::move(handler));
m_eventProxies.front().setSelfIt(m_eventProxies.begin());
}
void Widget::addEventHandler(const SmartEvent event,
- const WidgetEventHandler handler)
+ WidgetEventHandler handler)
{
if (strncmp(event.name, UCL_SMART_FWD, strlen(UCL_SMART_FWD)) == 0) {
if (!ensureFwdEvent(event)) {
"Event is not supported: %s;", event.name);
}
}
- m_eventProxies.emplace_front(*this, event, handler);
+ m_eventProxies.emplace_front(*this, event, std::move(handler));
m_eventProxies.front().setSelfIt(m_eventProxies.begin());
}
void Widget::delEventHandler(const WidgetEvent event,
- const WidgetEventHandler handler)
+ WidgetEventHandler::CDRef handler)
{
delEventProxy(std::find(m_eventProxies.begin(), m_eventProxies.end(),
std::make_pair(event, handler)));
}
void Widget::delEventHandler(const SmartEvent event,
- const WidgetEventHandler handler)
+ WidgetEventHandler::CDRef handler)
{
delEventProxy(std::find(m_eventProxies.begin(), m_eventProxies.end(),
std::make_pair(event, handler)));
}
}
- StyledWidget bg(elm_bg_add(winEo));
+ StyledWidget bg(elm_bg_add(winEo), false);
expand(bg);
show(bg);
- StyledWidget conform(elm_conformant_add(winEo));
+ StyledWidget conform(elm_conformant_add(winEo), false);
expand(conform);
show(conform);
- elm_win_resize_object_add(winEo, bg);
- elm_win_resize_object_add(winEo, conform);
+ elm_win_resize_object_add(winEo, as_eo(bg));
+ elm_win_resize_object_add(winEo, as_eo(conform));
elm_win_indicator_opacity_set(winEo, ELM_WIN_INDICATOR_OPAQUE);
elm_win_conformant_set(winEo, EINA_TRUE);
- auto result = makeShared<Window>(winEo, isOwner, conform);
+ auto result = makeShared<Window>(winEo, isOwner,
+ as_eo(conform), PRIVATE);
if (m_needBindToEo) {
result->bindToEo();
namespace ucl {
- TimeoutSRef Timeout::create(double timeoutSec,
- const TimeoutHandler &handler)
+ TimeoutSRef Timeout::create(double timeoutSec, TimeoutHandler handler)
{
- auto result = makeShared<Timeout>(handler);
+ auto result = makeShared<Timeout>(std::move(handler), PRIVATE);
FAIL_RETURN_VALUE(result->prepare(timeoutSec), {},
"result->prepare() failed!");
return result;
}
- Timeout::Timeout(const TimeoutHandler &handler) :
- m_timer(nullptr),
- m_handler(handler)
+ Timeout::Timeout(TimeoutHandler handler, Private) :
+ m_handler(std::move(handler)),
+ m_timer(nullptr)
{
}
{
const auto self = static_cast<Timeout *>(data);
self->m_timer = nullptr;
- if (self->m_handler) {
- self->m_handler(self);
+ if (const auto handler = self->m_handler.lock()) {
+ handler(self);
}
return ECORE_CALLBACK_CANCEL;
},
if (const auto parentSink = m_parentSink.lock()) {
delDeactivatorSource(*parentSink);
}
- } else if (m_window) {
- delDeactivatorSource(*m_window);
+ } else if (const auto window = getWindowRef()) {
+ delDeactivatorSource(*window);
}
}
}
Result GuiPresenter::prepare(ElmWidget &widget, const int flags)
{
- m_window = asShared(widget.getWindow());
- if (!m_window) {
- LOG_RETURN(RES_FAIL, "m_window is NULL!");
+ const auto window = asShared(widget.getWindow());
+ if (!window) {
+ LOG_RETURN(RES_FAIL, "window is NULL!");
}
if (flags & PF_ADD_DEACTIVATOR_SOURCES) {
- addDeactivatorSource(*m_window);
+ addDeactivatorSource(*window);
m_hasBuildInSources = true;
}
addDeactivatorException(getObjPtr());
}
+ m_window = window;
m_isPrepared = true;
return RES_OK;
Result GuiPresenter::prepare(GuiPresenter &parent, const int flags)
{
+ const auto window = parent.getWindowRef();
+ if (!window) {
+ LOG_RETURN(RES_FAIL, "window is NULL!");
+ }
+
if (flags & PF_ADD_DEACTIVATOR_SOURCES) {
if (!parent.m_sink) {
LOG_RETURN(RES_FAIL, "parent.m_sink is NULL!");
addDeactivatorException(getObjPtr());
}
- m_window = parent.m_window;
+ m_window = window;
m_isChild = true;
m_isPrepared = true;
Window &GuiPresenter::getWindow()
{
- UCL_ASSERT(isWindowReady(), "m_window is NULL!");
- return *m_window;
+ const auto window = getWindowRef();
+ UCL_ASSERT(window, "window is NULL!");
+ // Since GUI is single threaded Window instance will not be deleted
+ // on "window" shared reference destroy
+ return *window;
}
- bool GuiPresenter::isWindowReady() const
+ WindowSRef GuiPresenter::getWindowRef()
{
- return !!m_window;
+ return m_window.lock();
}
void GuiPresenter::addDeactivatorException(const void *const deactivator)
m_sink = sink;
}
+ const void *GuiPresenter::getSelfDeactivator() const
+ {
+ // Just return some unknown pointer that will never be aliaced
+ return &m_isPrepared;
+ }
+
+ void GuiPresenter::activateSelf()
+ {
+ activateByImpl({getSelfDeactivator(), false});
+ }
+
+ void GuiPresenter::deactivateSelf()
+ {
+ deactivateByImpl({getSelfDeactivator(), false});
+ }
+
void GuiPresenter::sendActivate(Widget &sender)
{
sendDeactivator(sender, impl::ACTIVATE_BY, getObjPtr());
void GuiPresenter::broadcastDeactivator(const SmartEvent event,
const void *const deactivator)
{
- sendDeactivatorInfo(*m_window, event, {deactivator, true});
+ if (const auto window = getWindowRef()) {
+ sendDeactivatorInfo(*window, event, {deactivator, true});
+ }
}
void GuiPresenter::sendDeactivatorInfo(Widget &sender,
void GuiPresenter::addDeactivatorSource(Widget &source)
{
- source.addEventHandler(impl::ACTIVATE_BY, WEAK_DELEGATE(
- GuiPresenter::onActivateBySmart, asWeak(*this)));
- source.addEventHandler(impl::DEACTIVATE_BY, WEAK_DELEGATE(
- GuiPresenter::onDeactivateBySmart, asWeak(*this)));
+ source.addEventHandler(
+ impl::ACTIVATE_BY, WEAK_DELEGATE_THIS(onActivateBySmart));
+ source.addEventHandler(
+ impl::DEACTIVATE_BY, WEAK_DELEGATE_THIS(onDeactivateBySmart));
}
void GuiPresenter::delDeactivatorSource(Widget &source)
{
- source.delEventHandler(impl::ACTIVATE_BY, WEAK_DELEGATE(
- GuiPresenter::onActivateBySmart, asWeak(*this)));
- source.delEventHandler(impl::DEACTIVATE_BY, WEAK_DELEGATE(
- GuiPresenter::onDeactivateBySmart, asWeak(*this)));
+ source.delEventHandler(
+ impl::ACTIVATE_BY, DELEGATE_THIS(onActivateBySmart));
+ source.delEventHandler(
+ impl::DEACTIVATE_BY, DELEGATE_THIS(onDeactivateBySmart));
}
void GuiPresenter::activateByImpl(const DeactivatorInfo &info)
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucl/util/types/classTypes.h"
+
+namespace ucl {
+
+ const NonCopyable::PrivateType NonCopyable::PRIVATE;
+}