// Related to ImageGrid //
const TString SLOT_PART_FMT {"swallow.cell_%d"};
+ constexpr EdjeSignal SIGNAL_ENABLE_SELECT_MODE
+ {"gallery,enable,select,mode"};
+ constexpr EdjeSignal SIGNAL_DISABLE_SELECT_MODE
+ {"gallery,disable,select,mode"};
+ constexpr EdjeSignal SIGNAL_TRANSITION_FINISHED
+ {"gallery,transition,finished"};
+
// Related to Button //
constexpr ElmStyle ITEM_BTN_STYLE {"gallery_image"};
constexpr EdjePart PART_BTN_BG {"swallow.bg"};
}
}
- Widget &getWidget()
+ Layout &getLayout()
{
return m_layout;
}
- int calcSize()
+ int getSize()
{
int w = 0;
int h = 0;
- m_layout.calculate();
m_layout.getMin(&w, &h);
- return (m_info.isHorizontal ? w : h);
+ return std::max((m_info.isHorizontal ? w : h), 1);
}
void setImageLoadSize(const int value)
m_scrollOffset(0),
m_unrealizeLock(0),
- m_eventsLock(0)
+ m_eventsLock(0),
+
+ m_animator(nullptr),
+ m_isInSelectMode(false),
+ m_isRotaryActive(false)
{
prepare();
--m_eventsLock;
}
+ ImageGrid::~ImageGrid()
+ {
+ if (m_animator) {
+ finalizeTransition();
+ }
+ }
+
const ImageGrid::Info &ImageGrid::getInfo(const Type type)
{
switch (type) {
m_listener = listener;
}
- void ImageGrid::setItemCount(const int count)
+ Result ImageGrid::setItemCount(const int count)
{
+ if (m_animator) {
+ LOG_RETURN(RES_ILLEGAL_STATE, "Transition is in progress.");
+ }
+
if (m_itemCount == count) {
- return;
+ return RES_FALSE;
}
++m_eventsLock;
updateRectMins();
--m_eventsLock;
+
+ return RES_OK;
+ }
+
+ Result ImageGrid::setSelectModeEnabled(const bool enabled)
+ {
+ if (m_animator) {
+ LOG_RETURN(RES_ILLEGAL_STATE, "Transition is in progress.");
+ }
+
+ if (enabled == m_isInSelectMode) {
+ return RES_FALSE;
+ }
+
+ if ((m_scrollOffset % m_slotSize) > 0) {
+ DLOG("Can't handle it right now!");
+ return RES_FAIL;
+ }
+
+ m_isInSelectMode = enabled;
+
+ elm_object_scroll_freeze_push(*m_scroller);
+ evas_object_freeze_events_set(*m_scroller, EINA_TRUE);
+ eext_rotary_object_event_activated_set(m_circleScroller, EINA_FALSE);
+
+ const auto aSignal = (enabled ?
+ impl::SIGNAL_ENABLE_SELECT_MODE :
+ impl::SIGNAL_DISABLE_SELECT_MODE);
+ for (auto &slot: m_slots) {
+ slot->getLayout().emitSignal(aSignal);
+ }
+
+ m_animator = ecore_animator_add(
+ CALLBACK_A(ImageGrid::onAnimationFrame), this);
+
+ evas_object_event_callback_priority_add(m_box,
+ EVAS_CALLBACK_RESIZE, EO_CALLBACK_PRIORITY_AFTER,
+ CALLBACK_A(ImageGrid::onBoxResize), this);
+
+ elm_object_signal_callback_add(
+ m_slots[m_beginSlotIndex & 1]->getLayout(),
+ impl::SIGNAL_TRANSITION_FINISHED.name, "",
+ CALLBACK_A(ImageGrid::onTransitonFinished), this);
+
+ return RES_OK;
+ }
+
+ bool ImageGrid::isInSelectMode() const
+ {
+ return m_isInSelectMode;
+ }
+
+ bool ImageGrid::isInTransition() const
+ {
+ return !!m_animator;
+ }
+
+ void ImageGrid::onTransitonFinished(Evas_Object *obj,
+ const char *emission, const char *source)
+ {
+ evalSlotSizes();
+
+ finalizeTransition();
+
+ elm_object_scroll_freeze_pop(*m_scroller);
+ evas_object_freeze_events_set(*m_scroller, EINA_FALSE);
+ if (m_isRotaryActive) {
+ eext_rotary_object_event_activated_set(m_circleScroller, EINA_TRUE);
+ }
+
+ if (m_listener) {
+ m_listener->onTransitionFinished();
+ }
+ }
+
+ void ImageGrid::finalizeTransition()
+ {
+ if (m_animator) {
+ ecore_animator_del(m_animator);
+ m_animator = nullptr;
+ }
+
+ evas_object_event_callback_del_full(m_box, EVAS_CALLBACK_RESIZE,
+ CALLBACK_A(ImageGrid::onBoxResize), this);
+
+ elm_object_signal_callback_del(
+ m_slots[m_beginSlotIndex & 1]->getLayout(),
+ "gallery,transition,finished", "",
+ CALLBACK_A(ImageGrid::onTransitonFinished));
+ }
+
+ Eina_Bool ImageGrid::onAnimationFrame()
+ {
+ evalSlotSizes();
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ void ImageGrid::evalSlotSizes()
+ {
+ for (auto &slot: m_slots) {
+ elm_layout_sizing_eval(slot->getLayout());
+ }
+ }
+
+ void ImageGrid::onBoxResize(Evas *e, Evas_Object *obj, void *eventInfo)
+ {
+ const int scrollLockIndex = (m_scrollOffset / m_slotSize);
+
+ if (updateSlotSize()) {
+
+ m_scrollOffset = (scrollLockIndex * m_slotSize);
+ if (m_info.isHorizontal) {
+ elm_scroller_region_show(*m_scroller,
+ m_scrollOffset, 0, m_scrollerSize, 1);
+ } else {
+ elm_scroller_region_show(*m_scroller,
+ 0, m_scrollOffset, 1, m_scrollerSize);
+ }
+
+ updatePadSizes();
+ updateScrollBias();
+ updateRectMins();
+ }
}
void ImageGrid::update()
Result ImageGrid::scrollToItem(const int itemIndex)
{
+ if (m_animator) {
+ LOG_RETURN(RES_ILLEGAL_STATE, "Transition is in progress.");
+ }
return showItem(itemIndex, elm_scroller_region_show);
}
Result ImageGrid::bringInItem(int itemIndex)
{
+ if (m_animator) {
+ LOG_RETURN(RES_ILLEGAL_STATE, "Transition is in progress.");
+ }
return showItem(itemIndex, elm_scroller_region_bring_in);
}
void ImageGrid::activateRotary()
{
- eext_rotary_object_event_activated_set(m_circleScroller, EINA_TRUE);
+ m_isRotaryActive = true;
+ if (!m_animator) {
+ eext_rotary_object_event_activated_set(m_circleScroller, EINA_TRUE);
+ }
}
void ImageGrid::deactivateRotary()
{
+ m_isRotaryActive = false;
eext_rotary_object_event_activated_set(m_circleScroller, EINA_FALSE);
}
void ImageGrid::addUnrealizeLock()
{
- unrealizeSlots(0, m_slotCount);
+ if (m_animator) {
+ ELOG("Transition is in progress.");
+ } else {
+ unrealizeSlots(0, m_slotCount);
+ }
++m_unrealizeLock;
}
{
if (m_unrealizeLock > 0) {
--m_unrealizeLock;
- realizeSlots();
+ if (m_animator) {
+ ELOG("Transition is in progress.");
+ } else {
+ realizeSlots();
+ }
} else {
WLOG("m_unrealizeLock = 0!");
}
if (m_slotSize == 0) {
UCL_ASSERT(!isOdd, "Must be even!");
- m_slotSize = std::max(slot->calcSize(), 1);
- const int pageSize = (m_slotSize * m_info.slotsPerPage);
- if (m_info.isHorizontal) {
- elm_scroller_page_size_set(*m_scroller, pageSize, 0);
- } else {
- elm_scroller_page_size_set(*m_scroller, 0, pageSize);
- }
+ slot->getLayout().calculate();
+ setSlotSize(slot->getSize());
}
slot->setImageLoadSize(m_slotSize);
- elm_box_pack_before(m_box, slot->getWidget(), m_rect2);
+ elm_box_pack_before(m_box, slot->getLayout(), m_rect2);
m_slots.emplace_back(std::move(slot));
}
const int spaceSize = (m_scrollerSize -
(std::max((m_scrollerSize / m_slotSize), 1) * m_slotSize));
- m_padSize1 = (spaceSize / 2);
+ m_padSize1 = std::lround(spaceSize / 2.0);
m_padSize2 = (spaceSize - m_padSize1 +
m_info.calcExtraPaddingSize(m_slotSize, m_itemCount));
}
}
}
+ bool ImageGrid::updateSlotSize()
+ {
+ const int newSlotSize = m_slots[m_beginSlotIndex & 1]->getSize();
+
+ if (newSlotSize != m_slotSize) {
+ DLOG("newSlotSize: %d; m_slotSize: %d;",
+ newSlotSize, m_slotSize);
+ setSlotSize(newSlotSize);
+ return true;
+ }
+
+ return false;
+ }
+
+ void ImageGrid::setSlotSize(const int newSlotSize)
+ {
+ m_slotSize = newSlotSize;
+ const int pageSize = (m_slotSize * m_info.slotsPerPage);
+ if (m_info.isHorizontal) {
+ elm_scroller_page_size_set(*m_scroller, pageSize, 0);
+ } else {
+ elm_scroller_page_size_set(*m_scroller, 0, pageSize);
+ }
+ }
+
int ImageGrid::calcScrollerSize()
{
int scrollerW = 0;
for (int i = 0; i < count; ++i) {
SlotUPtr slot = std::move(m_slots.back());
m_slots.pop_back();
- elm_box_unpack(m_box, slot->getWidget());
- elm_box_pack_after(m_box, slot->getWidget(), m_rect1);
+ elm_box_unpack(m_box, slot->getLayout());
+ elm_box_pack_after(m_box, slot->getLayout(), 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->getWidget());
- elm_box_pack_before(m_box, slot->getWidget(), m_rect2);
+ elm_box_unpack(m_box, slot->getLayout());
+ elm_box_pack_before(m_box, slot->getLayout(), m_rect2);
m_slots.emplace_back(std::move(slot));
}
}
void ImageGrid::handleScrolling()
{
+ if (m_animator) {
+ return;
+ }
+
if (m_eventsLock > 0) {
WLOG("Event handling was blocked!");
return;
void ImageGrid::handleResize()
{
+ if (m_animator) {
+ return;
+ }
+
if (m_eventsLock > 0) {
WLOG("Event handling was blocked!");
return;