X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/d7d291938c45893e28715fb12ae5b83d334084e9..59efe28a00e5713ad5279ed976430da31292a129:/lib/service/listboxservice.cpp diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 881047df..f35c00a5 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -3,6 +3,7 @@ void eListboxServiceContent::setRoot(const eServiceReference &root) { + m_list.clear(); m_root = root; assert(m_service_center); @@ -16,6 +17,9 @@ void eListboxServiceContent::setRoot(const eServiceReference &root) m_size = m_list.size(); cursorHome(); + + if (m_listbox) + m_listbox->entryReset(); } void eListboxServiceContent::getCurrent(eServiceReference &ref) @@ -26,32 +30,143 @@ void eListboxServiceContent::getCurrent(eServiceReference &ref) ref = eServiceReference(); } +void eListboxServiceContent::initMarked() +{ + m_marked.clear(); +} + +void eListboxServiceContent::addMarked(const eServiceReference &ref) +{ + m_marked.insert(ref); + if (m_listbox) + m_listbox->entryChanged(lookupService(ref)); +} + +void eListboxServiceContent::removeMarked(const eServiceReference &ref) +{ + m_marked.erase(ref); + if (m_listbox) + m_listbox->entryChanged(lookupService(ref)); +} + +int eListboxServiceContent::isMarked(const eServiceReference &ref) +{ + return m_marked.find(ref) != m_marked.end(); +} + +void eListboxServiceContent::markedQueryStart() +{ + m_marked_iterator = m_marked.begin(); +} + +int eListboxServiceContent::markedQueryNext(eServiceReference &ref) +{ + if (m_marked_iterator == m_marked.end()) + return -1; + ref = *m_marked_iterator++; + return 0; +} + +int eListboxServiceContent::lookupService(const eServiceReference &ref) +{ + /* shortcut for cursor */ + if (ref == *m_cursor) + return m_cursor_number; + /* otherwise, search in the list.. */ + int index = 0; + for (list::const_iterator i(m_list.begin()); i != m_list.end(); ++i, ++index); + + /* this is ok even when the index was not found. */ + return index; +} + +void eListboxServiceContent::setVisualMode(int mode) +{ + m_visual_mode = mode; + + if (m_visual_mode == visModeSimple) + { + m_element_position[celServiceName] = eRect(ePoint(0, 0), m_itemsize); + m_element_font[celServiceName] = new gFont("Arial", 14); + m_element_position[celServiceNumber] = eRect(); + m_element_font[celServiceNumber] = 0; + m_element_position[celIcon] = eRect(); + m_element_position[celServiceInfo] = eRect(); + m_element_font[celServiceInfo] = 0; + } +} + +void eListboxServiceContent::setElementPosition(int element, eRect where) +{ + if ((element >= 0) && (element < celElements)) + m_element_position[element] = where; +} + +void eListboxServiceContent::setElementFont(int element, gFont *font) +{ + if ((element >= 0) && (element < celElements)) + m_element_font[element] = font; +} + +void eListboxServiceContent::sort() +{ + ePtr lst; + if (!m_service_center->list(m_root, lst)) + { + m_list.sort(iListableServiceCompare(lst)); + /* FIXME: is this really required or can we somehow keep the current entry? */ + cursorHome(); + if (m_listbox) + m_listbox->entryReset(); + } +} + DEFINE_REF(eListboxServiceContent); eListboxServiceContent::eListboxServiceContent() + :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_swap(m_list.end()) { - m_size = 0; cursorHome(); eServiceCenter::getInstance(m_service_center); } void eListboxServiceContent::cursorHome() { + list::iterator old = m_cursor; + m_cursor = m_list.begin(); m_cursor_number = 0; + + if ( m_current_marked && m_saved_cursor == m_list.end() ) + std::iter_swap( old, m_cursor ); } void eListboxServiceContent::cursorEnd() { + if ( m_current_marked && m_saved_cursor == m_list.end() && m_cursor != m_list.end() ) + m_swap = m_cursor; m_cursor = m_list.end(); m_cursor_number = m_size; } +int eListboxServiceContent::setCurrentMarked(bool state) +{ + bool prev = m_current_marked; + m_current_marked = state; + + if (state != prev && m_listbox) + m_listbox->entryChanged(m_cursor_number); + + return 0; +} + int eListboxServiceContent::cursorMove(int count) { + list::iterator old = m_cursor; + if (count > 0) { - while (count && (m_cursor != m_list.end())) + while(count && (m_cursor != m_list.end())) { ++m_cursor; ++m_cursor_number; @@ -66,7 +181,20 @@ int eListboxServiceContent::cursorMove(int count) ++count; } } - + + if ( m_current_marked && m_saved_cursor == m_list.end() ) + { + if ( m_cursor == m_list.end() ) + m_swap = old; + else if ( old == m_list.end() ) + { + std::iter_swap( m_swap, m_cursor ); + m_swap = m_list.end(); + } + else + std::iter_swap( old, m_cursor ); + } + return 0; } @@ -98,6 +226,7 @@ void eListboxServiceContent::cursorRestore() { m_cursor = m_saved_cursor; m_cursor_number = m_saved_cursor_number; + m_saved_cursor = m_list.end(); } int eListboxServiceContent::size() @@ -108,30 +237,64 @@ int eListboxServiceContent::size() void eListboxServiceContent::setSize(const eSize &size) { m_itemsize = size; + setVisualMode(m_visual_mode); } void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { - ePtr fnt = new gFont("Arial", 14); painter.clip(eRect(offset, m_itemsize)); - style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal); + + if (m_current_marked && selected) + style.setStyle(painter, eWindowStyle::styleListboxMarked); + else if (cursorValid() && isMarked(*m_cursor)) + style.setStyle(painter, eWindowStyle::styleListboxMarked); + else + style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal); painter.clear(); if (cursorValid()) { - painter.setFont(fnt); - - ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1)); - - /* get name of service */ + /* get service information */ ePtr service_info; m_service_center->info(*m_cursor, service_info); - std::string name = ""; - - if (service_info) - service_info->getName(*m_cursor, name); - painter.renderText(eRect(text_offset, m_itemsize), name); + for (int e = 0; e < celElements; ++e) + { + if (!m_element_font[e]) + continue; + painter.setFont(m_element_font[e]); + + std::string text = ""; + + switch (e) + { + case celServiceName: + { + if (service_info) + service_info->getName(*m_cursor, text); + break; + } + case celServiceNumber: + { + char bla[10]; + sprintf(bla, "%d", m_cursor_number + 1); + text = bla; + break; + } + case celServiceInfo: + { + text = "now&next"; + break; + } + case celIcon: + continue; + } + + eRect area = m_element_position[e]; + area.moveBy(offset.x(), offset.y()); + + painter.renderText(area, text); + } if (selected) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);