|
From: <arn...@us...> - 2008-02-07 22:59:09
|
Revision: 992
http://dcplusplus.svn.sourceforge.net/dcplusplus/?rev=992&view=rev
Author: arnetheduck
Date: 2008-02-07 14:59:03 -0800 (Thu, 07 Feb 2008)
Log Message:
-----------
Fancy menus, language setting fix
Modified Paths:
--------------
dcplusplus/trunk/smartwin/include/smartwin/WidgetFactoryPlatformSmartWinDesktop.h
dcplusplus/trunk/smartwin/include/smartwin/widgets/WidgetMenuExtended.h
dcplusplus/trunk/win32/AppearancePage.cpp
dcplusplus/trunk/win32/DCPlusPlus.rc
dcplusplus/trunk/win32/MainWindow.cpp
dcplusplus/trunk/win32/MainWindow.h
dcplusplus/trunk/win32/PropPage.cpp
dcplusplus/trunk/win32/PropPage.h
dcplusplus/trunk/win32/resource.h
Modified: dcplusplus/trunk/smartwin/include/smartwin/WidgetFactoryPlatformSmartWinDesktop.h
===================================================================
--- dcplusplus/trunk/smartwin/include/smartwin/WidgetFactoryPlatformSmartWinDesktop.h 2008-02-06 09:37:07 UTC (rev 991)
+++ dcplusplus/trunk/smartwin/include/smartwin/WidgetFactoryPlatformSmartWinDesktop.h 2008-02-07 22:59:03 UTC (rev 992)
@@ -56,14 +56,12 @@
/// RichEditBox object type.
typedef typename WidgetRichTextBox::ObjectType WidgetRichTextBoxPtr;
-#ifdef PORT_ME
/// ExtendedMenu class type.
- typedef SmartWin::WidgetMenuExtended< EventHandlerClass > WidgetMenuExtended;
+ typedef SmartWin::WidgetMenuExtended WidgetMenuExtended;
/// ExtendedMenu object type.
typedef typename WidgetMenuExtended::ObjectType WidgetMenuExtendedPtr;
-#endif
-
+
/// ChooseFont class and object type.
typedef SmartWin::WidgetChooseFont< SmartWin::Widget > WidgetChooseFont;
@@ -115,17 +113,15 @@
return WidgetCreator< WidgetRichTextBox >::attach( this, id );
}
-#ifdef PORT_ME
/// Creates an Extended Menu
/** The returned object is of type std::tr1::shared_ptr< WidgetMenuExtended >, but
* you should use the typedef WidgetMenuExtendedPtr and not <br>
* the shared_ptr itself since this may change in future releases.
*/
- WidgetMenuExtendedPtr createExtendedMenu()
+ WidgetMenuExtendedPtr createExtendedMenu(const typename WidgetMenuExtended::Seed& cs = WidgetMenuExtended::Seed())
{
- return WidgetCreator< WidgetMenuExtended >::create( this );
+ return WidgetCreator< WidgetMenuExtended >::create( this, cs );
}
-#endif
/// Creates a Tool Bar and returns a pointer to it.
/** DON'T delete the returned pointer!!!
Modified: dcplusplus/trunk/smartwin/include/smartwin/widgets/WidgetMenuExtended.h
===================================================================
--- dcplusplus/trunk/smartwin/include/smartwin/widgets/WidgetMenuExtended.h 2008-02-06 09:37:07 UTC (rev 991)
+++ dcplusplus/trunk/smartwin/include/smartwin/widgets/WidgetMenuExtended.h 2008-02-07 22:59:03 UTC (rev 992)
@@ -5,14 +5,14 @@
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met :
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the SmartWin++ nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the SmartWin++ nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -29,10 +29,10 @@
#ifndef WidgetMenuExtended_h
#define WidgetMenuExtended_h
+#include "../Application.h"
#include "../BasicTypes.h"
#include "../CanvasClasses.h"
-#include <boost/cast.hpp>
-#ifdef PORT_ME
+
namespace SmartWin
{
// begin namespace SmartWin
@@ -67,9 +67,9 @@
/// \ingroup GlobalStuff
// MenuItemDataPtr type, contains rendering data for e.g. WidgetMenuExtended
/** Helps easily create color values and so on for a WidgetMenuExtended item! <br>
- * Each Menu Item can have different colors and so on, use this smart pointer to set
- * those values!
- */
+* Each Menu Item can have different colors and so on, use this smart pointer to set
+* those values!
+*/
typedef std::tr1::shared_ptr< MenuItemData > MenuItemDataPtr;
namespace private_
@@ -101,10 +101,10 @@
// Wrapper Constructor
ItemDataWrapper( HMENU owner, int itemIndex, MenuItemDataPtr itemData, bool isTitleItem = false )
- : menu( owner )
- , index( itemIndex )
- , isMenuTitleItem( isTitleItem )
- , data( itemData )
+ : menu( owner )
+ , index( itemIndex )
+ , isMenuTitleItem( isTitleItem )
+ , data( itemData )
{}
~ItemDataWrapper()
@@ -114,8 +114,8 @@
/// Struct for coloring different areas of WidgetMenuExtended
/** Contains the different color settings of the WidgetMenuExtended <br>
- * Default values to constructor makes menu look roughly like MSVC++7.1 menus
- */
+* Default values to constructor makes menu look roughly like MSVC++7.1 menus
+*/
struct MenuColorInfo
{
/// Menu color
@@ -141,9 +141,9 @@
/// Constructs MenuColorInfo objects
/** If all the default arguments are used it will construct an object making
- * menus look roughly like they do in MSVC++ 7.1 <br>
- * Pass your own arguments to construct other color effects
- */
+ * menus look roughly like they do in MSVC++ 7.1 <br>
+ * Pass your own arguments to construct other color effects
+ */
MenuColorInfo( COLORREF menuColor = ColorUtilities::darkenColor( ::GetSysColor( COLOR_WINDOW ), 0.02 ),
COLORREF stripColor = ColorUtilities::darkenColor( ::GetSysColor( COLOR_3DFACE ), 0.02 ),
COLORREF titleColor = ColorUtilities::darkenColor( ::GetSysColor( COLOR_MENUBAR ), 0.1 ),
@@ -161,905 +161,228 @@
{}
};
-// ///////////////////////////////////////////////////////////////////////////////
-// Default Menu Renderer, create your own by copying this and modyfying
-// if you want your menus to be different!
-// Basic process is to add Event Handlers for onDrawItem and onMeasureItem
-// ///////////////////////////////////////////////////////////////////////////////
-template< class MenuType >
-class DefaultMenuRenderer
-{
-public:
- /// Rendering settting settings
- static const int borderGap = 3; /// Gap between the border and item
- static const int pointerGap = 5; /// Gap between item text and sub - menu pointer
- static const int textIconGap = 8; /// Gap between text and icon
- static const int textBorderGap = 4; /// Gap between text and rectangel border
- static const int separatorHeight = 8; /// Defines default height for rectangle containing separator
- static const int minSysMenuItemWidth = 130; /// Minimum width for system menu items
-
- static Point defaultImageSize; /// Default image size, used when no image is available
-
- // Default callback for WM_MEASUREITEM message processing
- static bool measureItem( EventHandlerClass * parent, typename MenuType::ObjectType menu, MEASUREITEMSTRUCT * measureInfo )
- {
- if ( measureInfo->CtlType != ODT_MENU ) // if not intended for us
- return false;
-
- // get data wrapper
- private_::ItemDataWrapper * wrapper = reinterpret_cast< private_::ItemDataWrapper * >( measureInfo->itemData );
-
- xAssert( wrapper != 0, _T( "Unsupported menu item type in measureItem()" ) );
-
- // this will contain item size
- UINT & itemWidth = measureInfo->itemWidth;
- UINT & itemHeight = measureInfo->itemHeight;
-
- // init struct for item info
- MENUITEMINFO info;
- memset( & info, 0, sizeof( MENUITEMINFO ) );
- info.cbSize = sizeof( MENUITEMINFO );
-
- // set up flags
- info.fMask = MIIM_FTYPE | MIIM_DATA | MIIM_CHECKMARKS | MIIM_STRING;
-
- // get menu handle
- HMENU handle = reinterpret_cast< HMENU >( menu->handle() );
-
- // try to get item info
- if ( ::GetMenuItemInfo( handle, wrapper->index, TRUE, & info ) == FALSE )
- throw xCeption ( _T( "Couldn't get item info in measureItem()" ) );
-
- // check if item is owner drawn
- xAssert( ( info.fType & MFT_OWNERDRAW ) != 0, _T( "Not owner - drawn item encountered in measureItem()" ) );
-
- // check if separator
- if ( info.fType & MFT_SEPARATOR )
- {
- itemWidth = 60;
- itemHeight = separatorHeight;
- return true;
- }
-
- // are we processing menu bar ?
- bool isMenuBar = ::GetMenu( parent->handle() ) == handle;
-
- // compute text width and height by simulating write to dc
- // get its DC
- HDC hdc = ::GetDC( menu->getParent()->handle() );
-
- // get the item data
- MenuItemDataPtr data = wrapper->data;
- xAssert( data != 0, _T( "Couldn't find item data in measureItem()" ) );
-
- // get item text
- const int length = info.cch + 1;
- std::vector< TCHAR > buffer ( length );
- int count = ::GetMenuString( handle, wrapper->index, & buffer[0], length, MF_BYPOSITION );
- SmartUtil::tstring itemText ( buffer.begin(), buffer.begin() + count );
-
- // now get text extents
- SIZE textSize;
- memset( & textSize, 0, sizeof( SIZE ) );
-
- HGDIOBJ oldFont = ::SelectObject( hdc, data->Font->getHandle() );
- ::GetTextExtentPoint32( hdc, itemText.c_str(), ( int ) itemText.size(), & textSize );
- ::SelectObject( hdc, oldFont );
-
- // release DC
- ::ReleaseDC( menu->handle(), hdc );
-
- // adjust item size
- itemWidth = textSize.cx + borderGap;
- itemHeight = textSize.cy + borderGap;
-
- // check to see if item has an image
- Point imageSize = data->Image->getBitmapSize();
-
- // this will contain checked/unchecked image size
- Point checkImageSize;
-
- // if item has check/unchecked state images, then get their sizes
- if ( ( info.hbmpChecked != NULL ) && ( info.hbmpUnchecked != NULL ) )
- checkImageSize = ( info.fState & MFS_CHECKED ) == 0
- ? Bitmap::getBitmapSize( info.hbmpUnchecked )
- : Bitmap::getBitmapSize( info.hbmpChecked );
-
- // take the maximum of all available images or set default image size
- imageSize.x = (std::max)( imageSize.x, checkImageSize.x );
- imageSize.y = (std::max)( imageSize.y, checkImageSize.y );
-
- bool hasImage = ( imageSize.x != 0 ) && ( imageSize.y != 0 );
-
- // set default image size if no image is available
- if ( !hasImage )
- {
- imageSize.x = (std::max)( defaultImageSize.x, (std::max)( imageSize.x, checkImageSize.x ) );
- imageSize.y = (std::max)( defaultImageSize.y, (std::max)( imageSize.y, checkImageSize.y ) );
- }
-
- // adjust default image size
- defaultImageSize.x = (std::max)( defaultImageSize.x, imageSize.x );
- defaultImageSize.y = (std::max)( defaultImageSize.y, imageSize.y );
-
- // adjust width
- if ( !isMenuBar || // if not menu bar item
- ( isMenuBar && hasImage ) ) // or menu bar item with image
- {
- // adjust item width
- itemWidth += imageSize.x + textIconGap + pointerGap;
-
- // adjust item height
- itemHeight = (std::max)( itemHeight, ( UINT ) imageSize.y + borderGap );
- }
-
- // adjust width for system menu items
- if ( menu->isSysMenu )
- itemWidth = (std::max)( ( UINT ) minSysMenuItemWidth, itemWidth );
-
- // adjust width for sidebar
- if ( menu->drawSidebar )
- {
- // get title text extents
- SIZE textSize;
- memset( & textSize, 0, sizeof( SIZE ) );
-
- ::GetTextExtentPoint32( hdc, menu->itsTitle.c_str(), ( int ) menu->itsTitle.size(), & textSize );
-
- itemWidth += textSize.cy;
- }
-
- // adjust item height
- itemHeight = (std::max)( itemHeight, ( UINT )::GetSystemMetrics( SM_CYMENU ) );
- return true;
- }
-
- // Default callback for WM_DRAWITEM message processing
- static bool drawItem( EventHandlerClass * parent, typename MenuType::ObjectType menu, int controlID, const DRAWITEMSTRUCT & drawInfo )
- {
- if ( ( controlID != 0 ) || ( drawInfo.CtlType != ODT_MENU ) ) // if not intended for us
- return false;
-
- // setup colors
- MenuColorInfo colorInfo = menu->itsColorInfo;
- COLORREF colorMenuBar = colorInfo.colorMenuBar;
- COLORREF colorTitle = colorInfo.colorTitle;
- COLORREF colorMenuDraw = colorInfo.colorMenu; // color for drawing menu
- COLORREF colorFillHighlighted = ColorUtilities::lightenColor( colorInfo.colorHighlight, 0.7 );
-
- // get menu handle
- HMENU handle = reinterpret_cast< HMENU >( menu->handle() );
-
- // if processing menu bar
- const bool isMenuBar = ::GetMenu( parent->handle() ) == handle;
-
- // change menu draw color for menubars
- if ( isMenuBar )
- colorMenuDraw = colorMenuBar;
-
- // get item data wrapper
- private_::ItemDataWrapper * wrapper = reinterpret_cast< private_::ItemDataWrapper * >( drawInfo.itemData );
- xAssert( wrapper != 0, _T( "Unsupported menu item in drawItem()" ) )
-
- // init struct for menu item info
- MENUITEMINFO info;
- memset( & info, 0, sizeof( MENUITEMINFO ) );
- info.cbSize = sizeof( MENUITEMINFO );
-
- // set flags
- info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_DATA | MIIM_STATE | MIIM_STRING;
-
- if ( ::GetMenuItemInfo( handle, wrapper->index, TRUE, & info ) == FALSE )
- throw xCeption ( _T( "Couldn't get menu item info in drawItem()" ) );
-
- // check if item is owner drawn
- xAssert( ( info.fType & MFT_OWNERDRAW ) != 0, _T( "Not a owner - drawn item in drawItem()" ) )
-
- // get item data
- MenuItemDataPtr data ( wrapper->data );
- xAssert( data != 0, _T( "Couldn't find item data in drawItem()" ) )
-
- // get state info
- bool isGrayed = ( drawInfo.itemState & ODS_GRAYED ) == ODS_GRAYED;
- bool isChecked = ( drawInfo.itemState & ODS_CHECKED ) == ODS_CHECKED;
- bool isDisabled = ( drawInfo.itemState & ODS_DISABLED ) == ODS_DISABLED;
- bool isSelected = ( drawInfo.itemState & ODS_SELECTED ) == ODS_SELECTED;
- bool isHighlighted = ( drawInfo.itemState & ODS_HOTLIGHT ) == ODS_HOTLIGHT;
-
- // this will contain item image
- HBITMAP image = NULL;
-
- // if checked/unchecked image is avaiable
- if ( ( info.hbmpChecked != NULL ) && ( info.hbmpUnchecked != NULL ) )
- image = isChecked ? info.hbmpChecked : info.hbmpUnchecked;
- else // get normal image
- image = data->Image->getBitmap();
-
- // this will contain image size
- Point imageSize = data->Image->getBitmapSize();
-
- if ( ( imageSize.x == 0 ) && ( imageSize.y == 0 ) ) // no image
- imageSize = defaultImageSize; // set default image size
-
- // compute strip width
- int stripWidth = imageSize.x + textIconGap;
-
- // prepare item rectangle
- Rectangle itemRectangle( drawInfo.rcItem.left, drawInfo.rcItem.top, // position
- drawInfo.rcItem.right - drawInfo.rcItem.left, // width
- drawInfo.rcItem.bottom - drawInfo.rcItem.top ); // height
-
- // setup buffered canvas
- BufferedCanvas< FreeCanvas > canvas( menu->handle(), drawInfo.hDC );
-
- // this will conain adjusted sidebar width
- int sidebarWidth = 0;
-
- // this will contain logical information
- // about title font
- LOGFONT lf;
- memset( & lf, 0, sizeof( LOGFONT ) );
-
- // this will contain adjusted(rotated) title font for sidebar
- HFONT titleFont = NULL;
-
- // get title font info and adjust item rectangle
- if ( menu->drawSidebar )
- {
- // get title font
- std::tr1::shared_ptr< Font > font = menu->itsTitleFont;
-
- // get logical info for title font
- ::GetObject( font->getHandle(), sizeof( LOGFONT ), & lf );
-
- // 90 degree rotation and bold
- lf.lfOrientation = lf.lfEscapement = 900;
-
- // create title font from logical info
- titleFont = ::CreateFontIndirect( & lf );
-
- // get title text size
- SIZE textSize;
- memset( & textSize, 0, sizeof( SIZE ) );
-
- HGDIOBJ oldFont = ::SelectObject( canvas.getDc(), titleFont );
- ::GetTextExtentPoint32( canvas.getDc(), menu->itsTitle.c_str(), ( int ) menu->itsTitle.size(), & textSize );
- ::SelectObject( canvas.getDc(), oldFont );
-
- // set sidebar width to text height
- sidebarWidth = textSize.cy;
-
- // adjust item rectangle and item background
- itemRectangle.pos.x += sidebarWidth;
- itemRectangle.size.x -= sidebarWidth;
- }
-
- // draw sidebar with menu title
- if ( ( drawInfo.itemAction & ODA_DRAWENTIRE ) && ( menu->drawSidebar ) && !menu->itsTitle.empty() )
- {
- // select title font and color
- HGDIOBJ oldFont = ::SelectObject ( canvas.getDc(), titleFont );
- COLORREF oldColor = canvas.setTextColor( colorInfo.colorTitleText );
-
- // set background mode to transparent
- bool oldMode = canvas.setBkMode( true );
-
- // get rect for sidebar
- RECT rect;
- ::GetClipBox( drawInfo.hDC, & rect );
- //rect.left -= borderGap;
-
- // set title rectangle
- Rectangle textRectangle( 0, 0, sidebarWidth, rect.bottom - rect.top );
-
- // draw background
- Brush brush( canvas, colorInfo.colorTitle );
- canvas.fillRectangle( textRectangle, brush );
-
- // draw title
- textRectangle.pos.y += 10;
- canvas.drawText( menu->itsTitle, textRectangle, DT_BOTTOM | DT_SINGLELINE );
-
- // clear
- canvas.setTextColor( oldColor );
- canvas.setBkMode( oldMode );
-
- // set back old font
- ::SelectObject( canvas.getDc(), oldFont );
- }
-
- // destroy title font
- ::DeleteObject( titleFont );
-
- // set item background
- if ( wrapper->isMenuTitleItem ) // for title
- {
- Brush brush( canvas, colorTitle );
- canvas.fillRectangle( itemRectangle, brush );
-
- // draw raised border
- RECT rc( itemRectangle );
- ::DrawEdge( canvas.getDc(), & rc, EDGE_RAISED, BF_RECT );
- }
- else // for normal items
- {
- Brush brush( canvas, colorMenuDraw );
- canvas.fillRectangle( itemRectangle, brush );
- }
-
- if ( isMenuBar && isSelected ) // draw selected menu bar item
- {
- // TODO: Simulate shadow
-
- // select pen for drawing broder
- // and brush for filling item
- COLORREF colorBorder = 0;
- Pen pen ( canvas, colorBorder );
- Brush brush ( canvas, ColorUtilities::lightenColor( colorMenuBar, 0.5 ) );
-
- canvas.rectangle( itemRectangle );
- } // end if
- else if ( ( isSelected || isHighlighted ) && !isDisabled ) // draw selected or highlighted menu item (if not inactive)
- {
- // select pen for drawing broder
- // and brush for filling item
- Pen pen ( canvas, colorInfo.colorHighlight );
- Brush brush ( canvas, colorFillHighlighted );
-
- canvas.rectangle( itemRectangle );
- } // end if
- else if ( !isMenuBar && !wrapper->isMenuTitleItem ) // draw strip bar for menu items (except menu title item)
- {
- // create rectangle for strip bar
- Rectangle stripRectangle ( itemRectangle );
- stripRectangle.size.x = stripWidth;
-
- // draw strip bar
- Brush brush( canvas, colorInfo.colorStrip );
- canvas.fillRectangle( stripRectangle, brush );
- } // end if
-
- if ( !isMenuBar && info.fType & MFT_SEPARATOR ) // draw separator
- {
- // set up separator rectangle
- Rectangle rectangle ( itemRectangle );
-
- // center in the item rectangle
- rectangle.pos.x += stripWidth + textIconGap;
- rectangle.pos.y += rectangle.size.y / 2 - 1;
-
- // select color
- Pen pen( canvas, ::GetSysColor( COLOR_GRAYTEXT ) );
-
- // draw separator
- canvas.moveTo( rectangle.pos.x, rectangle.pos.y );
- canvas.lineTo( rectangle.size.x, rectangle.pos.y );
- } // end if
- else // not a seperator, then draw item text and icon
- {
- // get item text
- const int length = info.cch + 1;
- std::vector< TCHAR > buffer( length );
- int count = ::GetMenuString( handle, wrapper->index, & buffer[0], length, MF_BYPOSITION );
- SmartUtil::tstring itemText( buffer.begin(), buffer.begin() + count );
-
- // index will contain accelerator position
- size_t index = itemText.find_last_of( _T( '\t' ) );
-
- // split item text to draw accelerator correctly
- SmartUtil::tstring text = itemText.substr( 0, index );
-
- // get accelerator
- SmartUtil::tstring accelerator;
-
- if ( index != itemText.npos )
- accelerator = itemText.substr( index + 1 );
-
- // set mode to transparent
- bool oldMode = canvas.setBkMode( true );
-
- // select item text color
- canvas.setTextColor( isGrayed ? ::GetSysColor( COLOR_GRAYTEXT ) : wrapper->isMenuTitleItem ? colorInfo.colorTitleText : data->TextColor );
-
- // Select item font if available
- FontPtr font( data->Font );
-
- HGDIOBJ oldFont = ::SelectObject( canvas.getDc(), font->getHandle() );
-
- if ( !isMenuBar && !wrapper->isMenuTitleItem && !itemText.empty() ) // if menu item
- {
- // compute text rectangle
- Rectangle textRectangle( itemRectangle );
-
- // adjust rectangle
- textRectangle.pos.x += stripWidth + textIconGap;
- textRectangle.size.x -= stripWidth + textIconGap + borderGap;
-
- canvas.drawText( text, textRectangle, DT_LEFT | DT_VCENTER | DT_SINGLELINE );
-
- // draw accelerator
- if ( !accelerator.empty() )
- canvas.drawText( accelerator, textRectangle, DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
- } // end if
- else if ( !itemText.empty() ) // draw menu bar item text
- {
- Rectangle textRectangle( itemRectangle );
-
- if ( image != NULL ) // has icon
- textRectangle.pos.x += textIconGap;
-
- canvas.drawText( text, textRectangle, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
- } // end if
-
- // set back old font
- ::SelectObject( canvas.getDc(), oldFont );
-
- // reset old mode
- canvas.setBkMode( oldMode );
-
- // set up image rectangle
- Rectangle imageRectangle( itemRectangle.pos, imageSize );
-
- // adjust icon rectangle
- imageRectangle.pos.x += ( stripWidth - imageSize.x ) / 2;
- imageRectangle.pos.y += ( itemRectangle.size.y - imageSize.y ) / 2;
-
- if ( image == NULL ) // drawing item without icon
- {
- if ( isChecked ) // needs checkmark
- {
- // draw the check mark or radio bullet
- // prepare background
- Brush brush( canvas, colorInfo.colorStrip );
- canvas.fillRectangle( imageRectangle, brush );
-
- // create memory DC and set bitmap on it
- HDC memoryDC = ::CreateCompatibleDC( canvas.getDc() );
- HGDIOBJ old = ::SelectObject( memoryDC, ::CreateCompatibleBitmap( canvas.getDc(), imageSize.x, imageSize.y ) );
-
- // draw into memory
- RECT rc( Rectangle( 0, 0, imageSize.x, imageSize.y ) );
- ::DrawFrameControl( memoryDC, & rc, DFC_MENU, ( info.fType & MFT_RADIOCHECK ) == 0 ? DFCS_MENUCHECK : DFCS_MENUBULLET );
-
- const int adjustment = 2; // adjustment for mark to be in the center
-
- // bit - blast into out canvas
- ::BitBlt( canvas.getDc(), imageRectangle.pos.x + adjustment, imageRectangle.pos.y, imageSize.x, imageSize.y, memoryDC, 0, 0, SRCAND );
-
- // delete memory dc
- ::DeleteObject( ::SelectObject( memoryDC, old ) );
- ::DeleteDC( memoryDC );
- }
- }
- else // drawing item with icon
- {
- if ( isSelected && !isDisabled ) // if selected and active, then imitate icon shadow
- {
- // adjust icon position for later drawing
- imageRectangle.pos.x -= 1;
- imageRectangle.pos.y -= 1;
-
- // setup brush for shadow emulation
- Brush brush( canvas, ColorUtilities::darkenColor( colorInfo.colorStrip, 0.7 ) );
-
- // draw the icon shadow
- Rectangle shadowRectangle( imageRectangle );
- shadowRectangle.pos.x += 2;
- shadowRectangle.pos.y += 2;
- canvas.drawBitmap( image, shadowRectangle, colorInfo.colorImageBackground, true );
- }
-
- // draw normal icon
- canvas.drawBitmap( image, imageRectangle, colorInfo.colorImageBackground, isGrayed );
- }
-
- if ( isChecked ) // draw surrounding rectangle for checked items
- {
- /*if ( image != NULL ) // adjust for icon
- iconRectangle = iconRectangle.shrink( 1.20 );*/
-
- // draw the surrounding rectangle
- Pen pen( canvas, colorInfo.colorHighlight );
- canvas.line( imageRectangle );
- }
- }
-
- // blast buffer into screen
- if ( ( drawInfo.itemAction & ODA_DRAWENTIRE ) && menu->drawSidebar ) // adjustment for sidebar
- {
- itemRectangle.pos.x -= sidebarWidth;
- itemRectangle.size.x += sidebarWidth;
- }
-
- canvas.blast( itemRectangle );
- return true;
- }
-};
-
-// Since this is a Dispatcher ONLY for Menus it CAN'T be a "non control", therefore
-// we DON'T need the partial specialization for it...
-template< class EventHandlerClass, class WidgetType, class MessageMapType >
-class WidgetMenuExtendedDispatcher
-{
- static EventHandlerClass * getParent( Widget * parentGiven )
- {
- Widget * tmpParent = parentGiven;
- EventHandlerClass * ptrMainParent;
- while ( true )
- {
- ptrMainParent = dynamic_cast< EventHandlerClass * >( tmpParent );
- if ( ptrMainParent != 0 )
- break;
- tmpParent = tmpParent->getParent();
- if ( 0 == tmpParent )
- throw xCeption( _T( "Serious error while trying to get MainWindow parent to menu, menu probably not attached to Main WidgetFactory..." ) );
- }
- return ptrMainParent;
- }
-
-public:
-#ifdef PORT_ME
- static HRESULT dispatch( private_::SignalContent & params )
- {
- EventHandlerClass * ptrMainParent = getParent( params.This->getParent() );
- typename WidgetType::menuExtendedVoidFunctionTakingUInt func =
- reinterpret_cast< typename WidgetType::menuExtendedVoidFunctionTakingUInt >( params.Function );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- func
- ( dynamic_cast< EventHandlerClass * >( 0 )
- , ptrThis
- , LOWORD( params.Msg.WParam )
- );
- return 1;
- }
-
- static HRESULT dispatchThis( private_::SignalContent & params )
- {
- EventHandlerClass * ptrMainParent = getParent( params.This->getParent() );
- typename WidgetType::itsVoidMenuExtendedFunctionTakingUInt func =
- reinterpret_cast< typename WidgetType::itsVoidMenuExtendedFunctionTakingUInt >( params.FunctionThis );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- ( ( * boost::polymorphic_cast< EventHandlerClass * >( ptrMainParent ) ).*func )
- ( ptrThis
- , LOWORD( params.Msg.WParam )
- );
- return 1;
- }
-
- static HRESULT dispatchDrawItem( private_::SignalContent & params )
- {
- // get callback
- typename WidgetType::boolDrawItemFunction func =
- reinterpret_cast< typename WidgetType::boolDrawItemFunction >( params.Function );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- // call the callback
- bool handled = func
- ( dynamic_cast< EventHandlerClass * >( params.This->getParent() )
- , ptrThis
- , params.Msg.WParam // control id
- , * reinterpret_cast< DRAWITEMSTRUCT * >( params.Msg.LParam )
- );
- return handled;
- }
-
- static HRESULT dispatchDrawItemThis( private_::SignalContent & params )
- {
- // get method pointer
- typename WidgetType::itsBoolDrawItemFunction func =
- reinterpret_cast< typename WidgetType::itsBoolDrawItemFunction >( params.FunctionThis );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- // call method
- bool handled = ( ( * boost::polymorphic_cast< EventHandlerClass * >( params.This->getParent() ) ).*func )
- ( ptrThis
- , params.Msg.WParam // control id
- , * reinterpret_cast< DRAWITEMSTRUCT * >( params.Msg.LParam )
- );
- return handled;
- }
-
- static HRESULT dispatchMeasureItem( private_::SignalContent & params )
- {
- // get callback
- typename WidgetType::boolMeasureItemFunction func =
- reinterpret_cast< typename WidgetType::boolMeasureItemFunction >( params.Function );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- // call the callback
- bool handled = func
- ( dynamic_cast< EventHandlerClass * >( params.This->getParent() )
- , ptrThis
- , reinterpret_cast< MEASUREITEMSTRUCT * >( params.Msg.LParam )
- );
- return handled;
- }
-
- static HRESULT dispatchMeasureItemThis( private_::SignalContent & params )
- {
- // get method pointer
- typename WidgetType::itsBoolMeasureItemFunction func =
- reinterpret_cast< typename WidgetType::itsBoolMeasureItemFunction >( params.FunctionThis );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- // call method
- bool handled = ( ( * boost::polymorphic_cast< EventHandlerClass * >( params.This->getParent() ) ).*func )
- ( ptrThis
- , reinterpret_cast< MEASUREITEMSTRUCT * >( params.Msg.LParam )
- );
- return handled;
- }
-
- static HRESULT dispatchPopup( private_::SignalContent & params )
- {
- // get callback
- typename WidgetType::voidPopupFunction func =
- reinterpret_cast< typename WidgetType::voidPopupFunction >( params.Function );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- // call the callback
- func
- ( dynamic_cast< EventHandlerClass * >( params.This->getParent() )
- , ptrThis
- );
- return 0;
- }
-
- static HRESULT dispatchPopupThis( private_::SignalContent & params )
- {
- // get method pointer
- typename WidgetType::itsVoidPopupFunction func =
- reinterpret_cast< typename WidgetType::itsVoidPopupFunction >( params.FunctionThis );
-
- StayAliveDeleter< WidgetType > deleter;
- std::tr1::shared_ptr< WidgetType > ptrThis( boost::polymorphic_cast< WidgetType * >( params.This ), deleter );
-
- // call method
- ( ( * boost::polymorphic_cast< EventHandlerClass * >( params.This->getParent() ) ).*func )
- ( ptrThis
- );
- return 0;
- }
-#endif
-};
-
-// Menu Renderer static data members initialization
-template< class MenuType >
-Point DefaultMenuRenderer< MenuType >::defaultImageSize = Point( 16, 16 );
-
// Platform specific implementation
template< class MenuType, Platform >
class WidgetMenuExtendedPlatformImplementation;
/// Specialized functions in menu for desktop Windows API version
/** This class contains all the functions in the WidgetMenuExtended which only works
- * in the Desktop Version of the OS. <br>
- * Though WidgetMenuExtended class does not actually WORK on WinCE we plan to MAKE
- * it work in future versions, therefore we have created the CurrentPlatform
- * specialization classes for it here...!!
- */
-template< class MenuType >
-class WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >
+* in the Desktop Version of the OS. <br>
+* Though WidgetMenuExtended class does not actually WORK on WinCE we plan to MAKE
+* it work in future versions, therefore we have created the CurrentPlatform
+* specialization classes for it here...!!
+*/
+template< typename MenuType >
+class WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >
{
- // friends
- friend class DefaultMenuRenderer< MenuType >;
public:
-
typedef std::tr1::shared_ptr< MenuType > WidgetMenuExtendedPtr;
- typedef WidgetMenuExtendedDispatcher< MenuType > Dispatcher;
- /// Attaches the menu to a parent window
- void attach( EventHandlerClass * mainWindow );
+ struct Seed {
+ Seed(bool popup_) : popup(popup_) { }
+ Seed() : popup(false) { }
+ bool popup;
+ };
+ HMENU handle() const {
+ return itsHandle;
+ }
+
+ HWND getParent() const {
+ return itsParent ? itsParent->handle() : 0;
+ }
+
/// Actually creates the menu
/** Creates the menu, the menu will be created initially empty!
- */
- void create( bool isPopup = false );
+ */
+ void create(const Seed& cs);
- /// Actually creates the menu
- /** Copies the menu if copy is true, otherwise just hooks it
- */
- void create( HMENU source, bool copy );
+ /// Attaches the menu to the parent window
+ void attach();
/// Appends a popup to the menu
/** Everything you "append" to a menu is added sequentially to the menu <br>
- * This specific "append" function appends a "popup" menu which is a menu
- * containing other menus. <br>
- * With other words a menu which is not an "option" but rather a new "subgroup".
- * <br>
- * The "File" menu of most application is for instance a "popup" menu while the
- * File/Print is often NOT a popup. <br>
- * To append items to the popup created call one of the appendItem overloaded
- * functions on the returned value of this function. <br>
- * Also, although references to all menu objects must be kept ( since they're
- * not collected automatically like other Widgets ) <br>
- * you don't have to keep a reference to the return value of this function since
- * it's being added as a reference to the children list of the "this" object.
- * <br>
- * A popup is basically another branch in the menu hierarchy <br>
- * See the WidgetMenu project for a demonstration.
- */
- WidgetMenuExtendedPtr appendPopup( const SmartUtil::tstring & text, MenuItemDataPtr itemData = MenuItemDataPtr( new MenuItemData() ) );
+ * This specific "append" function appends a "popup" menu which is a menu
+ * containing other menus. <br>
+ * With other words a menu which is not an "option" but rather a new "subgroup".
+ * <br>
+ * The "File" menu of most application is for instance a "popup" menu while the
+ * File/Print is often NOT a popup. <br>
+ * To append items to the popup created call one of the appendItem overloaded
+ * functions on the returned value of this function. <br>
+ * Also, although references to all menu objects must be kept ( since they're
+ * not collected automatically like other Widgets ) <br>
+ * you don't have to keep a reference to the return value of this function since
+ * it's being added as a reference to the children list of the "this" object.
+ * <br>
+ * A popup is basically another branch in the menu hierarchy <br>
+ * See the WidgetMenu project for a demonstration.
+ */
+ WidgetMenuExtendedPtr appendPopup( const SmartUtil::tstring & text, MenuItemDataPtr itemData = MenuItemDataPtr(new MenuItemData()) );
/// Returns the "System Menu"
/** The system menu is a special menu that ( normally ) is accessed by pressing
- * the "window icon" at the top left of the window. <br>
- * In SmartWin++ this menu can ALSO be easily manipulated and added items to
- * etc... <br>
- * Also, although references to all menu objects must be kept ( since they're
- * not collected automatically like other Widgets ) <br>
- * you don't have to keep a reference to the return value of this function since
- * it's being added as a reference to the children list <br>
- * of the "this" object. <br>
- * See the WidgetMenu sample project for a demonstration.
- */
+ * the "window icon" at the top left of the window. <br>
+ * In SmartWin++ this menu can ALSO be easily manipulated and added items to
+ * etc... <br>
+ * Also, although references to all menu objects must be kept ( since they're
+ * not collected automatically like other Widgets ) <br>
+ * you don't have to keep a reference to the return value of this function since
+ * it's being added as a reference to the children list <br>
+ * of the "this" object. <br>
+ * See the WidgetMenu sample project for a demonstration.
+ */
WidgetMenuExtendedPtr getSystemMenu();
-protected:
- // Initializes menu with given handle
- void init( HMENU handle );
+ /// Rendering settting settings
+ static const int borderGap; /// Gap between the border and item
+ static const int pointerGap; /// Gap between item text and sub - menu pointer
+ static const int textIconGap; /// Gap between text and icon
+ static const int textBorderGap; /// Gap between text and rectangel border
+ static const int separatorHeight; /// Defines default height for rectangle containing separator
+ static const int minSysMenuItemWidth; /// Minimum width for system menu items
+ static Point defaultImageSize; /// Default image size, used when no image is available
+protected:
// its sub menus
std::vector< WidgetMenuExtendedPtr > itsChildren;
// its item data
std::vector < private_::ItemDataWrapper * > itsItemData;
+
+ HMENU itsHandle;
+
+ Widget* itsParent;
+
+ typedef std::map<unsigned, Widget::CallbackType> CallbackMap;
+ CallbackMap callbacks;
+
+ void addCommands(Widget* widget);
};
/// Extended Menu class
/** \ingroup WidgetControls
- * \WidgetUsageInfo
- * \image html menuextended.png
- * Class for creating an Extended Menu Control which then can be attached to e.g. a
- * WidgetWindow. <br>
- * Note for Desktop version only! <br>
- * After you have created a menu you must call WidgetMenu::attach() to make it
- * "attach" to the WidgetWindow you want it to belong to. <br>
- * Do not be fooled, a WidgetMenuExtended is a much more advanced menu type then the
- * "normal" WidgetMenu and contains support for visualizations far beyond the
- * capabilities of the WidgetMenu. <br>
- * If you need those truly awesome visual menu effects use this menu control instead
- * of the WidgetMenu.
- */
+* \WidgetUsageInfo
+* \image html menuextended.png
+* Class for creating an Extended Menu Control which then can be attached to e.g. a
+* WidgetWindow. <br>
+* Note for Desktop version only! <br>
+* After you have created a menu you must call WidgetMenu::attach() to make it
+* "attach" to the WidgetWindow you want it to belong to. <br>
+* Do not be fooled, a WidgetMenuExtended is a much more advanced menu type then the
+* "normal" WidgetMenu and contains support for visualizations far beyond the
+* capabilities of the WidgetMenu. <br>
+* If you need those truly awesome visual menu effects use this menu control instead
+* of the WidgetMenu.
+*/
class WidgetMenuExtended :
- public WidgetMenuExtendedPlatformImplementation< CurrentPlatform >
+ public WidgetMenuExtendedPlatformImplementation< WidgetMenuExtended, CurrentPlatform >,
+ public boost::enable_shared_from_this< WidgetMenuExtended >
{
// friends
- friend class DefaultMenuRenderer< WidgetMenuExtended >;
- friend class WidgetMenuExtendedPlatformImplementation< CurrentPlatform >;
+ friend class WidgetMenuExtendedPlatformImplementation< WidgetMenuExtended, CurrentPlatform >;
friend class WidgetCreator< WidgetMenuExtended >;
- typedef WidgetMenuExtendedPlatformImplementation< CurrentPlatform > Implementation;
- typedef SmartWin::DefaultMenuRenderer< WidgetMenuExtended > DefaultMenuRenderer;
- typedef typename WidgetMenuExtendedPlatformImplementation< CurrentPlatform >::Dispatcher Dispatcher;
+ typedef WidgetMenuExtendedPlatformImplementation< WidgetMenuExtended, CurrentPlatform > Implementation;
public:
/// Type of object
typedef WidgetMenuExtended ThisType;
/// Object type
- typedef typename WidgetMenuExtendedPlatformImplementation< CurrentPlatform >::WidgetMenuExtendedPtr ObjectType;
+ typedef WidgetMenuExtendedPlatformImplementation< WidgetMenuExtended, CurrentPlatform >::WidgetMenuExtendedPtr ObjectType;
- /// Creational info
- //TODO: empty because it is not used anywhere ...
- class Seed
- {};
+ struct IdDispatcher
+ {
+ typedef std::tr1::function<void (unsigned)> F;
- // Event Handlers signature typedefs
+ IdDispatcher(const F& f_) : f(f_) { }
- /// \ingroup eventsSignatures
- /// \typedef Typedef of a member function to the original class taking pointer to the this Widget and an unsigned int returning void
- typedef void ( EventHandlerClass::* itsVoidMenuExtendedFunctionTakingUInt )( ObjectType, unsigned );
+ bool operator()(const MSG& msg, LRESULT& ret) {
+ f(LOWORD(msg.wParam));
+ return true;
+ }
- /// \ingroup eventsSignatures
- /// Typedef of a static/global function taking a pointer to the original class, a pointer to the this Widget class and an unsigned int returning void
- typedef void ( * menuExtendedVoidFunctionTakingUInt )( EventHandlerClass *, ObjectType, unsigned );
+ F f;
+ };
- /// \ingroup eventsSignatures
- /// \typedef Typedef of a member function to the original class taking pointer to the this Widget and an unsigned int returning void
- typedef bool ( EventHandlerClass::* itsBoolDrawItemFunction )( ObjectType, int, const DRAWITEMSTRUCT & );
+ struct DrawItemDispatcher {
+ typedef std::tr1::function<bool (int, LPDRAWITEMSTRUCT)> F;
- /// \ingroup eventsSignatures
- /// Typedef of a static/global function taking a pointer to the original class, a pointer to the this Widget class and an unsigned int returning void
- typedef bool ( * boolDrawItemFunction )( EventHandlerClass *, ObjectType, int, const DRAWITEMSTRUCT & );
+ DrawItemDispatcher(const F& f_) : f(f_) { }
- /// \ingroup eventsSignatures
- /// \typedef Typedef of a member function to the original class taking pointer to the this Widget and an unsigned int returning void
- typedef bool ( EventHandlerClass::* itsBoolMeasureItemFunction )( ObjectType, MEASUREITEMSTRUCT * );
+ bool operator()(const MSG& msg, LRESULT& ret) {
+ return f(msg.wParam, reinterpret_cast<LPDRAWITEMSTRUCT>(msg.lParam));
+ }
- /// \ingroup eventsSignatures
- /// Typedef of a static/global function taking a pointer to the original class, a pointer to the this Widget class and an unsigned int returning void
- typedef bool ( * boolMeasureItemFunction )( EventHandlerClass *, ObjectType, MEASUREITEMSTRUCT * );
+ F f;
+ };
- /// \ingroup eventsSignatures
- /// \typedef Typedef of a member function to the original class taking pointer to the this Widget returning void
- typedef void ( EventHandlerClass::* itsVoidPopupFunction )( ObjectType );
+ struct MeasureItemDispatcher {
+ typedef std::tr1::function<bool (LPMEASUREITEMSTRUCT)> F;
- /// \ingroup eventsSignatures
- /// Typedef of a static/global function taking a pointer to the original class, a pointer to the this Widget class returning void
- typedef void ( * voidPopupFunction )( EventHandlerClass *, ObjectType );
+ MeasureItemDispatcher(const F& f_) : f(f_) { }
- // Overriden to set default drawing
- void create( bool isPopup = false );
+ bool operator()(const MSG& msg, LRESULT& ret) {
+ return f(reinterpret_cast<LPMEASUREITEMSTRUCT>(msg.lParam));
+ }
- // Overriden to set default drawing
- void create( HMENU source, bool copy );
+ F f;
+ };
/// Setting event handler for Draw Item Event
/** The Draw Item Event will be raised when the menu needs to draw itself, if you
- * wish to truly be creative and be 100% in control you must handle this Event
- * and do the actualy drawing of the Menu yourself, but for most people it will
- * be enough to just manipulate the background colors etc of the MenuItemData
- * given to the menu in the appendItem or to call the setColorInfo function <br>
- * Note! <br>
- * If this event is handled you also MUST handle the Measure Item Event!!
- */
- void onDrawItem( boolDrawItemFunction eventHandler );
- void onDrawItem( itsBoolDrawItemFunction eventHandler );
+ * wish to truly be creative and be 100% in control you must handle this Event
+ * and do the actualy drawing of the Menu yourself, but for most people it will
+ * be enough to just manipulate the background colors etc of the MenuItemData
+ * given to the menu in the appendItem or to call the setColorInfo function <br>
+ * Note! <br>
+ * If this event is handled you also MUST handle the Measure Item Event!!
+ */
+ bool handleDrawItem(int id, LPDRAWITEMSTRUCT drawInfo);
- /// Setting event handler for Draw Item Event
+ /// Setting event handler for Measure Item Event
/** The Measure Item Event is nessecary to handle if you want to draw the menu
- * yourself since it is inside this Event Handler you're telling the system how
- * much space you need to actually do the drawing <br>
- * Note! <br>
- * If this event is handled you also MUST handle the Draw Item Event!!
- */
- void onMeasureItem( boolMeasureItemFunction eventHandler );
- void onMeasureItem( itsBoolMeasureItemFunction eventHandler );
+ * yourself since it is inside this Event Handler you're telling the system how
+ * much space you need to actually do the drawing <br>
+ * Note! <br>
+ * If this event is handled you also MUST handle the Draw Item Event!!
+ */
+ bool handleMeasureItem(LPMEASUREITEMSTRUCT measureInfo);
- /// Sets the event handler for the Popup event
- void onPopup( voidPopupFunction eventHandler );
-
- /// Sets the event handler for the Popup event
- void onPopup( itsVoidPopupFunction eventHandler );
-
/// Appends a separator item to the menu
/** A menu separator is basically just "air" between menu items.< br >
- * A separator cannot be "clicked" or "chosen".
- */
+ * A separator cannot be "clicked" or "chosen".
+ */
void appendSeparatorItem();
/// Appends a Menu Item
/** eventHandler is the function that will receive the "click" event from the
- * menu item. <br>
- * Event handler's signature must be "void foo( WidgetMenuExtendedPtr, unsigned
- * int )" and it must be contained as a member <br>
- * of the class that is defined as the EventHandlerClass, normally either the
- * WidgetWindow derived class or the class derived from WidgetMenu. <br>
- * See e.g. WidgetMenu for an example. <br>
- * The reason to why we have this "id" is because the same event handler can be
- * defined for several menu items even in fact across menu objects, therefore
- * this number should be unique across the application.
- */
- void appendItem( unsigned itemID, const SmartUtil::tstring & text, MenuItemDataPtr itemData, itsVoidMenuExtendedFunctionTakingUInt eventHandler );
- void appendItem( unsigned itemID, const SmartUtil::tstring & text, MenuItemDataPtr itemData, menuExtendedVoidFunctionTakingUInt eventHandler );
+ * menu item. <br>
+ * Event handler's signature must be "void foo( WidgetMenuExtendedPtr, unsigned
+ * int )" and it must be contained as a member <br>
+ * of the class that is defined as the Widget, normally either the
+ * WidgetWindow derived class or the class derived from WidgetMenu. <br>
+ * See e.g. WidgetMenu for an example. <br>
+ * The reason to why we have this "id" is because the same event handler can be
+ * defined for several menu items even in fact across menu objects, therefore
+ * this number should be unique across the application.
+ */
+ void appendItem(unsigned int id, const SmartUtil::tstring & text, MenuItemDataPtr itemData = MenuItemDataPtr(new MenuItemData()));
+ void appendItem(unsigned int id, const SmartUtil::tstring & text, const IdDispatcher::F& f, MenuItemDataPtr itemData = MenuItemDataPtr(new MenuItemData()));
+ void appendItem(unsigned int id, const SmartUtil::tstring & text, BitmapPtr image);
+ void appendItem(unsigned int id, const SmartUtil::tstring & text, const IdDispatcher::F& f, BitmapPtr image);
/// Removes specified item from this menu
/** Call this function to actually DELETE a menu item from the menu hierarchy.
- * Note that you have to specify the item position; and whenever you remove an item,
- * all subsequent items change positions. To remove a range of items, remove from
- * end to start.
- */
+ * Note that you have to specify the item position; and whenever you remove an item,
+ * all subsequent items change positions. To remove a range of items, remove from
+ * end to start.
+ */
void removeItem( unsigned itemIndex );
/// Remove all items from the menu
/** Will also delete any submenus.
- */
+ */
void removeAllItems();
/// Return the number of items in the menu
@@ -1067,69 +390,69 @@
/// Displays and handles a menu which can appear anywhere in the window.
/** Typically called by a Right Mouse click. If both the x and the y coordinate
- * is - 1 ( default ) it'll show the context menu on the position the mouse was
- * at when the system last recieved a message, basically the "right" place...
- * <br>
- * Depending on the flags it might return the id of the menu item selected, or 0
- * if none was chosen. Flags with TPM_RETURNCMD will return the menu - item, but
- * not do the menu command.
- * < ul >
- * < li >TPM_CENTERALIGN : Centers the shortcut menu horizontally relative to the coordinate specified by the x parameter< /li >
- * < li >TPM_LEFTALIGN : Function positions the shortcut menu so that its left side is aligned with the coordinate specified by the x parameter< /li >
- * < li >TPM_RIGHTALIGN : Opposite of LEFTALIGN< /li >
- * < li >TPM_BOTTOMALIGN : Aligns menu bottoms to the coordinate specified by the y parameter< /li >
- * < li >TPM_TOPALIGN : Opposite of BOTTOMALIGN< /li >
- * < li >TPM_VCENTERALIGN : Centers vertically relative to the y parameter< /li >
- * < li >TPM_NONOTIFY : Restricts the menu from sending notifications when user clicks item< /li >
- * < li >TPM_RETURNCMD : returns the menu item identifier of the user's selection in the return value but DOES NOT carry out the event handler< /li >
- * < li >TPM_LEFTBUTTON : Restricts users to selecting menu items with only left mouse button< /li >
- * < li >TPM_RIGHTBUTTON : User can choose menu item with both mouse buttons< /li >
- * < /ul >
- * None of the following are used by default but can be manually chosen if you
- * manually call SystemParametersInfo
- * < ul >
- * < li >TPM_HORNEGANIMATION : Animates the menu from right to left< /li >
- * < li >TPM_HORPOSANIMATION : Animates the menu from left to right< /li >
- * < li >TPM_NOANIMATION : Displays menu without animation< /li >
- * < li >TPM_VERNEGANIMATION : Animates the menu from bottom to top< /li >
- * < li >TPM_VERPOSANIMATION : Animates the menu from top to bottom< /li >
- * < /ul >
- */
- unsigned trackPopupMenu( EventHandlerClass * mainWindow, int x = - 1, int y = - 1, unsigned flags = 0 );
+ * is - 1 ( default ) it'll show the context menu on the position the mouse was
+ * at when the system last recieved a message, basically the "right" place...
+ * <br>
+ * Depending on the flags it might return the id of the menu item selected, or 0
+ * if none was chosen. Flags with TPM_RETURNCMD will return the menu - item, but
+ * not do the menu command.
+ * < ul >
+ * < li >TPM_CENTERALIGN : Centers the shortcut menu horizontally relative to the coordinate specified by the x parameter< /li >
+ * < li >TPM_LEFTALIGN : Function positions the shortcut menu so that its left side is aligned with the coordinate specified by the x parameter< /li >
+ * < li >TPM_RIGHTALIGN : Opposite of LEFTALIGN< /li >
+ * < li >TPM_BOTTOMALIGN : Aligns menu bottoms to the coordinate specified by the y parameter< /li >
+ * < li >TPM_TOPALIGN : Opposite of BOTTOMALIGN< /li >
+ * < li >TPM_VCENTERALIGN : Centers vertically relative to the y parameter< /li >
+ * < li >TPM_NONOTIFY : Restricts the menu from sending notifications when user clicks item< /li >
+ * < li >TPM_RETURNCMD : returns the menu item identifier of the user's selection in the return value but DOES NOT carry out the event handler< /li >
+ * < li >TPM_LEFTBUTTON : Restricts users to selecting menu items with only left mouse button< /li >
+ * < li >TPM_RIGHTBUTTON : User can choose menu item with both mouse buttons< /li >
+ * < /ul >
+ * None of the following are used by default but can be manually chosen if you
+ * manually call SystemParametersInfo
+ * < ul >
+ * < li >TPM_HORNEGANIMATION : Animates the menu from right to left< /li >
+ * < li >TPM_HORPOSANIMATION : Animates the menu from left to right< /li >
+ * < li >TPM_NOANIMATION : Displays menu without animation< /li >
+ * < li >TPM_VERNEGANIMATION : Animates the menu from bottom to top< /li >
+ * < li >TPM_VERPOSANIMATION : Animates the menu from top to bottom< /li >
+ * < /ul >
+ */
+ unsigned trackPopupMenu( Widget * mainWindow, const ScreenCoordinate& sc, unsigned flags = 0 );
/// Sets menu title
/** A WidgetMenuExtended can have a title, this function sets that title
- */
+ */
void setTitle( const SmartUtil::tstring & title, bool drawSidebar = false );
/// Sets title font
/** Create a font through e.g. createFont in WidgetFactory or similar and set the
- * title font to the menu title through using this function
- */
+ * title font to the menu title through using this function
+ */
void setTitleFont( FontPtr font );
/// Removes menu title
/** If clearSidebar is true, sidebar is removed
- */
+ */
void clearTitle( bool clearSidebar = false );
/// Enables or disables menu item
/** If the second argument is true the menu item will be enabled, otherwise it'll
- * be disabled
- */
- void enableItem( unsigned itemID, bool setEnabled );
+ * be disabled
+ */
+ void enableItem( unsigned int id, bool setEnabled );
/// Set item state to checked/unchecked
/** If second parameter is true the menu item will be checked, otherwise it'll be
- * unchecked
- */
- void checkItem( unsigned itemID, bool setChecked, bool radioMark );
+ * unchecked
+ */
+ void checkItem( unsigned int id, bool setChecked, bool radioMark );
/// Returns true if item is checked
- bool isItemEnabled( unsigned itemID );
+ bool isItemEnabled( unsigned int id );
/// Returns true if item is checked
- bool isItemChecked( unsigned itemID );
+ bool isItemChecked( unsigned int id );
/// Returns true if menu is "system menu" (icon in top left of window)
bool isSystemMenu()
@@ -1138,16 +461,16 @@
}
/// Returns item text
- SmartUtil::tstring getItemText( unsigned itemID );
+ SmartUtil::tstring getItemText( unsigned int id );
/// Sets item text
- void setItemText( unsigned itemID, SmartUtil::tstring text );
+ void setItemText( unsigned int id, SmartUtil::tstring text );
/// Sets color information for the menu
/** The MenuColorInfo declares which colors will be used for drawing the menu (
- * items ) <br>
- * Have no effect if you override the onDrawItem/onMeasureItem
- */
+ * items ) <br>
+ * Have no effect if you override the onDrawItem/onMeasureItem
+ */
void setColorInfo( const MenuColorInfo & info );
/// Returns menu color information
@@ -1181,136 +504,67 @@
MenuColorInfo itsColorInfo;
// work around for gcc
- std::vector< typename WidgetMenuExtendedPlatformImplementation< EventHandlerClass, CurrentPlatform >
- ::WidgetMenuExtendedPtr > & itsChildrenRef;
+ std::vector< WidgetMenuExtendedPlatformImplementation< WidgetMenuExtended, CurrentPlatform > ::WidgetMenuExtendedPtr > & itsChildrenRef;
+
// work around for gcc
std::vector < private_::ItemDataWrapper * > & itsItemDataRef;
private:
// Returns item index in the menu item list
// If no item with specified id is found, - 1 is returned
- int getItemIndex( unsigned itemID );
+ int getItemIndex( unsigned int id );
- // Sets event handler for specified item (to process WM_COMMAND)
- void setItemCommandHandler( unsigned itemID, menuExtendedVoidFunctionTakingUInt eventHandler );
- void setItemCommandHandler( unsigned itemID, itsVoidMenuExtendedFunctionTakingUInt eventHandler );
-
- // TODO: Basically we have a copy constructor which is create( HMENU, bool )
WidgetMenuExtended( const WidgetMenuExtended & ); // Never implemented intentionally
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation of class
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template< class EventHandlerClass >
-void WidgetMenuExtendedPlatformImplementation< EventHandlerClass, SmartWinDesktop >::attach( EventHandlerClass * mainWindow )
-{
- // get my handle
- HMENU handle = reinterpret_cast< HMENU >( this->Widget::itsHandle );
+template< typename MenuType >
+const int WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::borderGap = 3;
+template< typename MenuType >
+const int WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::pointerGap = 5;
+template< typename MenuType >
+const int WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::textIconGap = 8;
+template< typename MenuType >
+const int WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::textBorderGap = 4;
+template< typename MenuType >
+const int WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::separatorHeight = 8;
+template< typename MenuType >
+const int WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::minSysMenuItemWidth = 130;
+template< typename MenuType >
+Point WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::defaultImageSize = Point( 16, 16 );
- // set menu
- if ( ::SetMenu( mainWindow->handle(), handle ) == FALSE )
- throw xCeption( _T( "Couldn't attach menu to given parent" ) );
+template< typename MenuType >
+void WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::attach()
+{
+ addCommands(itsParent);
+ if ( ::SetMenu( getParent(), this->itsHandle ) == FALSE )
+ throw xCeption( _T( "Couldn't attach menu to the parent window" ) );
}
-template< class EventHandlerClass >
-void WidgetMenuExtendedPlatformImplementation< EventHandlerClass, SmartWinDesktop >::create( bool isPopup )
+template< typename MenuType >
+void WidgetMenuExtendedPlatformImplementation< MenuType, SmartWinDesktop >::create(const Seed& cs)
{
- HMENU handle = NULL;
-
// Create menu
- if ( isPopup )
- handle = ::CreatePopupMenu();
+ if(cs.popup)
+ itsHandle = ::CreatePopupMenu();
else
- handle = ::CreateMenu();
-
- // init newly created menu
- init( handle );
-}
-
-template< class EventHandlerClass >
-void WidgetMenuExtendedPlatformImplementation< EventHandlerClass, SmartWinDesktop >::create( HMENU source, bool copy )
-{
- if ( !::IsMenu( source ) ) // if source is not a valid menu, cancel
- return;
-
- if ( copy )
- void create(); // create empty menu
- else
- init( source ); // init with the source
-
- // get handle to this menu
- HMENU handle = reinterpret_cast< HMENU >( this->Widget::itsHandle );
-
- // get source item count
- int itemCount = ::GetMenuItemCount( source );
-
- // variables used in the loop
- int index = 0;
- int length = 0;
- MENUITEMINFO info;
- for ( index = 0; index < itemCount; ++index )
+ itsHandle = ::CreateMenu();
+ if ( !itsHandle )
{
- // init struct for menu item info
- memset( & info, 0, sizeof( MENUITEMINFO ) );
- info.cbSize = sizeof( MENUITEMINFO );
-
- // set mask
- info.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_FTYPE |
- MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
-
- if ( ::GetMenuItemInfo( source, index, TRUE, & info ) == FALSE )
- throw xCeption( _T( "Couldn't get menu item info in create()" ) );
-
- // set item to owner - drawn
- info.fType |= MFT_OWNERDRAW;
-
- // create item extended info
- MenuItemDataPtr data( new MenuItemData() );
- std::auto_ptr< private_::ItemDataWrapper > wrapper( new private_::ItemDataWrapper( handle, index, data ) );
-
- // modify item info data
- info.dwItemData = reinterpret_cast< ULONG_PTR >( wrapper.get() );
-
- // set item text
- length = info.cch + 1;
- boost::scoped_ptr< TCHAR > tmp( new TCHAR[ length ] );
- info.dwTypeData = tmp.get();
- memset( info.dwTypeData, 0, length );
- ::GetMenuString( source, index, info.dwTypeData, length, MF_BYPOSITION );
-
- // process submenus
- if ( info.hSubMenu != NULL )
- {
- // create popup menu
- WidgetMenuExtendedPtr popup ( new WidgetMenuExtended< EventHandlerClass >( this->getParent() ) );
- popup->create( info.hSubMenu, true /* copy */ );
-
- // get new handle
- info.hSubMenu = reinterpret_cast< HMENU >( popup->handle() );
-
- // store as child
- itsChildren.push_back( popup );
- }
-
- // set back item info
- if ( ( copy && ::InsertMenuItem( handle, index, TRUE, & info ) ) || // insert new item or
- ( !copy && ::SetMenuItemInfo( handle, index, TRUE, & info ) ) ) // change existing item info
- {
- itsItemData.push_back( wrapper.release() );
- }
- else
- throw xCeption( _T( "Couldn't insert/modify item in create()" ) );
+ xCeption x( _T( "CreateMenu in WidgetMenuExtended::create fizzle...
[truncated message content] |