diff --git a/data/theme/default/ChevronLeft.svg b/data/theme/default/ChevronLeft.svg new file mode 100644 index 00000000..c9c0f37c --- /dev/null +++ b/data/theme/default/ChevronLeft.svg @@ -0,0 +1,66 @@ + + + +image/svg+xml + + + + + + + \ No newline at end of file diff --git a/data/theme/default/ChevronLess.svg b/data/theme/default/ChevronLess.svg new file mode 100644 index 00000000..85466601 --- /dev/null +++ b/data/theme/default/ChevronLess.svg @@ -0,0 +1,66 @@ + + + +image/svg+xml + + + + + + + \ No newline at end of file diff --git a/data/theme/default/ChevronMore.svg b/data/theme/default/ChevronMore.svg new file mode 100644 index 00000000..da17476a --- /dev/null +++ b/data/theme/default/ChevronMore.svg @@ -0,0 +1,66 @@ + + + +image/svg+xml + + + + + + + \ No newline at end of file diff --git a/data/theme/default/ChevronRight.svg b/data/theme/default/ChevronRight.svg new file mode 100644 index 00000000..62d1accf --- /dev/null +++ b/data/theme/default/ChevronRight.svg @@ -0,0 +1,66 @@ + + + +image/svg+xml + + + + + + + \ No newline at end of file diff --git a/ewol/widget/List.cpp b/ewol/widget/List.cpp index 5a4042e8..2ed6efe5 100644 --- a/ewol/widget/List.cpp +++ b/ewol/widget/List.cpp @@ -26,6 +26,12 @@ ewol::widget::List::List() { m_limitScrolling = vec2(1, 0.5); } + +void ewol::widget::List::init() { + ewol::widget::WidgetScrolled::init(); +} + + ewol::widget::List::~List() { //clean all the object for (size_t iii=0; iiiy() == true) { int32_t fullSize = 0; for (auto &size: m_listSizeY) { @@ -160,6 +167,7 @@ void ewol::widget::List::onRegenerateDisplay() { } } } + */ // ------------------------------------------------------- // -- Calculate the start position size of each element // ------------------------------------------------------- @@ -277,30 +285,46 @@ bool ewol::widget::List::onEventInput(const ewol::event::Input& _event) { // nothing to do ... done on upper widet ... return true; } + if (m_listSizeY.size() == 0) { + return false; + } relativePos = vec2(relativePos.x(),m_size.y() - relativePos.y()) + m_originScrooled; // Find the colomn and the row - ivec2 pos{-1,-1}; - int32_t offset = 0; + ivec2 pos{0,0}; + float_t offsetY = 0; for (size_t iii=0; iii= previous ) { + int32_t previous = offsetY; + offsetY += m_listSizeY[iii]; + if ( relativePos.y() < offsetY + && relativePos.y() >= previous ) { pos.setY(iii); + offsetY = previous; + break; + } + if ( iii == m_listSizeY.size()-2 + && relativePos.y() >= offsetY ) { + pos.setY(iii+1); break; } } - offset = 0; + float_t offsetX = 0; for (size_t iii=0; iii= previous ) { + int32_t previous = offsetX; + offsetX += m_listSizeX[iii]; + if ( relativePos.x() < offsetX + && relativePos.x() >= previous ) { pos.setX(iii); + offsetX = previous; + break; + } + if ( iii == m_listSizeX.size()-2 + && relativePos.x() >= offsetX ) { + pos.setX(iii+1); break; } } - bool isUsed = onItemEvent(_event.getId(), _event.getStatus(), pos, _event.getPos()); + vec2 posInternalMouse = relativePos - vec2(offsetX, offsetY); + bool isUsed = onItemEvent(_event, pos, posInternalMouse); if (isUsed == true) { // TODO : this generate bugs ... I did not understand why .. //ewol::WidgetSharedManager::focusKeep(this); diff --git a/ewol/widget/List.hpp b/ewol/widget/List.hpp index d3e4b3c7..08fe0118 100644 --- a/ewol/widget/List.hpp +++ b/ewol/widget/List.hpp @@ -39,6 +39,7 @@ namespace ewol { class List : public ewol::widget::WidgetScrolled { protected: List(); + void init() override; public: virtual ~List(); void calculateMinMaxSize() override; @@ -103,7 +104,7 @@ namespace ewol { */ virtual void drawBackground(); - virtual bool onItemEvent(int32_t _IdInput, enum gale::key::status _typeEvent, const ivec2& _pos, const vec2& _mousePosition) { + virtual bool onItemEvent(const ewol::event::Input& _event, const ivec2& _pos, const vec2& _mousePosition) { return false; } /** diff --git a/ewol/widget/ListFileSystem.cpp b/ewol/widget/ListFileSystem.cpp index 158452d0..0ede4046 100644 --- a/ewol/widget/ListFileSystem.cpp +++ b/ewol/widget/ListFileSystem.cpp @@ -164,8 +164,7 @@ fluorine::Variant ewol::widget::ListFileSystem::getData(int32_t _role, const ive return fluorine::Variant(); } -bool ewol::widget::ListFileSystem::onItemEvent(int32_t _IdInput, - enum gale::key::status _typeEvent, +bool ewol::widget::ListFileSystem::onItemEvent(const ewol::event::Input& _event, const ivec2& _pos, const vec2& _mousePosition) { int32_t offset = 0; @@ -176,9 +175,9 @@ bool ewol::widget::ListFileSystem::onItemEvent(int32_t _IdInput, offset = 2; } } - if (_typeEvent == gale::key::status::pressSingle) { - EWOL_VERBOSE("Event on List : IdInput=" << _IdInput << " _pos=" << _pos ); - if (1 == _IdInput) { + if (_event.getStatus() == gale::key::status::pressSingle) { + EWOL_VERBOSE("Event on List : IdInput=" << _event.getId() << " _pos=" << _pos ); + if (1 == _event.getId()) { int32_t previousRaw = m_selectedLine; if (_pos.y() > (int32_t)m_list.size()+offset ) { m_selectedLine = -1; diff --git a/ewol/widget/ListFileSystem.hpp b/ewol/widget/ListFileSystem.hpp index 51ce1cb2..ac036ccd 100644 --- a/ewol/widget/ListFileSystem.hpp +++ b/ewol/widget/ListFileSystem.hpp @@ -46,7 +46,7 @@ namespace ewol { etk::Color<> getBasicBG() override; ivec2 getMatrixSize() const override; fluorine::Variant getData(int32_t _role, const ivec2& _pos) override; - bool onItemEvent(int32_t _IdInput, enum gale::key::status _typeEvent, const ivec2& _pos, const vec2& _mousePosition) override; + bool onItemEvent(const ewol::event::Input& _event, const ivec2& _pos, const vec2& _mousePosition) override; protected: // TODO: use shred_ptr etk::Vector m_list; //!< List of all element in the path. (they are filtered) diff --git a/ewol/widget/TreeView.cpp b/ewol/widget/TreeView.cpp index 90089e45..3a11403c 100644 --- a/ewol/widget/TreeView.cpp +++ b/ewol/widget/TreeView.cpp @@ -27,6 +27,11 @@ ewol::widget::TreeView::TreeView(): addObjectType("ewol::widget::TreeView"); } +void ewol::widget::TreeView::init() { + ewol::widget::List::init(); + propertyFill.set(bvec2(true,false)); +} + ewol::widget::TreeView::~TreeView() { } @@ -37,6 +42,14 @@ vec2 ewol::widget::TreeView::calculateElementSize(const ivec2& _pos) { float_t treeOffset = 0; if (_pos.x() == 0) { treeOffset += getData(ListRole::DistanceToRoot, _pos).getSafeNumber() * propertyOffsetTreeView.get(); + #if 0 + bool haveChild = getData(ListRole::HaveChild, _pos).getSafeBoolean(); + if (haveChild == true) { + treeOffset += propertyOffsetTreeView.get(); + } + #else + treeOffset += propertyOffsetTreeView.get(); + #endif } etk::String iconName; float_t iconSize = 0; @@ -46,7 +59,7 @@ vec2 ewol::widget::TreeView::calculateElementSize(const ivec2& _pos) { iconSize += propertyIconTreeViewSize.get(); } } - vec3 textSize = tmpText.calculateSize(myTextToWrite); + vec3 textSize = tmpText.calculateSizeDecorated(myTextToWrite); ivec2 count = getMatrixSize(); return vec2(textSize.x() + treeOffset + iconSize, etk::max(textSize.y(), iconSize) + m_paddingSizeY*3 @@ -56,16 +69,33 @@ vec2 ewol::widget::TreeView::calculateElementSize(const ivec2& _pos) { void ewol::widget::TreeView::drawElement(const ivec2& _pos, const vec2& _start, const vec2& _size) { vec2 posStart = _start; etk::String iconName; + etk::Color<> fg = getData(ListRole::FgColor, _pos).getSafeColor(); if (_pos.x() == 0) { auto value = getData(ListRole::DistanceToRoot, _pos); if (value.isNumber() == true) { posStart.setX(posStart.x() + value.getSafeNumber() * propertyOffsetTreeView.get()); } iconName = getData(ListRole::Icon, _pos).getSafeString(); + bool haveChild = getData(ListRole::HaveChild, _pos).getSafeBoolean(); + if (haveChild == true) { + ewol::compositing::Image * tmpImage = null; + if ( getData(ListRole::IsExpand, _pos).getSafeBoolean() == false) { + tmpImage = ETK_NEW(ewol::compositing::Image, "{ewol}THEME:GUI:ChevronRight.svg"); + } else { + tmpImage = ETK_NEW(ewol::compositing::Image, "{ewol}THEME:GUI:ChevronMore.svg"); + } + if (tmpImage != null) { + addOObject(tmpImage); + tmpImage->setColor(fg); + tmpImage->setPos(posStart); + tmpImage->print(vec2(propertyIconTreeViewSize.get(), propertyIconTreeViewSize.get())); + } + } + // move right + posStart.setX(posStart.x() + propertyIconTreeViewSize.get()); } etk::String myTextToWrite = getData(ListRole::Text, _pos).getSafeString(); - etk::Color<> fg = getData(ListRole::FgColor, _pos).getSafeColor(); auto backgroundVariant = getData(ListRole::BgColor, _pos); if (backgroundVariant.isColor() == true) { etk::Color<> bg = backgroundVariant.getColor(); @@ -95,7 +125,7 @@ void ewol::widget::TreeView::drawElement(const ivec2& _pos, const vec2& _start, addOObject(tmpText); tmpText->setColor(fg); tmpText->setPos(posStart); - tmpText->print(myTextToWrite);; + tmpText->printDecorated(myTextToWrite);; } } } @@ -104,3 +134,36 @@ void ewol::widget::TreeView::onChangePropertyOffsetTreeView() { markToRedraw(); } +bool ewol::widget::TreeView::onItemEvent(const ewol::event::Input& _event, const ivec2& _pos, const vec2& _mousePosition) { + if (_event.getStatus() != gale::key::status::pressSingle) { + return false; + } + if (_event.getId() != 1) { + return false; + } + if (_pos.x() != 0) { + return false; + } + //EWOL_INFO("event: " << _event); + vec2 posStart = vec2(0,0); + bool haveChild = getData(ListRole::HaveChild, _pos).getSafeBoolean(); + if (haveChild == false) { + return false; + } + auto value = getData(ListRole::DistanceToRoot, _pos); + if (value.isNumber() == true) { + posStart.setX(posStart.x() + value.getSafeNumber() * propertyOffsetTreeView.get()); + } + // Inverse the display of Y + EWOL_VERBOSE("check: " << vec2(_mousePosition.x(), m_listSizeY[_pos.y()] - _mousePosition.y()) + << " in " << posStart + << " -> " << (posStart+vec2(propertyIconTreeViewSize.get(),propertyIconTreeViewSize.get()))); + if ( _mousePosition.x() >= posStart.x() + && _mousePosition.x() <= posStart.x()+propertyIconTreeViewSize.get() + && m_listSizeY[_pos.y()] - _mousePosition.y() >= posStart.y() + && m_listSizeY[_pos.y()] - _mousePosition.y() <= propertyIconTreeViewSize.get() ) { + onItemExpandEvent(_pos); + return true; + } + return false; +} \ No newline at end of file diff --git a/ewol/widget/TreeView.hpp b/ewol/widget/TreeView.hpp index 6285df01..48f0ec50 100644 --- a/ewol/widget/TreeView.hpp +++ b/ewol/widget/TreeView.hpp @@ -28,6 +28,7 @@ namespace ewol { eproperty::Value propertyIconTreeViewSize; //!< Size of the icon. protected: TreeView(); + void init() override; public: virtual ~TreeView(); protected: @@ -48,6 +49,9 @@ namespace ewol { void drawElement(const ivec2& _pos, const vec2& _start, const vec2& _size) override; protected: virtual void onChangePropertyOffsetTreeView(); + + bool onItemEvent(const ewol::event::Input& _event, const ivec2& _pos, const vec2& _mousePosition) override; + virtual void onItemExpandEvent(const ivec2& _pos) { }; }; }; }; diff --git a/sample/treeView/appl/widget/BasicTree.cpp b/sample/treeView/appl/widget/BasicTree.cpp index b183b70e..7a4b79e1 100644 --- a/sample/treeView/appl/widget/BasicTree.cpp +++ b/sample/treeView/appl/widget/BasicTree.cpp @@ -7,31 +7,48 @@ #include "BasicTree.hpp" #include #include +#include #include ETK_DECLARE_TYPE(appl::widget::BasicTree); appl::widget::BasicTree::BasicTree() { addObjectType("appl::widget::BasicTree"); +} + +void appl::widget::BasicTree::init() { + ewol::widget::TreeView::init(); setMouseLimit(1); - m_tree = NodeElement::create(TreeElement("root", false, true)); + m_tree = etk::TreeNode::create(TreeElement("root", false, true)); for (size_t iii=0; iii<10; ++iii) { - auto elem_iii = NodeElement::create(TreeElement("elem_" + etk::toString(iii))); + auto elem_iii = etk::TreeNode::create(TreeElement("elem_" + etk::toString(iii), false, false)); m_tree->addChild(elem_iii); for (size_t jjj=0; jjjaddChild(elem_iii_jjj); + if (jjj%3 == 0) { + auto elem_iii_jjj = etk::TreeNode::create(TreeElement("elem_" + etk::toString(iii) + "____" + etk::toString(jjj) + "
an other line ...", false, false)); + elem_iii->addChild(elem_iii_jjj); + } else { + auto elem_iii_jjj = etk::TreeNode::create(TreeElement("elem_" + etk::toString(iii) + "____" + etk::toString(jjj), false, false)); + elem_iii->addChild(elem_iii_jjj); + } } } + updateFlatTree(); +} + + +void appl::widget::BasicTree::updateFlatTree() { m_flatTree.setRoot(m_tree, - [&](TreeElement* _value){ + [&](const TreeElement& _value){ return true; }, - [&](TreeElement* _value){ + [&](const TreeElement& _value){ return _value.m_isExpand; }); + markToRedraw(); } + appl::widget::BasicTree::~BasicTree() { } @@ -59,6 +76,10 @@ fluorine::Variant appl::widget::BasicTree::getData(int32_t _role, const ivec2& _ return "value: " + etk::toString(_pos); case ewol::widget::ListRole::DistanceToRoot: return uint_t(elem->countToRoot()); + case ewol::widget::ListRole::HaveChild: + return elem->haveChild(); + case ewol::widget::ListRole::IsExpand: + return value.m_isExpand; case ewol::widget::ListRole::Icon: if (elem->countToRoot() == 0) { return "{ewol}THEME:GUI:Home.svg"; @@ -73,88 +94,16 @@ fluorine::Variant appl::widget::BasicTree::getData(int32_t _role, const ivec2& _ case ewol::widget::ListRole::FgColor: return etk::Color<>(0,0,0,0xFF); case ewol::widget::ListRole::BgColor: + if ((_pos.y()%2) == 0) { + return etk::Color<>(0,0,0,0x15); + } return fluorine::Variant(); } return fluorine::Variant(); } -bool appl::widget::BasicTree::onItemEvent(int32_t _IdInput, - enum gale::key::status _typeEvent, - const ivec2& _pos, - const vec2& _mousePosition) { - /* - int32_t offset = 0; - if (*propertyShowFolder == true) { - if (*propertyPath == "/") { - offset = 1; - } else { - offset = 2; - } - } - if (_typeEvent == gale::key::status::pressSingle) { - EWOL_VERBOSE("Event on List : IdInput=" << _IdInput << " _pos=" << _pos ); - if (1 == _IdInput) { - int32_t previousRaw = m_selectedLine; - if (_pos.y() > (int32_t)m_list.size()+offset ) { - m_selectedLine = -1; - } else { - m_selectedLine = _pos.y(); - } - if (previousRaw != m_selectedLine) { - if( *propertyShowFolder == true - && m_selectedLine == 0) { - // "." folder - signalFolderSelect.emit("."); - } else if ( *propertyShowFolder == true - && m_selectedLine == 1) { - // ".." folder - signalFolderSelect.emit(".."); - } else if( m_selectedLine-offset >= 0 - && m_selectedLine-offset < (int32_t)m_list.size() - && null != m_list[m_selectedLine-offset] ) { - // generate event extern : - switch(m_list[m_selectedLine-offset]->getNodeType()) { - case etk::typeNode_file : - signalFileSelect.emit(m_list[m_selectedLine-offset]->getNameFile()); - break; - case etk::typeNode_folder : - signalFolderSelect.emit(m_list[m_selectedLine-offset]->getNameFile()); - break; - default: - EWOL_ERROR("Can not generate event on an unknow type"); - break; - } - } - } else { - if( *propertyShowFolder == true - && m_selectedLine == 0) { - // "." folder - signalFolderValidate.emit("."); - } else if ( *propertyShowFolder == true - && m_selectedLine == 1) { - // ".." folder - signalFolderValidate.emit(".."); - } else if( m_selectedLine-offset >= 0 - && m_selectedLine-offset < (int32_t)m_list.size() - && null != m_list[m_selectedLine-offset] ) { - switch(m_list[m_selectedLine-offset]->getNodeType()) { - case etk::typeNode_file : - signalFileValidate.emit(m_list[m_selectedLine-offset]->getNameFile()); - break; - case etk::typeNode_folder : - signalFolderValidate.emit(m_list[m_selectedLine-offset]->getNameFile()); - break; - default: - EWOL_ERROR("Can not generate event on an unknow type"); - break; - } - } - } - // need to regenerate the display of the list : - markToRedraw(); - return true; - } - } - */ - return false; +void appl::widget::BasicTree::onItemExpandEvent(const ivec2& _pos) { + TEST_WARNING("Event on expand on " << _pos); + m_flatTree[_pos.y()]->getData().m_isExpand = m_flatTree[_pos.y()]->getData().m_isExpand?false:true; + updateFlatTree(); } diff --git a/sample/treeView/appl/widget/BasicTree.hpp b/sample/treeView/appl/widget/BasicTree.hpp index 302e43c3..93cff718 100644 --- a/sample/treeView/appl/widget/BasicTree.hpp +++ b/sample/treeView/appl/widget/BasicTree.hpp @@ -18,7 +18,7 @@ namespace appl { using BasicTreeWeak = ememory::WeakPtr; class TreeElement { public: - TreeElement(const etk::String& _display="", bool _isSelected = false, bool m_isExpand=false): + TreeElement(const etk::String& _display="", bool _isSelected = false, bool _isExpand=false): m_display(_display), m_isSelected(_isSelected), m_isExpand(_isExpand) { @@ -27,23 +27,25 @@ namespace appl { etk::String m_display; bool m_isSelected = false; bool m_isExpand = false; - } + }; /** * @brief Generic display folder class. This widget display the content of a single folder : */ class BasicTree : public ewol::widget::TreeView { protected: BasicTree(); + void init() override; public: DECLARE_WIDGET_FACTORY(BasicTree, "BasicTree"); virtual ~BasicTree(); protected: + void updateFlatTree(); etk::Color<> getBasicBG() override; ivec2 getMatrixSize() const override; fluorine::Variant getData(int32_t _role, const ivec2& _pos) override; - bool onItemEvent(int32_t _IdInput, enum gale::key::status _typeEvent, const ivec2& _pos, const vec2& _mousePosition) override; - - ememory::SharedPtr> m_tree; + //bool onItemEvent(const ewol::event::Input& _event, const ivec2& _pos, const vec2& _mousePosition) override; + void onItemExpandEvent(const ivec2& _pos) override; + ememory::SharedPtr> m_tree; etk::FlatTree m_flatTree; }; }; diff --git a/sample/treeView/lutin_ewol-sample-treeview.py b/sample/treeView/lutin_ewol-sample-treeview.py index 25ad7458..95902011 100644 --- a/sample/treeView/lutin_ewol-sample-treeview.py +++ b/sample/treeView/lutin_ewol-sample-treeview.py @@ -34,7 +34,8 @@ def configure(target, my_module): 'appl/widget/BasicTree.cpp', ]) my_module.add_depend([ - 'ewol' + 'ewol', + 'test-debug', ]) my_module.add_flag('c++', [ "-DPROJECT_NAME=\"\\\""+my_module.get_name()+"\\\"\"",