All pastes #444281 Raw Edit

Stuff

public text v1 · immutable
·published 2007-04-17 09:17 UTC
rendered paste body
#include "../../../stdafx.h"
#include "GUIPythonWindowXML.h"
#include "guiwindow.h"
#include "pyutil.h"
#include "..\..\..\application.h"
#include "..\..\..\GUIMediaWindow.h"
#include "window.h"
#include "control.h"
#include "action.h"

#define CONTROL_BTNVIEWASICONS  2
#define CONTROL_BTNSORTBY       3
#define CONTROL_BTNSORTASC      4
#define CONTROL_LIST            50
#define CONTROL_LABELFILES      12

#define CONTROL_VIEW_START      50
#define CONTROL_VIEW_END        59


using namespace PYXBMC;

CGUIPythonWindowXML::CGUIPythonWindowXML(DWORD dwId, CStdString strXML, CStdString strFallBackPath)
: CGUIWindow(dwId,strXML)
{
  pCallbackWindow = NULL;
  m_actionEvent = CreateEvent(NULL, true, false, NULL);
  m_loadOnDemand = false;
  m_guiState.reset(CGUIViewState::GetViewState(GetID(), m_vecItems));
  m_coordsRes  = PAL_4x3;
  m_fallbackPath = strFallBackPath;
}

CGUIPythonWindowXML::~CGUIPythonWindowXML(void)
{
    CloseHandle(m_actionEvent);
}
void CGUIPythonWindowXML::Update()
{
}
bool CGUIPythonWindowXML::OnAction(const CAction &action)
{
  // do the base class window first, and the call to python after this
  bool ret = CGUIWindow::OnAction(action);
  if(pCallbackWindow)
  {
    PyXBMCAction* inf = new PyXBMCAction;
    inf->pObject = Action_FromAction(action);
    inf->pCallbackWindow = pCallbackWindow;

    // aquire lock?
    Py_AddPendingCall(Py_XBMC_Event_OnAction, inf);
    PulseActionEvent();
  }
  return ret;
}

void CGUIPythonWindowXML::OnWindowLoaded()
{
  CGUIWindow::OnWindowLoaded();
  m_viewControl.Reset();
  m_viewControl.SetParentWindow(GetID());
  for (int i = CONTROL_VIEW_START; i <= CONTROL_VIEW_END; i++)
  {
    m_viewControl.AddView(GetControl(i));
  }
  m_viewControl.SetViewControlID(CONTROL_BTNVIEWASICONS);
  UpdateButtons();
}

bool CGUIPythonWindowXML::OnMessage(CGUIMessage& message)
{
  switch (message.GetMessage())
  {
    case GUI_MSG_WINDOW_DEINIT:
    {
      m_gWindowManager.ShowOverlay(OVERLAY_STATE_SHOWN);
    }
    break;

    case GUI_MSG_WINDOW_INIT:
    {
      CGUIWindow::OnMessage(message);
      m_gWindowManager.ShowOverlay(OVERLAY_STATE_HIDDEN);
      PyXBMCAction* inf = new PyXBMCAction;
      inf->pObject = NULL;
      // create a new call and set it in the python queue
      inf->pCallbackWindow = pCallbackWindow;
      Py_AddPendingCall(Py_XBMC_Event_OnInit, inf);
      return true;
    }
    break;

    case GUI_MSG_SETFOCUS:
    {
      if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId())
      {
        m_viewControl.SetFocused();
        return true;
      }
        // check if our focused control is one of our category buttons
        int iControl=message.GetControlId();
        if(pCallbackWindow)
        {
          PyXBMCAction* inf = new PyXBMCAction;
          inf->pObject = NULL;
          // create a new call and set it in the python queue
          inf->pCallbackWindow = pCallbackWindow;
          inf->controlId = iControl;
          // aquire lock?
          Py_AddPendingCall(Py_XBMC_Event_OnFocus, inf);
          PulseActionEvent();
        }
    }
    break;

    case GUI_MSG_CLICKED:
    {
      int iControl=message.GetSenderId();
      // Handle Sort/View internally. Scripters shouldn't use ID 2, 3 or 4.

      if (iControl == CONTROL_BTNVIEWASICONS)
      {
        if (m_guiState.get())
        {
          m_guiState->SaveViewAsControl(m_viewControl.GetNextViewMode());
        }
        UpdateButtons();
        return true;
      }
      else if (iControl == CONTROL_BTNSORTASC) // sort asc
      {
        CLog::Log(LOGINFO,"WindowXML: Internal asc/dsc button not implemented");
        /*if (m_guiState.get())
          m_guiState->SetNextSortOrder();
        UpdateFileList();*/
        return true;
      }
      else if (iControl == CONTROL_BTNSORTBY) // sort by
      {
        CLog::Log(LOGINFO,"WindowXML: Internal sort button not implemented");
        /*if (m_guiState.get())
          m_guiState->SetNextSortMethod();
        UpdateFileList();*/
        return true;
      }

      if(pCallbackWindow && iControl && iControl != this->GetID()) // pCallbackWindow &&  != this->GetID())
      {
        CGUIControl* controlClicked = (CGUIControl*)this->GetControl(iControl);
        
        // The old python way used to check list AND SELECITEM method or  if its a button, checkmark.
        // Its done this way for now to allow other controls without a python version like togglebutton to still raise a onAction event
        if (controlClicked)	// Will get problems if we the id is not on the window and we try to do GetControlType on it. So check to make sure it exists
        {
          if (controlClicked->GetControlType() == CGUIControl::GUICONTAINER_LIST &&  message.GetParam1() == ACTION_SELECT_ITEM  || controlClicked->GetControlType() != CGUIControl::GUICONTAINER_LIST)
          {
            PyXBMCAction* inf = new PyXBMCAction;
            inf->pObject = NULL;
            // create a new call and set it in the python queue
            inf->pCallbackWindow = pCallbackWindow;
            inf->controlId = iControl;
            // aquire lock?
            Py_AddPendingCall(Py_XBMC_Event_OnClick, inf);
            PulseActionEvent();
          }
        }
      }
    }
    break;
  }

  return CGUIWindow::OnMessage(message);
}

