static void ProcFileModRef( FILE *fp ) /************************************/ { byte hdr[ 3 ]; unsigned_16 page_len; unsigned_32 offset; char *module_name; page_len = 0; RecBuff = NULL; RecMaxLen = 0; module_name = NULL; for(;;) { offset = ftell( fp ); if( fread( hdr, 1, 3, fp ) != 3 ) break; RecLen = hdr[ 1 ] | ( hdr[ 2 ] << 8 ); ResizeBuff( RecLen ); RecPtr = RecBuff; if( fread( RecBuff, RecLen, 1, fp ) == 0 ) break; RecLen--; isMS386 = hdr[ 0 ] & 1; switch( hdr[ 0 ] & ~1 ) { case CMD_THEADR: if( module_name != NULL ) free( module_name ); GetName(); *RecPtr = 0; module_name = malloc( strlen( (char *)NamePtr ) + 1 ); strcpy( module_name, (char *)NamePtr ); break; case CMD_MODEND: if( module_name != NULL ) free( module_name ); module_name = NULL; if( page_len != 0 ) { offset = ftell( fp ); offset = page_len - offset % page_len; if( offset != page_len ) { fseek( fp, offset, SEEK_CUR ); } } break; case CMD_PUBDEF: if( ( GetIndex() | GetIndex() ) == 0 ) GetUInt(); while( ! EndRec() ) { GetName(); *RecPtr = 0; if( SymbolExists( pubdef_tab, (char *)NamePtr ) != 0 ) { if( SymbolExists( extdef_tab, module_name ) == 0 ) { AddSymbol( extdef_tab, module_name, NULL ); printf( "%s\n", module_name ); } } GetOffset(); GetIndex(); } break; case LIB_HEADER_REC: if( isMS386 ) { fseek( fp, 0L, SEEK_END ); page_len = 0; } else { page_len = RecLen + 4; } break; default: break; } } free( RecBuff ); }
bool CGUIPanelContainer::OnAction(const CAction &action) { switch (action.GetID()) { case ACTION_PAGE_UP: { if (GetOffset() == 0) { // already on the first page, so move to the first item SetCursor(0); } else { // scroll up to the previous page Scroll( -m_itemsPerPage); } return true; } break; case ACTION_PAGE_DOWN: { if ((GetOffset() + m_itemsPerPage) * m_itemsPerRow >= (int)m_items.size() || (int)m_items.size() < m_itemsPerPage) { // already at the last page, so move to the last item. SetCursor(m_items.size() - GetOffset() * m_itemsPerRow - 1); } else { // scroll down to the next page Scroll(m_itemsPerPage); } return true; } break; // smooth scrolling (for analog controls) case ACTION_SCROLL_UP: { m_analogScrollCount += action.GetAmount() * action.GetAmount(); bool handled = false; while (m_analogScrollCount > AnalogScrollSpeed()) { handled = true; m_analogScrollCount -= AnalogScrollSpeed(); if (GetOffset() > 0)// && GetCursor() <= m_itemsPerPage * m_itemsPerRow / 2) { Scroll(-1); } else if (GetCursor() > 0) { SetCursor(GetCursor() - 1); } } return handled; } break; case ACTION_SCROLL_DOWN: { m_analogScrollCount += action.GetAmount() * action.GetAmount(); bool handled = false; while (m_analogScrollCount > AnalogScrollSpeed()) { handled = true; m_analogScrollCount -= AnalogScrollSpeed(); if ((GetOffset() + m_itemsPerPage) * m_itemsPerRow < (int)m_items.size())// && GetCursor() >= m_itemsPerPage * m_itemsPerRow / 2) { Scroll(1); } else if (GetCursor() < m_itemsPerPage * m_itemsPerRow - 1 && GetOffset() * m_itemsPerRow + GetCursor() < (int)m_items.size() - 1) { SetCursor(GetCursor() + 1); } } return handled; } break; } return CGUIBaseContainer::OnAction(action); }
int CGUIBaseContainer::GetSelectedItem() const { return CorrectOffset(GetOffset(), GetCursor()); }
void CGUIBaseContainer::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) { // update our auto-scrolling as necessary UpdateAutoScrolling(currentTime); ValidateOffset(); if (m_bInvalidated) UpdateLayout(); if (!m_layout || !m_focusedLayout) return; UpdateScrollOffset(currentTime); int offset = (int)floorf(m_scroller.GetValue() / m_layout->Size(m_orientation)); int cacheBefore, cacheAfter; GetCacheOffsets(cacheBefore, cacheAfter); // Free memory not used on screen if ((int)m_items.size() > m_itemsPerPage + cacheBefore + cacheAfter) FreeMemory(CorrectOffset(offset - cacheBefore, 0), CorrectOffset(offset + m_itemsPerPage + 1 + cacheAfter, 0)); CPoint origin = CPoint(m_posX, m_posY) + m_renderOffset; float pos = (m_orientation == VERTICAL) ? origin.y : origin.x; float end = (m_orientation == VERTICAL) ? m_posY + m_height : m_posX + m_width; // we offset our draw position to take into account scrolling and whether or not our focused // item is offscreen "above" the list. float drawOffset = (offset - cacheBefore) * m_layout->Size(m_orientation) - m_scroller.GetValue(); if (GetOffset() + GetCursor() < offset) drawOffset += m_focusedLayout->Size(m_orientation) - m_layout->Size(m_orientation); pos += drawOffset; end += cacheAfter * m_layout->Size(m_orientation); int current = offset - cacheBefore; while (pos < end && m_items.size()) { int itemNo = CorrectOffset(current, 0); if (itemNo >= (int)m_items.size()) break; bool focused = (current == GetOffset() + GetCursor()); if (itemNo >= 0) { CGUIListItemPtr item = m_items[itemNo]; // render our item if (m_orientation == VERTICAL) ProcessItem(origin.x, pos, item, focused, currentTime, dirtyregions); else ProcessItem(pos, origin.y, item, focused, currentTime, dirtyregions); } // increment our position pos += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation); current++; } // when we are scrolling up, offset will become lower (integer division, see offset calc) // to have same behaviour when scrolling down, we need to set page control to offset+1 UpdatePageControl(offset + (m_scroller.IsScrollingDown() ? 1 : 0)); m_lastRenderTime = currentTime; CGUIControl::Process(currentTime, dirtyregions); }
bool CGUIBaseContainer::OnMessage(CGUIMessage& message) { if (message.GetControlId() == GetID() ) { if (!m_listProvider) { if (message.GetMessage() == GUI_MSG_LABEL_BIND && message.GetPointer()) { // bind our items Reset(); CFileItemList *items = (CFileItemList *)message.GetPointer(); for (int i = 0; i < items->Size(); i++) m_items.push_back(items->Get(i)); UpdateLayout(true); // true to refresh all items UpdateScrollByLetter(); SelectItem(message.GetParam1()); return true; } else if (message.GetMessage() == GUI_MSG_LABEL_RESET) { Reset(); SetPageControlRange(); return true; } } if (message.GetMessage() == GUI_MSG_ITEM_SELECT) { SelectItem(message.GetParam1()); return true; } else if (message.GetMessage() == GUI_MSG_SETFOCUS) { if (message.GetParam1()) // subfocus item is specified, so set the offset appropriately { int offset = GetOffset(); if (message.GetParam2() && message.GetParam2() == 1) offset = 0; int item = std::min(offset + (int)message.GetParam1() - 1, (int)m_items.size() - 1); SelectItem(item); } } else if (message.GetMessage() == GUI_MSG_ITEM_SELECTED) { message.SetParam1(GetSelectedItem()); return true; } else if (message.GetMessage() == GUI_MSG_PAGE_CHANGE) { if (message.GetSenderId() == m_pageControl && IsVisible()) { // update our page if we're visible - not much point otherwise if ((int)message.GetParam1() != GetOffset()) m_pageChangeTimer.StartZero(); ScrollToOffset(message.GetParam1()); return true; } } else if (message.GetMessage() == GUI_MSG_REFRESH_LIST) { // update our list contents for (unsigned int i = 0; i < m_items.size(); ++i) m_items[i]->SetInvalid(); } else if (message.GetMessage() == GUI_MSG_MOVE_OFFSET) { int count = (int)message.GetParam1(); while (count < 0) { MoveUp(true); count++; } while (count > 0) { MoveDown(true); count--; } return true; } } return CGUIControl::OnMessage(message); }
// scrolls the said amount void CGUIBaseContainer::Scroll(int amount) { ResetAutoScrolling(); ScrollToOffset(GetOffset() + amount); }
void CGUIBaseContainer::Render() { if (!m_layout || !m_focusedLayout) return; int offset = (int)floorf(m_scroller.GetValue() / m_layout->Size(m_orientation)); int cacheBefore, cacheAfter; GetCacheOffsets(cacheBefore, cacheAfter); if (g_graphicsContext.SetClipRegion(m_posX, m_posY, m_width, m_height)) { CPoint origin = CPoint(m_posX, m_posY) + m_renderOffset; float pos = (m_orientation == VERTICAL) ? origin.y : origin.x; float end = (m_orientation == VERTICAL) ? m_posY + m_height : m_posX + m_width; // we offset our draw position to take into account scrolling and whether or not our focused // item is offscreen "above" the list. float drawOffset = (offset - cacheBefore) * m_layout->Size(m_orientation) - m_scroller.GetValue(); if (GetOffset() + GetCursor() < offset) drawOffset += m_focusedLayout->Size(m_orientation) - m_layout->Size(m_orientation); pos += drawOffset; end += cacheAfter * m_layout->Size(m_orientation); float focusedPos = 0; CGUIListItemPtr focusedItem; int current = offset - cacheBefore; while (pos < end && m_items.size()) { int itemNo = CorrectOffset(current, 0); if (itemNo >= (int)m_items.size()) break; bool focused = (current == GetOffset() + GetCursor()); if (itemNo >= 0) { CGUIListItemPtr item = m_items[itemNo]; // render our item if (focused) { focusedPos = pos; focusedItem = item; } else { if (m_orientation == VERTICAL) RenderItem(origin.x, pos, item.get(), false); else RenderItem(pos, origin.y, item.get(), false); } } // increment our position pos += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation); current++; } // render focused item last so it can overlap other items if (focusedItem) { if (m_orientation == VERTICAL) RenderItem(origin.x, focusedPos, focusedItem.get(), true); else RenderItem(focusedPos, origin.y, focusedItem.get(), true); } g_graphicsContext.RestoreClipRegion(); } CGUIControl::Render(); }
int CGUIBaseContainer::GetCurrentPage() const { if (GetOffset() + m_itemsPerPage >= (int)GetRows()) // last page return (GetRows() + m_itemsPerPage - 1) / m_itemsPerPage; return GetOffset() / m_itemsPerPage + 1; }
void SystemDraw::Push() { Point p = GetOffset(); offset.Add(p); BufferPainter::BeginOp(); }
bool CGUIListContainer::HasPreviousPage() const { return (GetOffset() > 0); }
bool CGUIListContainer::HasNextPage() const { return (GetOffset() != (int)m_items.size() - m_itemsPerPage && (int)m_items.size() >= m_itemsPerPage); }