diff --git a/checkin_notes b/checkin_notes index 72de5f583b..bc27870071 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6053,3 +6053,23 @@ David 27 June 2009 db/ schema.sql + +Rom 29 June 2009 + - MGR: My first attempt to handle the project list control was turning + into a mess and becoming very complicated, as my former mentor used + to say "if you are having to try too hard, you are doing it wrong." + + Reimplement the project list control as a wxHtmlListBox which handles + keyboard navigation correctly and allows us to have variable height + list items. Another perk is the ability to detect when different + HTML elements are clicked on which might be useful for anonymous + attach at some point in time in the future. + + clientgui/ + AccountManagerInfoPage.cpp + AdvancedFrame.cpp + BOINCGUIApp.cpp + BOINCWizards.h + ProjectInfoPage.cpp + ProjectListCtrl.cpp, .h + stdwx.h diff --git a/clientgui/AccountManagerInfoPage.cpp b/clientgui/AccountManagerInfoPage.cpp index 0f6607f706..1d10d0e56c 100644 --- a/clientgui/AccountManagerInfoPage.cpp +++ b/clientgui/AccountManagerInfoPage.cpp @@ -263,8 +263,9 @@ void CAccountManagerInfoPage::OnPageChanged( wxWizardExEvent& event ) { ); m_pProjectListCtrl->Append( - wxString(pl.account_managers[i]->name.c_str(), wxConvUTF8), wxString(pl.account_managers[i]->url.c_str(), wxConvUTF8), + wxString(pl.account_managers[i]->name.c_str(), wxConvUTF8), + wxString(pl.account_managers[i]->description.c_str(), wxConvUTF8), true ); } diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 3f911a4281..3ed43fae0c 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -54,18 +54,12 @@ #include "BOINCWizards.h" #include "BOINCBaseWizard.h" #include "WizardAttachProject.h" -//#include "WizardAccountManager.h" #include "DlgAdvPreferences.h" #include "res/connect.xpm" #include "res/disconnect.xpm" -// Which of the view sets should we display. -// -//#define VIEW_LIST 2 - - enum STATUSBARFIELDS { STATUS_TEXT, STATUS_CONNECTION_STATUS diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index 712ae8adb3..597fecb44a 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -312,6 +312,7 @@ bool CBOINCGUIApp::OnInit() { wxInitAllImageHandlers(); // Enable additional file system type handlers + wxFileSystem::AddHandler(new wxMemoryFSHandler); #if wxUSE_FS_INET && wxUSE_STREAMS && wxUSE_SOCKETS wxFileSystem::AddHandler(new wxInternetFSHandler); #endif diff --git a/clientgui/BOINCWizards.h b/clientgui/BOINCWizards.h index 51b9ce9b19..fc03218070 100644 --- a/clientgui/BOINCWizards.h +++ b/clientgui/BOINCWizards.h @@ -71,10 +71,9 @@ #define ID_WELCOMECHANGEAPPS 11102 // Project Info/Account Manager Info Controls -#define ID_PROJECTSELECTIONCTRL 11200 +#define ID_PROJECTLISTCTRL 11200 #define ID_PROJECTURLSTATICCTRL 11201 -#define ID_PROJECTURLDESCRIPTIONSTATICCTRL 11202 -#define ID_PROJECTURLCTRL 11203 +#define ID_PROJECTURLCTRL 11202 // Terms Of Use Controls #define ID_TERMSOFUSECTRL 11300 diff --git a/clientgui/ProjectInfoPage.cpp b/clientgui/ProjectInfoPage.cpp index b35429851f..6e7e26e424 100644 --- a/clientgui/ProjectInfoPage.cpp +++ b/clientgui/ProjectInfoPage.cpp @@ -286,11 +286,19 @@ void CProjectInfoPage::OnPageChanged( wxWizardExEvent& event ) { ); m_pProjectListCtrl->Append( - wxString(pl.projects[i]->name.c_str(), wxConvUTF8), wxString(pl.projects[i]->url.c_str(), wxConvUTF8), + wxString(pl.projects[i]->name.c_str(), wxConvUTF8), + wxString(pl.projects[i]->description.c_str(), wxConvUTF8), bSupportedPlatformFound ); } + + // Pre select the first element + m_pProjectListCtrl->SetSelection(0); + m_strProjectURL = m_pProjectListCtrl->GetItem(0)->GetURL(); + m_bProjectSupported = m_pProjectListCtrl->GetItem(0)->IsPlatformSupported(); + TransferDataToWindow(); + m_bProjectListPopulated = true; } diff --git a/clientgui/ProjectListCtrl.cpp b/clientgui/ProjectListCtrl.cpp index 1de039d636..68b5e5edd2 100644 --- a/clientgui/ProjectListCtrl.cpp +++ b/clientgui/ProjectListCtrl.cpp @@ -21,6 +21,7 @@ #include "stdwx.h" #include "BOINCGUIApp.h" +#include "BOINCWizards.h" #include "ProjectListCtrl.h" ////@begin XPM images @@ -28,30 +29,325 @@ ////@end XPM images +#ifdef wxUSE_ACCESSIBILITY + +// Gets the name of the specified object. +wxAccStatus CProjectListCtrlAccessible::GetName(int childId, wxString* name) +{ + if (childId == wxACC_SELF) + { + *name = wxT("Project List"); + } + else + { + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl) + { + *name = pCtrl->GetItem(childId - 1)->GetTitle().c_str(); + } + } + return wxACC_OK; +} + + +// Can return either a child object, or an integer +// representing the child element, starting from 1. +wxAccStatus CProjectListCtrlAccessible::HitTest(const wxPoint& pt, int* childId, wxAccessible** /*childObject*/) +{ + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl) + { + *childId = pCtrl->HitTest(pt); + return wxACC_OK; + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Returns the rectangle for this object (id = 0) or a child element (id > 0). +wxAccStatus CProjectListCtrlAccessible::GetLocation(wxRect& rect, int elementId) +{ + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl && (0 != elementId)) + { + wxSize cCtrlSize = pCtrl->GetClientSize(); + int iItemWidth = cCtrlSize.GetWidth(); + int iItemHeight = pCtrl->GetTotalClientHeight() / (int)pCtrl->GetItemCount(); + + // Set the initial control postition to the absolute coords of the upper + // left hand position of the control + rect.SetPosition(pCtrl->GetScreenPosition()); + rect.width = iItemWidth - 1; + rect.height = iItemHeight - 1; + + if (1 == elementId) + { + // First child + } + else + { + // Other children + rect.SetTop(rect.GetTop() + ((elementId - 1) * iItemHeight) + 1); + rect.height -= 1; + } + return wxACC_OK; + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Navigates from fromId to toId/toObject. +wxAccStatus CProjectListCtrlAccessible::Navigate( + wxNavDir navDir, int fromId, int* toId, wxAccessible** toObject +) { + + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + *toObject = NULL; + + if (0 != fromId) + { + switch (navDir) + { + case wxNAVDIR_PREVIOUS: + case wxNAVDIR_UP: + if (1 == fromId) + { + return wxACC_FALSE; + } + else + { + *toId = fromId - 1; + return wxACC_OK; + } + break; + case wxNAVDIR_NEXT: + case wxNAVDIR_DOWN: + if ((int)pCtrl->GetItemCount() == fromId) + { + return wxACC_FALSE; + } + else + { + *toId = fromId + 1; + return wxACC_OK; + } + return wxACC_FALSE; + break; + case wxNAVDIR_LEFT: + return wxACC_FALSE; + break; + case wxNAVDIR_RIGHT: + return wxACC_FALSE; + break; + case wxNAVDIR_FIRSTCHILD: + if (1 == fromId) + { + return wxACC_FALSE; + } + else + { + *toId = 1; + return wxACC_OK; + } + break; + case wxNAVDIR_LASTCHILD: + if ((int)pCtrl->GetItemCount() == fromId) + { + return wxACC_FALSE; + } + else + { + *toId = (int)pCtrl->GetItemCount(); + return wxACC_OK; + } + break; + } + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Gets the number of children. +wxAccStatus CProjectListCtrlAccessible::GetChildCount(int* childCount) +{ + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl) + { + *childCount = (int)pCtrl->GetItemCount(); + return wxACC_OK; + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Performs the default action. childId is 0 (the action for this object) +// or > 0 (the action for a child). +// Return wxACC_NOT_SUPPORTED if there is no default action for this +// window (e.g. an edit control). +wxAccStatus CProjectListCtrlAccessible::DoDefaultAction(int childId) +{ + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl && (childId != wxACC_SELF)) + { + // Zero-based array index + int iRealChildId = childId - 1; + + pCtrl->SetSelection(iRealChildId); + + // Fire Event + ProjectListCtrlEvent evt( + wxEVT_PROJECTLIST_ITEM_CHANGE, + pCtrl->GetItem(iRealChildId)->GetTitle(), + pCtrl->GetItem(iRealChildId)->GetURL(), + true + ); + evt.SetEventObject(this); + + pCtrl->GetParent()->AddPendingEvent( evt ); + + return wxACC_OK; + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Gets the default action for this object (0) or > 0 (the action for a child). +// Return wxACC_OK even if there is no action. actionName is the action, or the empty +// string if there is no action. +// The retrieved string describes the action that is performed on an object, +// not what the object does as a result. For example, a toolbar button that prints +// a document has a default action of "Press" rather than "Prints the current document." +wxAccStatus CProjectListCtrlAccessible::GetDefaultAction(int childId, wxString* actionName) +{ + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl && (childId != wxACC_SELF)) + { + *actionName = _("Click"); + return wxACC_OK; + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Returns the description for this object or a child. +wxAccStatus CProjectListCtrlAccessible::GetDescription(int childId, wxString* description) +{ + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl && (childId != wxACC_SELF)) + { + *description = pCtrl->GetItem(childId - 1)->GetDescription().c_str(); + return wxACC_OK; + } + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Returns a role constant. +wxAccStatus CProjectListCtrlAccessible::GetRole(int childId, wxAccRole* role) +{ + if (childId == wxACC_SELF) + { + *role = wxROLE_SYSTEM_LIST; + } + else + { + *role = wxROLE_SYSTEM_LISTITEM; + } + return wxACC_OK; +} + + +// Returns a role constant. +wxAccStatus CProjectListCtrlAccessible::GetState(int childId, long* state) +{ + if (childId == wxACC_SELF) + { + *state = wxACC_STATE_SYSTEM_DEFAULT; + } + else + { + CProjectListCtrl* pCtrl = wxDynamicCast(GetWindow(), CProjectListCtrl); + if (pCtrl && (pCtrl->IsSelected(childId - 1))) + { + *state = wxACC_STATE_SYSTEM_SELECTED | wxACC_STATE_SYSTEM_FOCUSED; + } + else if (pCtrl && (pCtrl->IsVisible(childId - 1))) + { + *state = wxACC_STATE_SYSTEM_SELECTABLE; + } + else + { + *state = wxACC_STATE_SYSTEM_SELECTABLE | wxACC_STATE_SYSTEM_INVISIBLE; + } + } + return wxACC_OK; +} + + +// Selects the object or child. +wxAccStatus CProjectListCtrlAccessible::Select(int childId, wxAccSelectionFlags selectFlags) +{ + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + + +// Gets a variant representing the selected children +// of this object. +// Acceptable values: +// - a null variant (IsNull() returns true) +// - a list variant (GetType() == wxT("list")) +// - an integer representing the selected child element, +// or 0 if this object is selected (GetType() == wxT("long")) +// - a "void*" pointer to a wxAccessible child object +wxAccStatus CProjectListCtrlAccessible::GetSelections(wxVariant* selections) +{ + // Let the framework handle the other cases. + return wxACC_NOT_IMPLEMENTED; +} + +#endif + + +/*! + * CProjectListItem type definition + */ +IMPLEMENT_DYNAMIC_CLASS( CProjectListItem, wxObject ) + + /*! * CProjectListCtrl event definitions */ DEFINE_EVENT_TYPE( wxEVT_PROJECTLIST_ITEM_CHANGE ) DEFINE_EVENT_TYPE( wxEVT_PROJECTLIST_ITEM_DISPLAY ) + /*! * CProjectListCtrl type definition */ - -IMPLEMENT_DYNAMIC_CLASS( CProjectListCtrl, wxScrolledWindow ) +IMPLEMENT_DYNAMIC_CLASS( CProjectListCtrl, wxHtmlListBox ) IMPLEMENT_DYNAMIC_CLASS( ProjectListCtrlEvent, wxNotifyEvent ) + /*! * CProjectListCtrl event table definition */ -BEGIN_EVENT_TABLE( CProjectListCtrl, wxScrolledWindow ) +BEGIN_EVENT_TABLE( CProjectListCtrl, wxHtmlListBox ) ////@begin CProjectListCtrl event table entries - EVT_SET_FOCUS( CProjectListCtrl::OnFocusChanged ) - EVT_KILL_FOCUS( CProjectListCtrl::OnFocusChanged ) - EVT_KEY_DOWN( CProjectListCtrl::OnKeyPressed ) - EVT_KEY_UP( CProjectListCtrl::OnKeyPressed ) + EVT_LISTBOX(ID_PROJECTLISTCTRL, CProjectListCtrl::OnSelected) + EVT_HTML_CELL_CLICKED( ID_PROJECTLISTCTRL, CProjectListCtrl::OnClicked ) + EVT_LISTBOX_DCLICK(ID_PROJECTLISTCTRL, CProjectListCtrl::OnDClicked) + EVT_HTML_LINK_CLICKED( ID_PROJECTLISTCTRL, CProjectListCtrl::OnLinkClicked ) + EVT_HTML_CELL_HOVER( ID_PROJECTLISTCTRL, CProjectListCtrl::OnHover ) ////@end CProjectListCtrl event table entries END_EVENT_TABLE() @@ -76,203 +372,86 @@ CProjectListCtrl::CProjectListCtrl( wxWindow* parent ) bool CProjectListCtrl::Create( wxWindow* parent ) { ////@begin CProjectListCtrl member initialisation - m_pMainSizer = NULL; ////@end CProjectListCtrl member initialisation - m_pCurrentSelection = NULL; - + ////@begin CProjectListCtrl creation - wxScrolledWindow::Create( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxSUNKEN_BORDER | wxVSCROLL | wxTAB_TRAVERSAL ); + wxHtmlListBox::Create( parent, ID_PROJECTLISTCTRL, wxDefaultPosition, wxDefaultSize, + wxSUNKEN_BORDER | wxTAB_TRAVERSAL ); - SetMinSize(GetSize()); +#ifdef wxUSE_ACCESSIBILITY + SetAccessible(new CProjectListCtrlAccessible(this)); +#endif - CreateControls(); - - SetBackgroundColour( wxT("WHITE") ); - SetScrollRate( 0, 25 ); - - GetSizer()->Fit(this); + wxMemoryFSHandler::AddFile(wxT("webexternallink.xpm"), wxBitmap(externalweblink_xpm), wxBITMAP_TYPE_XPM); ////@end CProjectListCtrl creation return TRUE; } - -/*! - * Control creation for ProjectListCtrl - */ - -void CProjectListCtrl::CreateControls() -{ -////@begin CProjectListCtrl content construction - wxFlexGridSizer* itemFlexGridSizer5 = new wxFlexGridSizer(0, 1, 0, 0); - itemFlexGridSizer5->AddGrowableCol(0); - wxFlexGridSizer* itemFlexGridSizer6 = new wxFlexGridSizer(1, 1, 0, 0); - itemFlexGridSizer6->AddGrowableRow(0); - itemFlexGridSizer6->AddGrowableCol(0); - itemFlexGridSizer5->Add(itemFlexGridSizer6, 0, wxGROW|wxGROW|wxALL, 0); +void CProjectListCtrl::OnSelected( wxCommandEvent& event ) +{ + // Fire Event + ProjectListCtrlEvent evt( + wxEVT_PROJECTLIST_ITEM_CHANGE, + m_Items[event.GetInt()]->GetTitle(), + m_Items[event.GetInt()]->GetURL(), + m_Items[event.GetInt()]->IsPlatformSupported() + ); + evt.SetEventObject(this); - m_pMainSizer = new wxBoxSizer(wxVERTICAL); - itemFlexGridSizer6->Add(m_pMainSizer, 0, wxGROW|wxGROW|wxALL, 5); - - SetSizer(itemFlexGridSizer5); - -////@end CProjectListCtrl content construction + GetParent()->AddPendingEvent( evt ); } -/*! - * event handler for window - */ - -void CProjectListCtrl::OnItemChange( CProjectListItemCtrl* pSelectedItem ) { - - // Fire an event for the parent window notifing it of the new selection. - if (pSelectedItem) { - - // Store so we know where we are - m_pCurrentSelection = pSelectedItem; - - // Fire Event - ProjectListCtrlEvent evt( - wxEVT_PROJECTLIST_ITEM_CHANGE, - pSelectedItem->GetTitle(), - pSelectedItem->GetURL(), - pSelectedItem->IsSupported() - ); - evt.SetEventObject(this); - - GetParent()->AddPendingEvent( evt ); - } - -} - - -/*! - * event handler for window - */ - -void CProjectListCtrl::OnItemDisplay( wxCommandEvent& event ) { - - // Fire an event for the parent window notifing it to display more information. - CProjectListItemCtrl* pItem = wxDynamicCast(event.GetEventObject(), CProjectListItemCtrl); - if (pItem) { - - // Fire Event - ProjectListCtrlEvent evt( - wxEVT_PROJECTLIST_ITEM_DISPLAY, - pItem->GetTitle(), - pItem->GetURL(), - pItem->IsSupported() - ); - evt.SetEventObject(this); - - GetParent()->AddPendingEvent( evt ); - } - -} - - -/*! - * event handler for window - */ - -void CProjectListCtrl::OnItemFocusChange( CProjectListItemCtrl* pSelectedItem ) { - - // Reset the background color back to the default - wxWindowList::compatibility_iterator current = GetChildren().GetFirst(); - while (current) { - wxWindow* child = current->GetData(); - - child->SetBackgroundColour( wxNullColour ); - child->Refresh(); - - current = current->GetNext(); - } - - // Set the background color of the window that threw the event to the - // default background color of a selected control. - if (pSelectedItem) { - pSelectedItem->SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) ); - pSelectedItem->Refresh(); - - OnItemChange( pSelectedItem ); - } - -} - - -/*! - * wxEVT_SET_FOCUS, wxEVT_KILL_FOCUS event handler for window - */ - -void CProjectListCtrl::OnFocusChanged( wxFocusEvent& event ) { - - if ( wxEVT_SET_FOCUS == event.GetEventType() ) { - // Control has focus - if (!m_pCurrentSelection) { - // Set the focus to the first child - GetChildren().GetFirst()->GetData()->SetFocus(); - } - } +void CProjectListCtrl::OnClicked( wxHtmlCellEvent& event ) +{ event.Skip(); - } -/*! - * wxEVT_KEY_DOWN, wxEVT_KEY_UP event handler for window - */ +void CProjectListCtrl::OnDClicked( wxCommandEvent& event ) +{ + event.Skip(); +} -void CProjectListCtrl::OnKeyPressed( wxKeyEvent& event ) { - wxWindowList list; - list = GetChildren(); - if ( (wxEVT_KEY_DOWN == event.GetEventType()) && (WXK_DOWN == event.GetKeyCode()) ) { +void CProjectListCtrl::OnLinkClicked( wxHtmlLinkEvent& event ) +{ + // Fire Event + ProjectListCtrlEvent evt( + wxEVT_PROJECTLIST_ITEM_DISPLAY, + wxEmptyString, + event.GetLinkInfo().GetHref(), + true + ); + evt.SetEventObject(this); - wxWindowList::compatibility_iterator iter = GetChildren().GetLast(); - while (iter) { - wxWindow* pCurentWindow = iter->GetData(); - if (pCurentWindow == m_pCurrentSelection) { - wxWindowListNode* pNextNode = iter->GetNext(); - if (pNextNode) { - wxWindow* pNextWindow = pNextNode->GetData(); - if (pNextWindow) { - pNextWindow->SetFocus(); - } - } - } - iter = iter->GetPrevious(); - } + GetParent()->AddPendingEvent( evt ); +} - } else if ( (wxEVT_KEY_DOWN == event.GetEventType()) && (WXK_UP == event.GetKeyCode()) ) { - wxWindowList::compatibility_iterator iter = GetChildren().GetFirst(); - while (iter) { - wxWindow* pCurentWindow = iter->GetData(); - if (pCurentWindow == m_pCurrentSelection) { - wxWindowListNode* pPreviousNode = iter->GetPrevious(); - if (pPreviousNode) { - wxWindow* pPreviousWindow = pPreviousNode->GetData(); - if (pPreviousWindow) { - pPreviousWindow->SetFocus(); - } - } - } - iter = iter->GetNext(); - } +void CProjectListCtrl::OnHover( wxHtmlCellEvent& event ) +{ + event.Skip(); +} - } else if ( (wxEVT_KEY_DOWN == event.GetEventType()) && (WXK_TAB == event.GetKeyCode()) ) { - if (wxMOD_SHIFT == event.GetModifiers()) { - Navigate( wxNavigationKeyEvent::IsBackward & wxNavigationKeyEvent::WinChange ); - } else { - Navigate( wxNavigationKeyEvent::IsForward & wxNavigationKeyEvent::WinChange ); - } +wxString CProjectListCtrl::OnGetItem(size_t i) const +{ + wxString buf = wxEmptyString; - } else { - event.Skip(); - } + buf.Printf( + wxT(" ") + wxT(" ") + wxT(" ") + wxT(" ") + wxT(" ") + wxT("
%s
"), + m_Items[i]->GetTitle().c_str(), + m_Items[i]->GetURL().c_str() + ); + + return buf; } @@ -281,367 +460,44 @@ void CProjectListCtrl::OnKeyPressed( wxKeyEvent& event ) { */ bool CProjectListCtrl::Append( - wxString strTitle, wxString strURL, + wxString strTitle, + wxString strDescription, bool bSupported ) { - CProjectListItemCtrl* pItem = new CProjectListItemCtrl(); - pItem->Create( this ); - pItem->SetTitle( strTitle ); + CProjectListItem* pItem = new CProjectListItem(); + pItem->SetURL( strURL ); - pItem->SetSupportedStatus( bSupported ); + pItem->SetTitle( strTitle ); + pItem->SetDescription( strDescription ); + pItem->SetPlatformSupported( bSupported ); - m_pMainSizer->Add( pItem, 0, wxEXPAND ); - - FitInside(); + m_Items.push_back(pItem); + SetItemCount(m_Items.size()); return true; } /*! - * CProjectListItemCtrl type definition + * Return the project list entry at a given index. */ -IMPLEMENT_DYNAMIC_CLASS( CProjectListItemCtrl, wxPanel ) - - -/*! - * CProjectListItemCtrl event table definition - */ - -BEGIN_EVENT_TABLE( CProjectListItemCtrl, wxPanel ) - -////@begin CProjectListItemCtrl event table entries - EVT_ENTER_WINDOW( CProjectListItemCtrl::OnMouseEnterLeave ) - EVT_LEAVE_WINDOW( CProjectListItemCtrl::OnMouseEnterLeave ) - EVT_LEFT_DOWN( CProjectListItemCtrl::OnMouseClick ) - EVT_LEFT_UP( CProjectListItemCtrl::OnMouseClick ) - EVT_KEY_DOWN( CProjectListItemCtrl::OnKeyPressed ) - EVT_KEY_UP( CProjectListItemCtrl::OnKeyPressed ) - EVT_BUTTON( ID_WEBSITEBUTTON, CProjectListItemCtrl::OnWebsiteButtonClick ) -////@end CProjectListItemCtrl event table entries - -END_EVENT_TABLE() - -/*! - * CProjectListItemCtrl constructors - */ - -CProjectListItemCtrl::CProjectListItemCtrl( ) -{ -} - -CProjectListItemCtrl::CProjectListItemCtrl( wxWindow* parent ) -{ - Create( parent ); -} - -/*! - * CProjectListItemCtrl creator - */ - -bool CProjectListItemCtrl::Create( wxWindow* parent ) -{ -////@begin CProjectListItemCtrl member initialisation - m_pTitleStaticCtrl = NULL; - m_pWebsiteButtonCtrl = NULL; - m_strTitle = wxEmptyString; - m_strURL = wxEmptyString; - m_bSupported = false; -////@end CProjectListItemCtrl member initialisation - -////@begin CProjectListItemCtrl creation - wxPanel::Create( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxNO_BORDER | wxWANTS_CHARS | wxTAB_TRAVERSAL ); - - CreateControls(); - GetSizer()->Fit(this); -////@end CProjectListItemCtrl creation - - return TRUE; -} - -/*! - * Control creation for CProjectListItemCtrl - */ - -void CProjectListItemCtrl::CreateControls() -{ -////@begin CProjectListItemCtrl content construction - - wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxVERTICAL); - - wxFlexGridSizer* itemFlexGridSizer8 = new wxFlexGridSizer(1, 2, 0, 0); - itemFlexGridSizer8->AddGrowableRow(0); - itemFlexGridSizer8->AddGrowableCol(0); - itemBoxSizer7->Add(itemFlexGridSizer8, 0, wxGROW|wxALL, 0); - - m_pTitleStaticCtrl = new CProjectListItemStaticCtrl; - m_pTitleStaticCtrl->Create( this, wxID_STATIC, wxT(""), wxDefaultPosition, wxDefaultSize, 0 ); - itemFlexGridSizer8->Add(m_pTitleStaticCtrl, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 0); - - m_pWebsiteButtonCtrl = new CProjectListItemBitmapCtrl; - m_pWebsiteButtonCtrl->Create( this, ID_WEBSITEBUTTON, wxBitmap(externalweblink_xpm), wxDefaultPosition, wxSize(12,12), wxNO_BORDER ); - itemFlexGridSizer8->Add(m_pWebsiteButtonCtrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0); - - SetSizer(itemBoxSizer7); - -////@end CProjectListItemCtrl content construction -} - -/*! - * wxEVT_ENTER_WINDOW, wxEVT_LEAVE_WINDOW event handler for window - */ - -void CProjectListItemCtrl::OnMouseEnterLeave( wxMouseEvent& event ) { - m_bLeftButtonDownDetected = false; - event.Skip(); -} - - -/*! - * wxEVT_LEFT_DOWN, wxEVT_LEFT_UP event handler for window - */ - -void CProjectListItemCtrl::OnMouseClick( wxMouseEvent& event ) { - - if ( event.LeftDown() ) { - m_bLeftButtonDownDetected = true; - } else { - if ( m_bLeftButtonDownDetected ) { - CProjectListCtrl* pParent = wxDynamicCast(GetParent(), CProjectListCtrl); - if (pParent) { - pParent->OnItemFocusChange( this ); - } - } - } - event.Skip(); - -} - - -/*! - * wxEVT_KEY_DOWN, wxEVT_KEY_UP event handler for window - */ - -void CProjectListItemCtrl::OnKeyPressed( wxKeyEvent& event ) { - CProjectListCtrl* pParent = wxDynamicCast(GetParent(), CProjectListCtrl); - if (pParent) { - pParent->OnKeyPressed( event ); - } -} - - -/*! - * wxEVT_COMMAND_BUTTON_CLICKED event handler for window - */ - -void CProjectListItemCtrl::OnWebsiteButtonClick( wxCommandEvent& event ) { - - if (!m_strURL.IsEmpty()) { - // We now have focus, report that to the parent - CProjectListCtrl* pParent = wxDynamicCast(GetParent(), CProjectListCtrl); - if (pParent) { - pParent->OnItemDisplay( event ); - } - } - -} - - -bool CProjectListItemCtrl::SetTitle( wxString strTitle ) { - if (m_pTitleStaticCtrl) m_pTitleStaticCtrl->SetLabel( strTitle ); - m_strTitle = strTitle; - return true; -} - - -bool CProjectListItemCtrl::SetURL( wxString strURL ) { - if (m_pWebsiteButtonCtrl) { - wxString strBuffer = wxEmptyString; - - strBuffer.Printf( - _("Click here to go to %s's website."), - m_strTitle.c_str() - ); - - m_pWebsiteButtonCtrl->SetToolTip(strBuffer); - } - m_strURL = strURL; - return true; -} - - -bool CProjectListItemCtrl::SetSupportedStatus( bool bSupported ) { - if (m_pTitleStaticCtrl) { - m_pTitleStaticCtrl->Enable( bSupported ); - } - m_bSupported = bSupported; - return true; -} - - -/*! - * CProjectListItemStaticCtrl type definition - */ - -IMPLEMENT_DYNAMIC_CLASS( CProjectListItemStaticCtrl, wxStaticText ) - -/*! - * CProjectListItemStaticCtrl event table definition - */ - -BEGIN_EVENT_TABLE( CProjectListItemStaticCtrl, wxStaticText ) - -////@begin CProjectListItemStaticCtrl event table entries - EVT_ENTER_WINDOW( CProjectListItemStaticCtrl::OnMouseEnterLeave ) - EVT_LEAVE_WINDOW( CProjectListItemStaticCtrl::OnMouseEnterLeave ) - EVT_LEFT_DOWN( CProjectListItemStaticCtrl::OnMouseClick ) - EVT_LEFT_UP( CProjectListItemStaticCtrl::OnMouseClick ) -////@end CProjectListItemStaticCtrl event table entries - -END_EVENT_TABLE() - -/*! - * CProjectListItemStaticCtrl constructors - */ - -CProjectListItemStaticCtrl::CProjectListItemStaticCtrl( ) -{ -} - -CProjectListItemStaticCtrl::CProjectListItemStaticCtrl( - wxWindow *parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxString& name +CProjectListItem* CProjectListCtrl::GetItem( + int iIndex ) { - Create (parent, id, label, pos, size, style, name); + return m_Items[iIndex]; } - + + /*! - * CProjectListItemStaticCtrl creator + * Return the total height of all the client items. */ -bool CProjectListItemStaticCtrl::Create( - wxWindow *parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxString& name -) +wxCoord CProjectListCtrl::GetTotalClientHeight() { - bool retval = false; - - retval = wxStaticText::Create (parent, id, label, pos, size, style, name); - - return retval; -} - - -/*! - * wxEVT_ENTER_WINDOW, wxEVT_LEAVE_WINDOW event handler for window - */ - -void CProjectListItemStaticCtrl::OnMouseEnterLeave( wxMouseEvent& event ) { - CProjectListItemCtrl* pParent = wxDynamicCast(GetParent(), CProjectListItemCtrl); - if (pParent) { - pParent->OnMouseEnterLeave( event ); - } -} - - -/*! - * wxEVT_LEFT_DOWN, wxEVT_LEFT_UP event handler for window - */ - -void CProjectListItemStaticCtrl::OnMouseClick( wxMouseEvent& event ) { - CProjectListItemCtrl* pParent = wxDynamicCast(GetParent(), CProjectListItemCtrl); - if (pParent) { - pParent->OnMouseClick( event ); - } -} - - -/*! - * CProjectListItemBitmapCtrl type definition - */ - -IMPLEMENT_DYNAMIC_CLASS( CProjectListItemBitmapCtrl, wxStaticBitmap ) - -/*! - * CProjectListItemBitmapCtrl event table definition - */ - -BEGIN_EVENT_TABLE( CProjectListItemBitmapCtrl, wxStaticBitmap ) - -////@begin CProjectListItemBitmapCtrl event table entries - EVT_ENTER_WINDOW( CProjectListItemBitmapCtrl::OnMouseEnterLeave ) - EVT_LEAVE_WINDOW( CProjectListItemBitmapCtrl::OnMouseEnterLeave ) - EVT_LEFT_DOWN( CProjectListItemBitmapCtrl::OnMouseClick ) - EVT_LEFT_UP( CProjectListItemBitmapCtrl::OnMouseClick ) -////@end CProjectListItemBitmapCtrl event table entries - -END_EVENT_TABLE() - -/*! - * CProjectListItemBitmapCtrl constructors - */ - -CProjectListItemBitmapCtrl::CProjectListItemBitmapCtrl( ) -{ -} - -CProjectListItemBitmapCtrl::CProjectListItemBitmapCtrl( - wxWindow *parent, wxWindowID id, const wxBitmap& bitmap, const wxPoint& pos, const wxSize& size, long style, const wxString& name -) -{ - Create (parent, id, bitmap, pos, size, style, name); -} - -/*! - * CProjectListItemBitmapCtrl creator - */ - -bool CProjectListItemBitmapCtrl::Create( - wxWindow *parent, wxWindowID id, const wxBitmap& bitmap, const wxPoint& pos, const wxSize& size, long style, const wxString& name -) -{ - bool retval = false; - - retval = wxStaticBitmap::Create (parent, id, bitmap, pos, size, style, name); - - return retval; -} - - -/*! - * wxEVT_ENTER_WINDOW, wxEVT_LEAVE_WINDOW event handler for window - */ - -void CProjectListItemBitmapCtrl::OnMouseEnterLeave( wxMouseEvent& event ) { - m_bLeftButtonDownDetected = false; - event.Skip(); -} - - -/*! - * wxEVT_LEFT_DOWN, wxEVT_LEFT_UP event handler for window - */ - -void CProjectListItemBitmapCtrl::OnMouseClick( wxMouseEvent& event ) { - - if ( event.LeftDown() ) { - m_bLeftButtonDownDetected = true; - } else { - if ( m_bLeftButtonDownDetected ) { - // The control that reported the down event is also - // the one reporting the up event, so it is a valid - // click event. - wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED); - evt.SetId( ID_WEBSITEBUTTON ); - evt.SetEventObject(this); - - GetParent()->AddPendingEvent( evt ); - } - } - event.Skip(); - + return EstimateTotalHeight(); } diff --git a/clientgui/ProjectListCtrl.h b/clientgui/ProjectListCtrl.h index bd7a00cb76..858d62465f 100644 --- a/clientgui/ProjectListCtrl.h +++ b/clientgui/ProjectListCtrl.h @@ -23,22 +23,72 @@ #endif -class CProjectListItemCtrl; -class CProjectListItemStaticCtrl; -class CProjectListItemBitmapCtrl; -class ProjectListCtrlEvent; +/*! + * CProjectListItem class declaration + */ + +class CProjectListItem: public wxObject +{ + DECLARE_DYNAMIC_CLASS( CProjectListItem ) +public: + + wxString GetURL() const { return m_strURL ; } + void SetURL(wxString value) { m_strURL = value ; } + + wxString GetTitle() const { return m_strTitle ; } + void SetTitle(wxString value) { m_strTitle = value ; } + + wxString GetOrganization() const { return m_strOrganization ; } + void SetOrganization(wxString value) { m_strOrganization = value ; } + + wxString GetDescription() const { return m_strDescription ; } + void SetDescription(wxString value) { m_strDescription = value ; } + + wxString GetCategory() const { return m_strCategory ; } + void SetCategory(wxString value) { m_strCategory = value ; } + + bool IsPlatformSupported() const { return m_bSupported ; } + void SetPlatformSupported(bool value) { m_bSupported = value ; } + +private: + wxString m_strURL; + wxString m_strTitle; + wxString m_strOrganization; + wxString m_strDescription; + wxString m_strCategory; + bool m_bSupported; +}; -////@begin control identifiers -#define ID_WEBSITEBUTTON 10001 -////@end control identifiers +#ifdef wxUSE_ACCESSIBILITY + +class CProjectListCtrlAccessible: public wxWindowAccessible +{ +public: + CProjectListCtrlAccessible(wxWindow* win): wxWindowAccessible(win) {} + + virtual wxAccStatus GetName(int childId, wxString* name); + virtual wxAccStatus HitTest(const wxPoint& pt, int* childId, wxAccessible** childObject); + virtual wxAccStatus GetLocation(wxRect& rect, int elementId); + virtual wxAccStatus Navigate(wxNavDir navDir, int fromId, int* toId, wxAccessible** toObject); + virtual wxAccStatus GetChildCount(int* childCount); + virtual wxAccStatus DoDefaultAction(int childId); + virtual wxAccStatus GetDefaultAction(int childId, wxString* actionName); + virtual wxAccStatus GetDescription(int childId, wxString* description); + virtual wxAccStatus GetRole(int childId, wxAccRole* role); + virtual wxAccStatus GetState(int childId, long* state); + virtual wxAccStatus Select(int childId, wxAccSelectionFlags selectFlags); + virtual wxAccStatus GetSelections(wxVariant* selections); +}; + +#endif /*! * CProjectListCtrl class declaration */ -class CProjectListCtrl: public wxScrolledWindow +class CProjectListCtrl: public wxHtmlListBox { DECLARE_DYNAMIC_CLASS( CProjectListCtrl ) DECLARE_EVENT_TABLE() @@ -52,38 +102,34 @@ public: /// Creation bool Create( wxWindow* parent ); - /// Creates the controls and sizers - void CreateControls(); - ////@begin CProjectListCtrl event handler declarations - /// event handler for window - void OnItemChange( CProjectListItemCtrl* pSelectedItem ); - - /// event handler for window - void OnItemDisplay( wxCommandEvent& event ); - - /// event handler for window - void OnItemFocusChange( CProjectListItemCtrl* pSelectedItem ); - - /// wxEVT_SET_FOCUS, wxEVT_KILL_FOCUS event handler for window - void OnFocusChanged( wxFocusEvent& event ); - - /// wxEVT_KEY_DOWN, wxEVT_KEY_UP event handler for window - void OnKeyPressed( wxKeyEvent& event ); + void OnSelected( wxCommandEvent& event ); + void OnClicked( wxHtmlCellEvent& event ); + void OnDClicked( wxCommandEvent& event ); + void OnLinkClicked( wxHtmlLinkEvent& event ); + void OnHover( wxHtmlCellEvent& event ); ////@end CProjectListCtrl event handler declarations + virtual wxString OnGetItem(size_t i) const; + /// Methods bool Append( - wxString strTitle, wxString strURL, + wxString strTitle, + wxString strDescription, bool bSupported ); + CProjectListItem* GetItem( + int iIndex + ); + + wxCoord GetTotalClientHeight(); + private: - wxWindow* m_pCurrentSelection; - wxBoxSizer* m_pMainSizer; + std::vector m_Items; }; @@ -137,155 +183,4 @@ typedef void (wxEvtHandler::*ProjectListCtrlEventFunction)(ProjectListCtrlEvent& #define EVT_PROJECTLIST_ITEM_DISPLAY(fn) wx__DECLARE_PROJECTLISTEVT(ITEM_DISPLAY, fn) -/*! - * CProjectListItemCtrl class declaration - */ - -class CProjectListItemCtrl: public wxPanel -{ - DECLARE_DYNAMIC_CLASS( CProjectListItemCtrl ) - DECLARE_EVENT_TABLE() - -public: - /// Constructors - CProjectListItemCtrl( ); - - CProjectListItemCtrl( wxWindow* parent ); - - /// Creation - bool Create( wxWindow* parent ); - - /// Creates the controls and sizers - void CreateControls(); - -////@begin CProjectListItemCtrl event handler declarations - - /// wxEVT_ENTER_WINDOW, wxEVT_LEAVE_WINDOW event handler for window - void OnMouseEnterLeave( wxMouseEvent& event ); - - /// wxEVT_LEFT_DOWN, wxEVT_LEFT_UP event handler for window - void OnMouseClick( wxMouseEvent& event ); - - /// wxEVT_KEY_DOWN, wxEVT_KEY_UP event handler for window - void OnKeyPressed( wxKeyEvent& event ); - - /// wxEVT_COMMAND_BUTTON_CLICKED event handler for window - void OnWebsiteButtonClick( wxCommandEvent& event ); - -////@end CProjectListItemCtrl event handler declarations - - /// Methods - wxString GetTitle() { return m_strTitle; }; - wxString GetURL() { return m_strURL; }; - bool IsSupported() { return m_bSupported; }; - - bool SetTitle( wxString strTitle ); - bool SetURL( wxString strURL ); - bool SetSupportedStatus( bool bSupported ); - -private: - CProjectListItemStaticCtrl* m_pTitleStaticCtrl; - CProjectListItemBitmapCtrl* m_pWebsiteButtonCtrl; - wxString m_strTitle; - wxString m_strURL; - bool m_bSupported; - - bool m_bLeftButtonDownDetected; -}; - - -/*! - * CProjectListItemStaticCtrl class declaration - */ - -class CProjectListItemStaticCtrl: public wxStaticText -{ - DECLARE_DYNAMIC_CLASS( CProjectListItemStaticCtrl ) - DECLARE_EVENT_TABLE() - -public: - /// Constructors - CProjectListItemStaticCtrl(); - - CProjectListItemStaticCtrl( - wxWindow *parent, - wxWindowID id, - const wxString &label = wxEmptyString, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = 0, - const wxString &name = _T("ProjectListItemStaticCtrl") - ); - - /// Creation - bool Create ( - wxWindow *parent, - wxWindowID id, - const wxString &label = wxEmptyString, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = 0, - const wxString &name = _T("ProjectListItemStaticCtrl") - ); - -////@begin CProjectListItemStaticCtrl event handler declarations - - /// wxEVT_ENTER_WINDOW, wxEVT_LEAVE_WINDOW event handler for window - void OnMouseEnterLeave( wxMouseEvent& event ); - - /// wxEVT_LEFT_DOWN, wxEVT_LEFT_UP event handler for window - void OnMouseClick( wxMouseEvent& event ); - -////@end CProjectListItemStaticCtrl event handler declarations -}; - - -/*! - * CProjectListItemBitmapCtrl class declaration - */ - -class CProjectListItemBitmapCtrl: public wxStaticBitmap -{ - DECLARE_DYNAMIC_CLASS( CProjectListItemBitmapCtrl ) - DECLARE_EVENT_TABLE() - -public: - /// Constructors - CProjectListItemBitmapCtrl(); - - CProjectListItemBitmapCtrl( - wxWindow *parent, - wxWindowID id, - const wxBitmap& bitmap, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = 0, - const wxString &name = _T("ProjectListItemBitmapCtrl") - ); - - /// Creation - bool Create ( - wxWindow *parent, - wxWindowID id, - const wxBitmap& bitmap, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = 0, - const wxString &name = _T("ProjectListItemBitmapCtrl") - ); - -////@begin CProjectListItemBitmapCtrl event handler declarations - - /// wxEVT_ENTER_WINDOW, wxEVT_LEAVE_WINDOW event handler for window - void OnMouseEnterLeave( wxMouseEvent& event ); - - /// wxEVT_LEFT_DOWN, wxEVT_LEFT_UP event handler for window - void OnMouseClick( wxMouseEvent& event ); - -////@end CProjectListItemBitmapCtrl event handler declarations - - bool m_bLeftButtonDownDetected; -}; - - #endif // _WIZ_PROJECTLISTCTRL_H_ diff --git a/clientgui/stdwx.h b/clientgui/stdwx.h index 25bf9198f9..2d501fdde6 100644 --- a/clientgui/stdwx.h +++ b/clientgui/stdwx.h @@ -112,7 +112,9 @@ #include #include #include +#include #include +#include #ifdef _WIN32