void CGUIPythonWindowXML::AddItem(CFileItem * fileItem,int intPosition)
{
  if (intPosition == 0)	m_vecItems.AddFront(fileItem);
  else if (intPosition == -1)m_vecItems.Add(fileItem);
  else
  {
	  if (intPosition > m_vecItems.Size())return;
	  CFileItemList*orgVecItems = new CFileItemList(m_vecItems);
	  m_vecItems.Clear();
	  for (int i = 0; i <  orgVecItems->Size(); ++i)
		  if (i == intPosition){
			  m_vecItems.Add(fileItem);}
		  m_vecItems.Add(&orgVecItems[i]);
  }		
  m_viewControl.SetItems(m_vecItems);
  UpdateButtons();
}

void CGUIPythonWindowXML::RemoveItem(int itemPosition)
{
  m_vecItems.Remove(itemPosition);
  m_viewControl.SetItems(m_vecItems);
  UpdateButtons();
}


int CGUIPythonWindowXML::GetCurrentListPosition()
{
  return m_viewControl.GetSelectedItem();
}

void CGUIPythonWindowXML::SetCurrentListPosition(int item)
{
  return m_viewControl.SetSelectedItem(item);
}

CFileItem * CGUIPythonWindowXML::GetListItem(int position)
{ 
  CFileItem * selectedItem = new CFileItem("Item Index doesn't exist");
  if (position < m_vecItems.Size())
  {
    selectedItem = m_vecItems[position];
  } 
  return selectedItem;
}

void CGUIPythonWindowXML::RefreshList()
{
  m_viewControl.SetItems(m_vecItems);
  UpdateButtons();
}

void CGUIPythonWindowXML::ClearList()
{
  m_viewControl.Clear();
  m_vecItems.Clear();
  m_viewControl.SetItems(m_vecItems);
  UpdateButtons();
}

void CGUIPythonWindowXML::WaitForActionEvent(DWORD timeout)
{
  WaitForSingleObject(m_actionEvent, timeout);
  ResetEvent(m_actionEvent);
}

void CGUIPythonWindowXML::PulseActionEvent()
{
  SetEvent(m_actionEvent);
}
void CGUIPythonWindowXML::Render()
{
  string backupMediaDir = g_graphicsContext.GetMediaDir();
  g_graphicsContext.SetMediaDir(m_fallbackPath+"\\skins");
  CGUIWindow::Render();
  g_graphicsContext.SetMediaDir(backupMediaDir);
}

int Py_XBMC_Event_OnClick(void* arg)
{
  if (arg != NULL)
  {
    PyXBMCAction* action = (PyXBMCAction*)arg;
    PyObject_CallMethod(action->pCallbackWindow, "onClick", "i", action->controlId);
    delete action;
  }
  return 0;
}

int Py_XBMC_Event_OnFocus(void* arg)
{
  if (arg != NULL)
  {
    PyXBMCAction* action = (PyXBMCAction*)arg;
    PyObject_CallMethod(action->pCallbackWindow, "onFocus", "i", action->controlId);
    delete action;
  }
  return 0;
}

