[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
[XaraXtreme-commits] Commit Complete
Commit by : alex
Repository : xara
Revision : 1703
Date : Thu Aug 17 10:22:54 BST 2006
Changed paths:
A /Trunk/XaraLX/wxXtra/gridcombo.cpp
A /Trunk/XaraLX/wxXtra/gridcombo.h
A /Trunk/XaraLX/wxXtra/xh_gridcombo.cpp
A /Trunk/XaraLX/wxXtra/xh_gridcombo.h
Add files I forgot
Diff:
Index: Trunk/XaraLX/wxXtra/gridcombo.cpp
===================================================================
--- Trunk/XaraLX/wxXtra/gridcombo.cpp (revision 0)
+++ Trunk/XaraLX/wxXtra/gridcombo.cpp (revision 1703)
@@ -0,0 +1,914 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: gridcombo.cpp
+// Purpose: A grid grid combo
+// Author: Mikhail Tatarnikov
+// Modified by:
+// Created: 2006-08-16
+// RCS-ID: $Id: $
+// Copyright: (c) 2006 Xara Ltd
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "gridcombo.h"
+#include <wx/utils.h>
+
+
+#define HIGHLITED_TIMERID 777
+#define HIGHLITED_TIMERINTERVAL 250
+
+
+
+BEGIN_EVENT_TABLE(wxGridComboPopup, wxScrolledWindow)
+ EVT_TIMER(HIGHLITED_TIMERID, wxGridComboPopup::OnTimer)
+ EVT_SIZE(wxGridComboPopup::OnSize)
+ EVT_MOTION(wxGridComboPopup::OnMouseMove)
+ EVT_KEY_DOWN(wxGridComboPopup::OnKey)
+ EVT_LEFT_UP(wxGridComboPopup::OnLeftClick)
+END_EVENT_TABLE()
+
+
+
+wxGridComboPopup::wxGridComboPopup(wxGridCombo* pCombo)
+ : m_tmrHighlited(this, HIGHLITED_TIMERID)
+{
+ m_pCombo = pCombo;
+ m_iHighlighed = -1;
+
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::GetColumns
+Author : Mikhail Tatarnikov
+Purpose : A helper function to obtain the number of columns specified by the user
+Returns : int - the number of columns to display in the popup.
+Exceptions:
+Parameters: None
+Notes : All the information is stored in one place - the combobox control itself.
+******************************************************************************/
+int wxGridComboPopup::GetColumns() const
+{
+ return m_pCombo->GetColumns();
+}
+
+/******************************************************************************
+Function : intwxGridComboPopup::GetRows
+Author : Mikhail Tatarnikov
+Purpose : A helper function to obtain the number of rows that should be
+ displayd. Not all rows will be visible at once.
+Returns : int - the number of all rows (visible and invisible).
+Exceptions:
+Parameters: None
+Notes : All the required to calculate the rows coun is stored in one
+ place - the combobox control itself.
+******************************************************************************/
+int wxGridComboPopup::GetRows() const
+{
+ return m_pCombo->GetRows();
+}
+
+/******************************************************************************
+Function : intwxGridComboPopup::GetItemsNum
+Author : Mikhail Tatarnikov
+Purpose : A helper function to obtain the number of items in the combobx.
+Returns : int - the number of items to display.
+Exceptions:
+Parameters: None
+Notes : All the information is stored in one place - the combobox control itself.
+******************************************************************************/
+int wxGridComboPopup::GetItemsNum() const
+{
+ return m_pCombo->GetItemsNum();
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::GetItemSize
+Author : Mikhail Tatarnikov
+Purpose : A helper function to obtain the size of items - e.g. the popup cell
+ size.
+Returns : wxSize - the items size.
+Exceptions:
+Parameters: None
+Notes : All the information is stored in one place - the combobox control itself.
+ All items have the same size.
+******************************************************************************/
+wxSize wxGridComboPopup::GetItemSize() const
+{
+ return m_pCombo->GetItemSize();
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::GetSelected
+Author : Mikhail Tatarnikov
+Purpose : Get the currentrly selected element.
+Returns : int - the index of currently selected element, -1 if none.
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+int wxGridComboPopup::GetSelected() const
+{
+ return m_pCombo->GetSelected();
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::SetSelected
+Author : Mikhail Tatarnikov
+Purpose : Selects an element
+Returns : void
+Exceptions:
+Parameters: [in] int iItem - an element index to select.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::SetSelected(int iItem)
+{
+ m_pCombo->SetSelected(iItem);
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::Init
+Author : Mikhail Tatarnikov
+Purpose : Performs any initialization required.
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridComboPopup::Init()
+{
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::Create
+Author : Mikhail Tatarnikov
+Purpose : Creates the popup window
+Returns : bool - true if successfull, false otherwise.
+Exceptions:
+Parameters: [in] wxWindow* pwndParent - the parent window (combobox control).
+Notes :
+******************************************************************************/
+bool wxGridComboPopup::Create(wxWindow* pwndParent)
+{
+ if (!wxScrolledWindow::Create(pwndParent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxBORDER_SIMPLE | wxLB_INT_HEIGHT | wxWANTS_CHARS | wxVSCROLL | wxHSCROLL))
+ return false;
+
+ SetAutoLayout(true);
+
+ return true;
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::ChangeSelection
+Author : Mikhail Tatarnikov
+Purpose : Notification that the selection has been changed.
+Returns : void
+Exceptions:
+Parameters: [in] int iOldSelected - the prevoiusly selected item;
+ [in] int iNewSelected - the newly selected item.
+Notes : Control has to repqint both items.
+******************************************************************************/
+void wxGridComboPopup::ChangeSelection(int iOldSelected, int iNewSelected)
+{
+ InvalidateItem(iOldSelected);
+ InvalidateItem(iNewSelected);
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::UpdateScrollers
+Author : Mikhail Tatarnikov
+Purpose : Update the scroll bars with the current information
+ (items number, columns, sizes, etc).
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridComboPopup::UpdateScrollers()
+{
+ wxSize szItem = GetItemSize();
+
+ wxPoint ptGrid(0, 0);
+ int iSelected = GetSelected();
+ if (iSelected != -1)
+ ptGrid = ItemToGrid(iSelected);
+
+ SetScrollbars(szItem.x, szItem.y, GetColumns(), GetRows(),
+ ptGrid.x, ptGrid.y);
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::ItemToGrid
+Author : Mikhail Tatarnikov
+Purpose : Calculates position of an item based on its index
+Returns : wxPoint - the item position (row/column).
+Exceptions:
+Parameters: [in] int iItem - item index to calculate positio for.
+Notes :
+******************************************************************************/
+wxPoint wxGridComboPopup::ItemToGrid(int iItem)
+{
+ wxPoint ptGrid;
+ int iCols = GetColumns();
+ ptGrid.x = iItem % iCols;
+ ptGrid.y = iItem / iCols;
+
+ return ptGrid;
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::ItemFromPoint
+Author : Mikhail Tatarnikov
+Purpose : Finds item based on point (in client virtual coordinates)
+Returns : int - the item index which the point belong.
+Exceptions:
+Parameters: [in] wxPoint ptClient - the point to find item from.
+Notes :
+******************************************************************************/
+int wxGridComboPopup::ItemFromPoint(wxPoint ptClient)
+{
+ // TODO: Optimise - calculate instead of brute force iterate.
+
+ int iItemsNum = GetItemsNum();
+ for (int i = 0; i < iItemsNum; ++i)
+ {
+ // Calculate the area of the current item.
+ wxRect rcItem = GetItemRect(i);
+
+ // Check if the item should be updated.
+ if (rcItem.Inside(ptClient))
+ return i;
+ }
+
+ return -1;
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::GetItemRect
+Author : Mikhail Tatarnikov
+Purpose : Calculates the item area (in client virtual coordinates)
+Returns : wxRect - the area occupied by the item.
+Exceptions:
+Parameters: [in] int iItem - item to calculate the area for.
+Notes :
+******************************************************************************/
+wxRect wxGridComboPopup::GetItemRect(int iItem)
+{
+ wxPoint ptGrid = ItemToGrid(iItem);
+ wxSize szItem = GetItemSize();
+
+ ptGrid.x *= szItem.x;
+ ptGrid.y *= szItem.y;
+
+ wxRect rcItem(ptGrid, szItem);
+
+ return rcItem;
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::ClientToScrolledVirtual
+Author : Mikhail Tatarnikov
+Purpose : Transfers a point from client to virtual (scrolled) coordinates
+Returns : void
+Exceptions:
+Parameters: [in/out] int* pX - the absciss value to convert;
+ [in/out] int* pY - the ordinate value to convert.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::ClientToScrolledVirtual(int* pX, int* pY)
+{
+ wxSize szItem = GetItemSize();
+ int iXOrigin = 0;
+ int iYOrigin = 0;
+ GetViewStart(&iXOrigin, &iYOrigin);
+
+ if (pX)
+ *pX += iXOrigin * szItem.x;
+
+ if (pY)
+ *pY += iYOrigin * szItem.y;
+
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::OnShow
+Author : Mikhail Tatarnikov
+Purpose : Notification that the popup is about to be shown
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridComboPopup::OnShow()
+{
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::OnSize
+Author : Mikhail Tatarnikov
+Purpose : Resize notification handler.
+Returns : void
+Exceptions:
+Parameters: [in] wxSizeEvent& event - size event information.
+Notes : We need to update our scroll bars.
+******************************************************************************/
+void wxGridComboPopup::OnSize(wxSizeEvent& event)
+{
+ wxScrolledWindow::OnSize(event);
+
+ UpdateScrollers();
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::OnMouseMove
+Author : Mikhail Tatarnikov
+Purpose : mouse movement notification handler
+Returns : void
+Exceptions:
+Parameters: [in] wxMouseEvent& event - mouse event information.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::OnMouseMove(wxMouseEvent& event)
+{
+ // Convert the poin to the logical coordinates.
+ wxPoint ptMouse(event.GetX(), event.GetY());
+ ClientToScrolledVirtual(&ptMouse.x, &ptMouse.y);
+
+ // Find out what item the mouse hover over.
+ int iItem = ItemFromPoint(ptMouse);
+
+ // Check if mouse is hovered withing the same item.
+ if (iItem == m_iHighlighed)
+ return;
+
+ // If an item is hightlighted we need to start "dishighlight" timer
+ // since this message can be the last one before leaving the control.
+ if (iItem != -1)
+ m_tmrHighlited.Start(HIGHLITED_TIMERINTERVAL);
+
+ // Repaint the old and new items.
+ InvalidateItem(m_iHighlighed);
+ InvalidateItem(iItem);
+
+ m_iHighlighed = iItem;
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::OnTimer
+Author : Mikhail Tatarnikov
+Purpose : Timer notification handler
+Returns : void
+Exceptions:
+Parameters: [in] wxTimerEvent& event - time event information.
+Notes : We need it to trace situations when the mouse highlight an item and
+ then leave the control leaving the item highlighted.
+******************************************************************************/
+void wxGridComboPopup::OnTimer(wxTimerEvent& event)
+{
+ if (m_iHighlighed == -1)
+ {
+ m_tmrHighlited.Stop();
+ return;
+ }
+
+ wxMouseState oMouseState = wxGetMouseState();
+ wxPoint ptMouse(oMouseState.GetX(), oMouseState.GetY());
+
+ ScreenToClient(&(ptMouse.x), &(ptMouse.y));
+
+ int iItem = ItemFromPoint(ptMouse);
+
+ if (iItem == -1)
+ {
+ m_tmrHighlited.Stop();
+
+ int iCurHighlighted = m_iHighlighed;
+ m_iHighlighed = -1;
+ InvalidateItem(iCurHighlighted);
+ }
+
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::OnKey
+Author : Mikhail Tatarnikov
+Purpose : Keyboard notification handler.
+Returns : void
+Exceptions:
+Parameters: [in] wxKeyEvent& event - keyboard event information.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::OnKey(wxKeyEvent& event)
+{
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::OnLeftClick
+Author : Mikhail Tatarnikov
+Purpose : Left mouse button click handler
+Returns : void
+Exceptions:
+Parameters: [in] wxMouseEvent& event - mouse event information.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::OnLeftClick(wxMouseEvent& event)
+{
+ // Convert the poin to the logical coordinates.
+ wxPoint ptMouse(event.GetX(), event.GetY());
+ ClientToScrolledVirtual(&ptMouse.x, &ptMouse.y);
+
+ // Select a new item, if any was clicked.
+ int iItem = ItemFromPoint(ptMouse);
+ if (iItem != -1)
+ SetSelected(iItem);
+
+ DismissWithEvent();
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::DismissWithEvent
+Author : Mikhail Tatarnikov
+Purpose : Helper function to setup a new selection, close the popup and send
+ a notification message.
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridComboPopup::DismissWithEvent()
+{
+ Dismiss();
+
+ int iSelected = GetSelected();
+ SendComboBoxEvent(iSelected);
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::SendComboBoxEvent
+Author : Mikhail Tatarnikov
+Purpose : Sends a combobox selection event
+Returns : void
+Exceptions:
+Parameters: [in] int iSelection - a new selection to notify clients about.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::SendComboBoxEvent(int iSelection)
+{
+ wxCommandEvent evt(wxEVT_COMMAND_COMBOBOX_SELECTED, m_combo->GetId());
+
+ evt.SetEventObject(m_pCombo);
+
+ evt.SetInt(iSelection);
+
+ // Set client data, if any
+ if (iSelection >= 0 && GetItemsNum() > iSelection)
+ {
+ CGridComboUserData* pClientData = m_pCombo->GetUserData(iSelection);
+ evt.SetClientData(pClientData);
+ }
+
+ m_combo->GetEventHandler()->AddPendingEvent(evt);
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::GetAdjustedSize
+Author : Mikhail Tatarnikov
+Purpose : Calculates preferable size.
+Returns : wxSize - the final size requested.
+Exceptions:
+Parameters: [in] int iMinWidth - minimum width for the control. In some circumstances
+ can be ignored;
+ [in] int iPrefHeight - preferable height;
+ [in] int iMaxHeight - maximum of height allowed.
+Notes :
+******************************************************************************/
+wxSize wxGridComboPopup::GetAdjustedSize(int iMinWidth, int iPrefHeight, int iMaxHeight)
+{
+ wxSize szAdjusted(0, 0);
+ wxSize szItem = GetItemSize();
+ int iColumns = GetColumns();
+ int iRows = GetRows();
+
+ szAdjusted.x = szItem.x * iColumns;
+
+ int iRowsFit = iPrefHeight / szItem.y + 1;
+
+ // Check if we fit the maximum height.
+ int iHeight = iRowsFit * szItem.y;
+ if (iHeight > iMaxHeight)
+ iHeight = --iRowsFit * szItem.y;
+
+ // We must show at least one row.
+ iRowsFit = std::max(iRowsFit, 1);
+
+ // No point in showing more rows than we have.
+ iRowsFit = std::min(iRowsFit, iRows);
+
+ szAdjusted.y = iRowsFit * szItem.y;
+
+ // Check if a slider is required.
+ if (iRowsFit < iRows)
+ szAdjusted.x += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
+
+ // Take into account the border.
+ szAdjusted.x += 2;
+ szAdjusted.y += 2;
+
+
+ return szAdjusted;
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::InvalidateItem
+Author : Mikhail Tatarnikov
+Purpose : Requests repaint of an item.
+Returns : void
+Exceptions:
+Parameters: [in] int iItem - an item to repaint.
+Notes :
+******************************************************************************/
+void wxGridComboPopup::InvalidateItem(int iItem)
+{
+ if (iItem == -1)
+ return;
+
+ int iX = 0;
+ int iY = 0;
+
+ wxRect rcItem = GetItemRect(iItem);
+
+ ClientToScrolledVirtual(&iX, &iY);
+ rcItem.x -= iX;
+ rcItem.y -= iY;
+
+ Refresh(false, &rcItem);
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::OnDraw
+Author : Mikhail Tatarnikov
+Purpose : The default implementation of drawing.
+Returns : void
+Exceptions:
+Parameters: [in] wxDC& dc - device context of the control to paint to.
+Notes : Breaks the control to separate items and sends a request for painting
+ each item via DrawItem pure virtual function.
+******************************************************************************/
+void wxGridComboPopup::OnDraw(wxDC& dc)
+{
+ wxRect rcInvalid = GetUpdateClientRect();
+ ClientToScrolledVirtual(&(rcInvalid.x), &(rcInvalid.y));
+
+ // Iterate over all items, simply figing out whether we
+ // need to update it or not.
+ // TODO: optimize - iterate over visible items only.
+ int iItemsNum = GetColumns() * GetRows();
+ for (int i = 0; i < iItemsNum; ++i)
+ {
+ // Calculate the area of the current item.
+ wxRect rcItem = GetItemRect(i);
+
+ // Check if the item should be updated.
+ if (!rcItem.Intersects(rcInvalid))
+ continue;
+
+ // Check if the item is selected or highlighted.
+ int iFlags = 0;
+ if (i == GetSelected())
+ iFlags |= keSelected;
+
+ if (i == m_iHighlighed)
+ iFlags |= keHighlight;
+
+ DrawItem(dc, rcItem, i, iFlags);
+
+ }
+}
+
+/******************************************************************************
+Function : wxGridComboPopup::PaintComboControl
+Author : Mikhail Tatarnikov
+Purpose : Paints an item in the combo control itself.
+Returns : void
+Exceptions:
+Parameters: [in] wxDC& dc - dc to paint to;
+ [in] const wxRect& rect - area for painting.
+Notes : Uses DrawItem pure virtual function.
+******************************************************************************/
+void wxGridComboPopup::PaintComboControl(wxDC& dc, const wxRect& rect)
+{
+ int iSelected = GetSelected();
+ if (iSelected == -1)
+ {
+ wxComboPopup::PaintComboControl(dc, rect);
+ return;
+ }
+
+ int iFlags = keComboControl;
+ if (!m_pCombo->IsEnabled())
+ iFlags |= keDisabled;
+
+ DrawItem(dc, rect, iSelected, iFlags);
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::DrawItem
+Author : Mikhail Tatarnikov
+Purpose : Draws item based on row and column
+Returns : void
+Exceptions:
+Parameters: [in] wxDC& dc - device context to paint to;
+ [in] wxRect& rcRect - the item position;
+ [in] int iRow - element's row;
+ [in] int iCol - element's column;
+ [in] bool bSelected - indicate whether the item is selected or not.
+Notes : Calculates the item index and dispatch the call to descendants via
+ DrawItem pure virtual function.
+******************************************************************************/
+void wxGridComboPopup::DrawItem(wxDC& dc, const wxRect& rcRect, int iRow, int iCol, bool bSelected)
+{
+ int iItem = iRow * GetColumns() + iCol;
+
+ int iFlags = 0;
+ if (bSelected)
+ iFlags |= keSelected;
+
+ DrawItem(dc, rcRect, iItem, iFlags);
+}
+
+
+/******************************************************************************
+Function : wxGridComboPopup::UpdateColumnsNum
+Author : Mikhail Tatarnikov
+Purpose : Updates the coumn number.
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridComboPopup::UpdateColumnsNum()
+{
+ UpdateScrollers();
+}
+
+
+
+
+
+
+
+
+
+
+IMPLEMENT_DYNAMIC_CLASS(wxGridCombo, wxComboCtrl)
+
+/******************************************************************************
+Function : wxGridCombo::Init
+Author : Mikhail Tatarnikov
+Purpose : Initialization routine
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridCombo::Init()
+{
+ m_iColumns = 1; // A standard list box with one column by default.
+ m_iSelected = -1;
+}
+
+wxGridCombo::wxGridCombo(wxWindow* pwndParent,
+ wxWindowID wiID,
+ const wxPoint& crptPos,
+ const wxSize& crszSize,
+ long lStyle,
+ const wxString& crstrName)
+{
+ Init();
+ Create(pwndParent, wiID, crptPos, crszSize, lStyle, crstrName);
+}
+
+/******************************************************************************
+Function : wxGridCombo::Create
+Author : Mikhail Tatarnikov
+Purpose : Creates the control
+Returns : bool - see wxWindow::Create
+Exceptions:
+Parameters: see wxWindow::Create.
+Notes :
+******************************************************************************/
+bool wxGridCombo::Create(wxWindow* pwndParent,
+ wxWindowID wiID,
+ const wxPoint& crptPos,
+ const wxSize& crszSize,
+ long lStyle,
+ const wxString& crstrName)
+{
+ if (!wxComboCtrl::Create(pwndParent, wiID, wxEmptyString, crptPos, crszSize, lStyle, wxDefaultValidator, crstrName))
+ return false;
+
+ return true;
+}
+
+/******************************************************************************
+Function : wxGridCombo::~wxGridCombo
+Author : Mikhail Tatarnikov
+Purpose : Destroys the object
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+wxGridCombo::~wxGridCombo()
+{
+ DeleteUserData();
+}
+
+/******************************************************************************
+Function : wxGridCombo::DeleteUserData
+Author : Mikhail Tatarnikov
+Purpose : Deletes all user data for itmes.
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridCombo::DeleteUserData()
+{
+ std::vector<CGridComboUserData*>::const_iterator citCur = m_vecUserData.begin();
+ for (; citCur != m_vecUserData.end(); ++citCur)
+ delete *citCur;
+
+ m_vecUserData.clear();
+}
+
+/******************************************************************************
+Function : wxGridCombo::AddItem
+Author : Mikhail Tatarnikov
+Purpose : Adds a new item (appended to the end)
+Returns : void
+Exceptions:
+Parameters: [in] CGridComboUserData* pUserData - a new item to add.
+Notes :
+******************************************************************************/
+void wxGridCombo::AddItem(CGridComboUserData* pUserData)
+{
+ m_vecUserData.push_back(pUserData);
+
+ wxGridComboPopup* pPopup = dynamic_cast<wxGridComboPopup*>(GetPopupControl());
+ if (pPopup)
+ pPopup->UpdateScrollers();
+}
+
+/******************************************************************************
+Function : wxGridCombo::Clear
+Author : Mikhail Tatarnikov
+Purpose : Removes all elements from the combobox
+Returns : void
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+void wxGridCombo::Clear()
+{
+ DeleteUserData();
+
+ wxGridComboPopup* pPopup = dynamic_cast<wxGridComboPopup*>(GetPopupControl());
+ if (pPopup)
+ pPopup->UpdateScrollers();
+}
+
+
+/******************************************************************************
+Function : wxGridCombo::GetUserData
+Author : Mikhail Tatarnikov
+Purpose : Retrieves user data associated with an item.
+Returns : CGridComboUserData* - the user data for the item, if any.
+Exceptions:
+Parameters: [in] int iIndex - index of the item to retrieve associated user data for.
+Notes :
+******************************************************************************/
+CGridComboUserData* wxGridCombo::GetUserData(int iIndex)
+{
+ if (iIndex < GetItemsNum())
+ return m_vecUserData[iIndex];
+
+ return NULL;
+}
+
+/******************************************************************************
+Function : wxGridCombo::GetRows
+Author : Mikhail Tatarnikov
+Purpose : Calculates the number of rows.
+Returns : int - the number of rows.
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+int wxGridCombo::GetRows()
+{
+ // Calculate the full rows based on the item number and the columns requested.
+ // Then add a partial row if required.
+ int iRows = GetItemsNum() / GetColumns();
+ if (GetItemsNum() % GetColumns() != 0)
+ iRows++;
+
+ return iRows;
+}
+
+
+/******************************************************************************
+Function : wxGridCombo::SetItemSize
+Author : Mikhail Tatarnikov
+Purpose : Sets the item size
+Returns : void
+Exceptions:
+Parameters: [in] wxSize szItem - a new size for items.
+Notes : All items have the same size.
+******************************************************************************/
+void wxGridCombo::SetItemSize(wxSize szItem)
+{
+ m_szItem = szItem;
+
+ wxGridComboPopup* pPopup = dynamic_cast<wxGridComboPopup*>(GetPopupControl());
+ if (!pPopup)
+ return;
+
+ pPopup->UpdateScrollers();
+}
+
+
+/******************************************************************************
+Function : wxGridCombo::SetColumns
+Author : Mikhail Tatarnikov
+Purpose : Sets the number of columns
+Returns : void
+Exceptions:
+Parameters: [in] int iCols - new column number.
+Notes :
+******************************************************************************/
+void wxGridCombo::SetColumns(int iCols)
+{
+ m_iColumns = iCols;
+
+ wxGridComboPopup* pPopup = dynamic_cast<wxGridComboPopup*>(GetPopupControl());
+ if (!pPopup)
+ return;
+
+ pPopup->UpdateColumnsNum();
+}
+
+
+/******************************************************************************
+Function : wxGridCombo::SetSelected
+Author : Mikhail Tatarnikov
+Purpose : Selects an item.
+Returns : void
+Exceptions:
+Parameters: [in] int iItem - an item to select, -1 for unselecting.
+Notes :
+******************************************************************************/
+void wxGridCombo::SetSelected(int iItem)
+{
+ // Check if we actually changed anything.
+ if (GetSelected() == iItem)
+ return;
+
+ wxGridComboPopup* pPopup = dynamic_cast<wxGridComboPopup*>(GetPopupControl());
+ if (!pPopup)
+ return;
+
+ pPopup->ChangeSelection(GetSelected(), iItem);
+
+ m_iSelected = iItem;
+
+ // Invalidate the combo control.
+ Refresh(false);
+}
+
+/******************************************************************************
+Function : wxGridCombo::GetSelected
+Author : Mikhail Tatarnikov
+Purpose : Gets the selected item
+Returns : int - the index of the selected item, -1 otherwise.
+Exceptions:
+Parameters: None
+Notes :
+******************************************************************************/
+int wxGridCombo::GetSelected() const
+{
+ return m_iSelected;
+}
Index: Trunk/XaraLX/wxXtra/xh_gridcombo.h
===================================================================
--- Trunk/XaraLX/wxXtra/xh_gridcombo.h (revision 0)
+++ Trunk/XaraLX/wxXtra/xh_gridcombo.h (revision 1703)
@@ -0,0 +1,38 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/xrc/xh_odcombo.h
+// Purpose: XML resource handler for wxOwnerDrawnComboBox
+// Author: Alex Bligh - based on wx/xrc/xh_combo.h
+// Created: 2006/06/19
+// RCS-ID: $Id: xh_odcombo.h,v 1.1 2006/06/20 12:26:05 ABX Exp $
+// Copyright: (c) 2006 Alex Bligh
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_XH_GRIDCOMBO_H_
+#define _WX_XH_GRIDCOMBO_H_
+
+
+#include <wx/xrc/xmlres.h>
+
+
+/*************************************************************************
+Class : wxGridComboXmlHandler
+Base Class : public wxXmlResourceHandler
+Author : Mikhail Tatarnikov
+Description : Creator class for wxGridCombo based on XML resources.
+Pure Virtual : None
+Known Issues : None
+Usage Notes : None
+Override Notes: None
+**************************************************************************/
+class WXDLLIMPEXP_XRC wxGridComboXmlHandler : public wxXmlResourceHandler
+{
+DECLARE_DYNAMIC_CLASS(wxGridComboXmlHandler)
+public:
+ wxGridComboXmlHandler();
+ virtual wxObject *DoCreateResource();
+ virtual bool CanHandle(wxXmlNode *node);
+};
+
+
+#endif // _WX_XH_GRIDCOMBO_H_
Index: Trunk/XaraLX/wxXtra/xh_gridcombo.cpp
===================================================================
--- Trunk/XaraLX/wxXtra/xh_gridcombo.cpp (revision 0)
+++ Trunk/XaraLX/wxXtra/xh_gridcombo.cpp (revision 1703)
@@ -0,0 +1,98 @@
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_XRC
+
+#include "xh_gridcombo.h"
+
+#include "gridcombo.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxGridComboXmlHandler, wxXmlResourceHandler)
+
+wxGridComboXmlHandler::wxGridComboXmlHandler()
+ :wxXmlResourceHandler()
+{
+ XRC_ADD_STYLE(wxCB_SIMPLE);
+ XRC_ADD_STYLE(wxCB_READONLY);
+ XRC_ADD_STYLE(wxCB_DROPDOWN);
+
+ AddWindowStyles();
+}
+
+/******************************************************************************
+Function : *wxGridComboXmlHandler::DoCreateResource
+Author : Mikhail Tatarnikov
+Purpose : Creates new wxGridCombo and initializes it with values from the
+ resources.
+Returns : wxObject* - the brand new initialized object.
+Exceptions: None
+Parameters: None
+Notes :
+******************************************************************************/
+wxObject* wxGridComboXmlHandler::DoCreateResource()
+{
+ XRC_MAKE_INSTANCE(pControl, wxGridCombo)
+
+ // Grid like stuff
+ if(HasParam(wxT("columns")))
+ {
+ pControl->SetColumns(GetLong(wxT("columns")));
+ }
+
+ if(HasParam(wxT("itemsize")))
+ {
+ wxSize sizItemSize = GetSize(wxT("itemsize"));
+ pControl->SetItemSize(sizItemSize);
+ }
+
+ pControl->Create(m_parentAsWindow,
+ GetID(),
+ GetPosition(), GetSize(),
+ GetStyle(),
+ GetName());
+
+
+ // ComboCtrl like stuff
+ wxSize ButtonSize=GetSize(wxT("buttonsize"));
+ if (ButtonSize != wxDefaultSize)
+ pControl->SetButtonPosition(ButtonSize.GetWidth(), ButtonSize.GetHeight());
+
+ SetupWindow(pControl);
+
+ return pControl;
+}
+
+/******************************************************************************
+Function : wxGridComboXmlHandler::CanHandle
+Author : Mikhail Tatarnikov
+Purpose : Checks if an XML node corresponds to our wxGridCombo control.
+Returns : bool - true if wxGridCombo can be created from the node, false otherwise.
+Exceptions:
+Parameters: [in] wxXmlNode* node - resource XML node to test.
+Notes :
+******************************************************************************/
+bool wxGridComboXmlHandler::CanHandle(wxXmlNode* node)
+{
+#if wxCHECK_VERSION(2,7,0)
+
+ return (IsOfClass(node, wxT("wxGridCombo")));
+
+#else
+
+// Avoid GCC bug - this fails on certain GCC 3.3 and 3.4 builds for an unknown reason
+// it is believed to be related to the fact IsOfClass is inline, and node->GetPropVal
+// gets passed an invalid "this" pointer. On 2.7, the function is out of line, so the
+// above should work fine. This code is left in here so this file can easily be used
+// in a version backported to 2.6. All we are doing here is expanding the macro
+
+ bool bOurClass = node->GetPropVal(wxT("class"), wxEmptyString) == wxT("wxGridCombo");
+ return bOurClass;
+#endif
+}
+
+#endif // wxUSE_XRC
Index: Trunk/XaraLX/wxXtra/gridcombo.h
===================================================================
--- Trunk/XaraLX/wxXtra/gridcombo.h (revision 0)
+++ Trunk/XaraLX/wxXtra/gridcombo.h (revision 1703)
@@ -0,0 +1,213 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: gridcombo.h
+// Purpose: A grid grid combo
+// Author: Mikhail Tatarnikov
+// Modified by:
+// Created: 2006-08-16
+// RCS-ID: $Id: $
+// Copyright: (c) 2006 Xara Ltd
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WXXTRA_GRIDCOMBO_H_
+#define _WXXTRA_GRIDCOMBO_H_
+
+#include <wx/defs.h>
+//#include <wx/grid.h>
+#include <vector>
+
+#if wxUSE_COMBOCTRL
+#include <wx/combo.h>
+#else
+#include "combog.h"
+#endif
+
+
+class wxGridCombo;
+
+
+
+/*************************************************************************
+Class : wxGridComboPopup
+Base Class : public wxScrolledWindow
+ public wxComboPopup
+Author : Mikhail Tatarnikov
+Description : A base class for wxComboPopup implementation implementing
+ a grid-like popup (multicolmn as opposint to a standard one-column
+ list box popup).
+Pure Virtual : DrawItem - you have to override it and do the actuall cell paint in it.
+Known Issues : None
+Usage Notes : All the information that pertain to the control as a whole (a combobox and popup)
+ is stored in the combobox itself. A number of access functions (e.g. GetColumns)
+ are provided.
+ An item can be in selected or highlighted (when the mouse is hovered over the item)
+ state.
+Override Notes: None
+**************************************************************************/
+class wxGridComboPopup : public wxScrolledWindow,
+ public wxComboPopup
+{
+ friend class wxGridCombo;
+public:
+ enum EDrawFlags
+ {
+ keSelected = 0x0001, // The item is selected.
+ keHighlight = 0x0002, // The item is hovered.
+ keComboControl = 0x0004, // The paint the item in the combo control itself.
+ keDisabled = 0x0008 // The item is disabled. For now can be applied for the combo
+ // control itself only.
+ };
+
+public:
+
+ wxGridComboPopup(wxGridCombo* pCombo);
+
+ virtual void Init();
+ virtual bool Create(wxWindow* pwndParent);
+
+ virtual void OnShow();
+ virtual wxSize GetAdjustedSize(int iMinWidth, int iPrefHeight, int iMaxHeight);
+ virtual wxWindow* GetControl() {return this;}
+
+ // Drawing functions.
+ virtual void DrawItem(wxDC& dc, const wxRect& rect, int iItem, int iFlags) = 0;
+ virtual void PaintComboControl(wxDC& dc, const wxRect& rect);
+
+ virtual void SetSelected(int iItem);
+ virtual int GetSelected() const;
+
+
+ // Helper function
+ inline int GetColumns() const;
+ inline int GetRows() const;
+ inline int GetItemsNum() const;
+ inline wxSize GetItemSize() const;
+
+
+ // Gets displayed string representation of the value.
+ // Since we are owner-drawn control, the string doen't matter much.
+ virtual wxString GetStringValue() const {return wxString();}
+
+protected:
+ virtual void DrawItem(wxDC& dc, const wxRect& rect, int iCol, int iRow, bool bSelected);
+ virtual void UpdateScrollers();
+ virtual void UpdateColumnsNum();
+ virtual void ChangeSelection(int iOldSelected, int iNewSelected);
+ virtual void SendComboBoxEvent(int iSelection);
+
+ wxRect GetItemRect(int iItem);
+ wxPoint ItemToGrid(int iItem);
+ int ItemFromPoint(wxPoint ptClient);
+ void InvalidateItem(int iItem);
+ void ClientToScrolledVirtual(int* pX, int* pY);
+
+ // Closes the popup and sends notig
+ void DismissWithEvent();
+
+ // Message handlers.
+ virtual void OnDraw(wxDC& dc);
+ void OnSize(wxSizeEvent& event);
+ void OnMouseMove(wxMouseEvent& event);
+ void OnKey(wxKeyEvent& event);
+ void OnLeftClick(wxMouseEvent& event);
+ void OnTimer(wxTimerEvent& event);
+
+protected:
+ wxGridCombo* m_pCombo;
+ int m_iHighlighed;
+ wxTimer m_tmrHighlited; // Need a timer to spot the moment the mouse leaves popup (to dehighlight an item).
+private:
+ DECLARE_EVENT_TABLE()
+};
+
+
+
+
+
+
+
+
+
+
+
+
+struct CGridComboUserData
+{
+ virtual ~CGridComboUserData(){};
+};
+
+
+
+/*************************************************************************
+Class : wxGridCombo
+Base Class : public wxComboCtrl
+Author : Mikhail Tatarnikov
+Description : wxWidgit control extension that implements grid-like behaivor. Uses wxGridComboPopup
+ or its derivitives.
+Pure Virtual : None
+Known Issues : None
+Usage Notes : None
+Override Notes:
+**************************************************************************/
+class WXDLLIMPEXP_ADV wxGridCombo : public wxComboCtrl
+{
+// friend class wxGridComboPopup;
+public:
+
+ wxGridCombo(){Init();}
+
+ wxGridCombo(wxWindow* pwndParent,
+ wxWindowID wiID = wxID_ANY,
+ const wxPoint& crptPos = wxDefaultPosition,
+ const wxSize& crszSize = wxDefaultSize,
+ long lStyle = 0,
+ const wxString& crstrName = wxT("wxSliderComboBox"));
+
+ bool Create(wxWindow* pwndParent,
+ wxWindowID wiID = wxID_ANY,
+ const wxPoint& crptPos = wxDefaultPosition,
+ const wxSize& crszSize = wxDefaultSize,
+ long lStyle = 0,
+ const wxString& crstrName = wxT("wxSliderComboBox"));
+
+ virtual ~wxGridCombo();
+
+
+ virtual void AddItem(CGridComboUserData* pUserData);
+ virtual CGridComboUserData* GetUserData(int iIndex);
+
+ virtual void Clear();
+ virtual void DeleteUserData();
+
+
+ void SetColumns(int iCols);
+ int GetColumns() const {return m_iColumns;}
+ int GetRows();
+
+ void SetSelected(int iSelected);
+ int GetSelected() const;
+
+ int GetItemsNum() const {return m_vecUserData.size();}
+
+ void SetItemSize(wxSize szItem);
+ wxSize GetItemSize() const {return m_szItem;}
+
+
+protected:
+ void Init();
+
+protected:
+
+ std::vector<CGridComboUserData*> m_vecUserData;
+
+private:
+ int m_iColumns;
+
+ int m_iSelected;
+
+ wxSize m_szItem; // The item size. In grid we can have items with the same size only. TODO: allow rows/columns with different sizes?
+
+ DECLARE_DYNAMIC_CLASS(wxGridCombo)
+};
+
+#endif //_WXXTRA_GRIDCOMBO_H_
Xara