Reply to thread

For large lists it is convenient to use keyboard shortcuts to jump to an item in the list (like windows explorer).


To test this in media portal I added some code to the GUIListControl.cs and GUIThumbnailPanel.cs which handles all otherwise unhandled keys.

Maybe something like this can be added to the main code line? Well, here are the code snippets.


This is not much tested yet, but seems to work for 'My Music' and for me.


Thanks for MediaPortal,

Wog



GUIThumbnailPanell.cs[code]

        case Action.ActionType.ACTION_KEY_PRESSED :

        // <WOG>

        { 

            OnJump( action.m_key.KeyChar );

            m_bRefresh = true;

        }

        // </WOG>

        break;

[/code]

[code]

        // <WOG>

        /// <summary>

        /// Implementation of the OnJump action. If an (unhandled) key is pressed, the action tries to find

        /// an item which start with the same letter. If an item is found it changes selection to point to it.

        /// </summary>

        protected static DateTime tsLastKeyStroke = DateTime.Now; // time stamp last key pressed

        protected static double maxTimeSpan = 500.0;              // max time between two strokes

        protected static String sKey = "";                          // jump string


        protected void OnJump(int key)

        {

            if (m_iSelect != GUIListControl.ListType.CONTROL_LIST)

            {

                // don't do anything...

                return;

            }


            // convert to lower case string.

            // in case less than 0.5 seconds have been passed since the last keys troke, append the new character.

            DateTime tsThisKeyStroke = DateTime.Now;

            TimeSpan ts = tsThisKeyStroke - tsLastKeyStroke ;

            tsLastKeyStroke = tsThisKeyStroke;

            double ms = ts.TotalMilliseconds;

            char cKey = (char) key;

            if ( ms > maxTimeSpan )

            {

                sKey = "";

            }

            sKey += cKey.ToString().ToLower();


            // search the next item starting with this letter


            int startIndex =  m_iCursorY  * m_iColumns + m_iOffset + m_iCursorX;

            for ( int idx = 1; idx < (int)m_vecItems.Count; idx++ )

            {

                int index = (startIndex + idx) % (int)m_vecItems.Count;

                GUIListItem pItem = (GUIListItem)m_vecItems[index];

                String strLabel = pItem.Label.ToLower();

                if ( strLabel.StartsWith(sKey) )

                {

                    m_iCursorX = index % m_iColumns;

                    int iOffsetY = index / m_iColumns;


                    // selection in currently displayed area -> just change selection

                    if (m_iOffset / m_iColumns <= iOffsetY && m_iOffset / m_iColumns  + m_iRows > iOffsetY )

                    {

                        m_iCursorY = iOffsetY - m_iOffset / m_iColumns ;

                        // m_iOffset = m_iOffset; is unchanged...

                    }

                    else if ( iOffsetY < m_iRows )

                    {

                        // one of the first few items. start display with first line

                        m_iCursorY = iOffsetY;

                        m_iOffset = 0;

                    }

                    else if ( iOffsetY >  (m_vecItems.Count + m_iRows - 1) / m_iColumns  - m_iRows )

                    {

                        // one of the last few items.

                        int iOffRow = (m_vecItems.Count + m_iRows - 1) / m_iColumns  - m_iRows ;

                        m_iOffset = iOffRow * m_iColumns;

                        m_iCursorY = iOffsetY - iOffRow;

                    }

                    else

                    {

                        // center it

                        int iOffRow = iOffsetY - m_iRows / 2;

                        m_iOffset = iOffRow * m_iColumns;

                        m_iCursorY = iOffsetY - iOffRow;

                    }


                    OnSelectionChanged();

                    return;

                }

            }

        }

        // </WOG>[/code]



GUIListControl.cs[code]

        case Action.ActionType.ACTION_KEY_PRESSED :

        // <WOG>

        { 

            OnJump( action.m_key.KeyChar );

            m_bRefresh = true;

        }

        // </WOG>

        break;

[/code]

[code]

        // <WOG>

        /// <summary>

        /// Implementation of the OnJump action. If an overwise unhandled key is pressed, the action tries to find

        /// an item which start with the same letter. If an item is found it changes selection to point to it.

        /// </summary>

        protected static DateTime tsLastKeyStroke = DateTime.Now; // time stamp last key pressed

        protected static double maxTimeSpan = 500.0;              // max time between two strokes

        protected static String sKey = "";                          // jump string

       

        protected void OnJump(int key)

        {


            if (m_iSelect != ListType.CONTROL_LIST)

            {

                // don't do anything...

                return;

            }


            // convert to lower case string.

            // in case less than 0.5 seconds have been passed since the last keys troke, append the new character.

            DateTime tsThisKeyStroke = DateTime.Now;

            TimeSpan ts = tsThisKeyStroke - tsLastKeyStroke ;

            tsLastKeyStroke = tsThisKeyStroke;

            double ms = ts.TotalMilliseconds;

            char cKey = (char) key;

            if ( ms > maxTimeSpan )

            {

                sKey = "";

            }

            sKey += cKey.ToString().ToLower();

            // search the next item starting with this letter


            int startIndex = m_iOffset + m_iCursorY;

            for ( int idx = 1; idx < (int)m_vecItems.Count; idx++ )

            {

                int index = (startIndex + idx) % (int)m_vecItems.Count;

                GUIListItem pItem = (GUIListItem)m_vecItems[index];

                String strLabel = pItem.Label.ToLower();

                if ( strLabel.StartsWith(sKey) )

                {

                    // selection in currently displayed area -> just change selection

                    if (m_iCursorY + idx < m_iItemsPerPage)

                    {

                        m_iCursorY += idx;

                        OnSelectionChanged();

                        return;

                    }

   

                    // selection not visible. center displayed area aorund selected item

                    int iCursor = m_iItemsPerPage / 2;

                    int iOffset = index - iCursor;

                    if ( index < m_iItemsPerPage / 2 )

                    {

                        // one of the first few (m_iItemsPerPage / 2) items. start display with first

                        iCursor = index;

                        iOffset = 0;

                    }

                    else if ( index >  m_vecItems.Count - m_iItemsPerPage )

                    {

                        // one of the last few items.

                        iOffset = m_vecItems.Count - m_iItemsPerPage;

                        iCursor = index - iOffset;

                    }


                    m_iCursorY = iCursor;

                    m_iOffset = iOffset;

                    OnSelectionChanged();

                    return;

                }

            }

        }

        // </WOG>

[/code]


Top Bottom