int Py_XBMC_Event_OnInit(void* arg)
{
  if (arg != NULL)
  {
    PyXBMCAction* action = (PyXBMCAction*)arg;
    PyObject_CallMethod(action->pCallbackWindow, "onInit",""); //, "O", &self);
    delete action;
  }
  return 0;
}

/// Functions Below here are speceifc for the 'MediaWindow' Like stuff (such as Sort and View)

// \brief Prepares and adds the fileitems list/thumb panel
void CGUIPythonWindowXML::OnSort()
{
  FormatItemLabels();
  SortItems(m_vecItems);
}

// \brief Formats item labels based on the formatting provided by guiViewState
void CGUIPythonWindowXML::FormatItemLabels()
{
  if (!m_guiState.get())
    return;

  CGUIViewState::LABEL_MASKS labelMasks;
  m_guiState->GetSortMethodLabelMasks(labelMasks);
}
// \brief Sorts Fileitems based on the sort method and sort oder provided by guiViewState
void CGUIPythonWindowXML::SortItems(CFileItemList &items)
{
  auto_ptr<CGUIViewState> guiState(CGUIViewState::GetViewState(GetID(), items));

  if (guiState.get())
  {
    items.Sort(guiState->GetSortMethod(), guiState->GetDisplaySortOrder());

    // Should these items be saved to the hdd
    if (items.GetCacheToDisc())
      items.Save();
  }
}
// \brief Synchonize the fileitems with the playlistplayer
// It recreated the playlist of the playlistplayer based
// on the fileitems of the window
void CGUIPythonWindowXML::UpdateFileList()
{
  int nItem = m_viewControl.GetSelectedItem();
  CFileItem* pItem = m_vecItems[nItem];
  const CStdString& strSelected = pItem->m_strPath;

  OnSort();
  UpdateButtons();

  m_viewControl.SetItems(m_vecItems);
  m_viewControl.SetSelectedItem(strSelected);
}

// \brief Updates the states (enable, disable, visible...)
// of the controls defined by this window
// Override this function in a derived class to add new controls
void CGUIPythonWindowXML::UpdateButtons()
{
  if (m_guiState.get())
  {
    // Update sorting controls
    if (m_guiState->GetDisplaySortOrder()==SORT_ORDER_NONE)
    {
      CONTROL_DISABLE(CONTROL_BTNSORTASC);
    }
    else
    {
      CONTROL_ENABLE(CONTROL_BTNSORTASC);
      if (m_guiState->GetDisplaySortOrder()==SORT_ORDER_ASC)
      {
        CGUIMessage msg(GUI_MSG_DESELECTED, GetID(), CONTROL_BTNSORTASC);
        g_graphicsContext.SendMessage(msg);
      }
      else
      {
        CGUIMessage msg(GUI_MSG_SELECTED, GetID(), CONTROL_BTNSORTASC);
        g_graphicsContext.SendMessage(msg);
      }
    }

    // Update list/thumb control
    m_viewControl.SetCurrentView(m_guiState->GetViewAsControl());

    // Update sort by button
    if (m_guiState->GetSortMethod()==SORT_METHOD_NONE)
    {
      CONTROL_DISABLE(CONTROL_BTNSORTBY);
    }
    else
    {
      CONTROL_ENABLE(CONTROL_BTNSORTBY);
    }
    CStdString sortLabel;
    sortLabel.Format(g_localizeStrings.Get(550).c_str(), g_localizeStrings.Get(m_guiState->GetSortMethodLabel()).c_str());
    SET_CONTROL_LABEL(CONTROL_BTNSORTBY, sortLabel);
  }

  int iItems = m_vecItems.Size();
  if (iItems)
  {
    CFileItem* pItem = m_vecItems[0];
    if (pItem->IsParentFolder()) iItems--;
  }
  CStdString items;
  items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
  SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
}

void CGUIPythonWindowXML::OnInitWindow()
{
  // Update list/thumb control
  m_viewControl.SetCurrentView(DEFAULT_VIEW_LIST);
  m_viewControl.SetFocused();
  SET_CONTROL_VISIBLE(CONTROL_LIST);
  CGUIWindow::OnInitWindow();
}

CGUIControl *CGUIPythonWindowXML::GetFirstFocusableControl(int id)
{
  if (m_viewControl.HasControl(id))
    id = m_viewControl.GetCurrentControl();
  return CGUIWindow::GetFirstFocusableControl(id);
}