From: David Elliott Date: Tue, 16 Dec 2003 15:36:56 +0000 (+0000) Subject: Very basic wxToolBar implementation X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/7dafb55fdec4ef71567ee1ccbf16d4461df8198f Very basic wxToolBar implementation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24883 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/cocoa/toolbar.h b/include/wx/cocoa/toolbar.h new file mode 100644 index 0000000000..d8ccd336b9 --- /dev/null +++ b/include/wx/cocoa/toolbar.h @@ -0,0 +1,113 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/cocoa/toolbar.h +// Purpose: wxToolBar +// Author: David Elliott +// Modified by: +// Created: 2003/08/17 +// RCS-ID: $Id$ +// Copyright: (c) 2003 David Elliott +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef __WX_COCOA_TOOLBAR_H__ +#define __WX_COCOA_TOOLBAR_H__ + +#if wxUSE_TOOLBAR + +// ======================================================================== +// wxToolBar +// ======================================================================== +typedef struct _NSPoint NSPoint; +class wxToolBarTool; + +class wxToolBar : public wxToolBarBase +{ + DECLARE_DYNAMIC_CLASS(wxToolBar) +// ------------------------------------------------------------------------ +// initialization +// ------------------------------------------------------------------------ +public: + wxToolBar() { Init(); } + wxToolBar( wxWindow *parent, + wxWindowID toolid, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxToolBarNameStr ) + { + Init(); + + Create(parent, toolid, pos, size, style, name); + } + + bool Create( wxWindow *parent, + wxWindowID toolid, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxToolBarNameStr ); + + virtual ~wxToolBar(); + +protected: + // common part of all ctors + void Init(); + +// ------------------------------------------------------------------------ +// Cocoa +// ------------------------------------------------------------------------ +protected: + virtual bool Cocoa_drawRect(const NSRect &rect); + virtual bool Cocoa_mouseDown(WX_NSEvent theEvent); + virtual bool Cocoa_mouseDragged(WX_NSEvent theEvent); + wxToolBarTool *CocoaFindToolForPosition(const NSPoint& pos) const; +// ------------------------------------------------------------------------ +// Implementation +// ------------------------------------------------------------------------ +public: + // override base class virtuals + virtual void SetMargins(int x, int y); + virtual void SetToolSeparation(int separation); + + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; + + virtual void SetToolShortHelp(int toolid, const wxString& helpString); + + virtual void SetWindowStyleFlag( long style ); + + // implementation from now on + // -------------------------- + + void OnInternalIdle(); + virtual bool Realize(); + virtual wxSize DoGetBestSize() const; + + void SetOwningFrame(wxFrame *owningFrame) + { m_owningFrame = owningFrame; } +protected: + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + virtual wxToolBarToolBase *CreateTool(int toolid, + const wxString& label, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + wxItemKind kind, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + + wxSize m_bestSize; + wxFrame *m_owningFrame; + wxToolBarTool *m_mouseDownTool; +}; + +#endif // wxUSE_TOOLBAR + +#endif // __WX_COCOA_TOOLBAR_H__ diff --git a/src/cocoa/toolbar.mm b/src/cocoa/toolbar.mm new file mode 100644 index 0000000000..03b84d6b63 --- /dev/null +++ b/src/cocoa/toolbar.mm @@ -0,0 +1,442 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/cocoa/toolbar.mm +// Purpose: wxToolBar +// Author: David Elliott +// Modified by: +// Created: 2003/08/17 +// RCS-ID: $Id$ +// Copyright: (c) 2003 David Elliott +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_TOOLBAR_NATIVE +#ifndef WX_PRECOMP + #include "wx/toolbar.h" + #include "wx/frame.h" + #include "wx/log.h" +#endif // WX_PRECOMP + +#include "wx/cocoa/string.h" +#include "wx/cocoa/autorelease.h" + +#import +#import +#import +#import +#import +#import +#import +#import + +#include + +DECLARE_WXCOCOA_OBJC_CLASS(NSActionCell); + +// ======================================================================== +// wxCocoaNSActionCell +// ======================================================================== +WX_DECLARE_OBJC_HASHMAP(NSActionCell); + +class wxCocoaNSActionCell +{ + WX_DECLARE_OBJC_INTERFACE(NSActionCell) +public: + virtual void CocoaTarget_wxNSActionCellAction() {} +protected: + static struct objc_object *sm_cocoaTarget; +}; + +// ============================================================================ +// @class wxNSActionCellTarget +// ============================================================================ +@interface wxNSActionCellTarget : NSObject +{ +} + +- (void)wxNSActionCellAction: (id)sender; +@end //interface wxNSActionCellTarget + +@implementation wxNSActionCellTarget : NSObject + +- (void)wxNSActionCellAction: (id)sender +{ + wxLogDebug("wxNSActionCellAction"); + wxCocoaNSActionCell *wxcontrol = wxCocoaNSActionCell::GetFromCocoa(sender); + wxCHECK_RET(wxcontrol,"wxNSActionCellAction received but no wxCocoaNSActionCell exists!"); + wxcontrol->CocoaTarget_wxNSActionCellAction(); +} + +@end //implementation wxNSActionCellTarget + +// ======================================================================== +// wxCocoaNSActionCell +// ======================================================================== +struct objc_object *wxCocoaNSActionCell::sm_cocoaTarget = [[wxNSActionCellTarget alloc] init]; +WX_IMPLEMENT_OBJC_INTERFACE(NSActionCell) + +// ======================================================================== +// wxToolBarTool +// ======================================================================== +class wxToolBarTool : public wxToolBarToolBase, protected wxCocoaNSActionCell +{ +public: + wxToolBarTool(wxToolBar *tbar, int toolid, const wxString& label, + const wxBitmap& bitmap1, const wxBitmap& bitmap2, + wxItemKind kind, wxObject *clientData, + const wxString& shortHelpString, const wxString& longHelpString) + : wxToolBarToolBase(tbar, toolid, label, bitmap1, bitmap2, kind, + clientData, shortHelpString, longHelpString) + { + Init(); + CreateButtonCell(); + } + + wxToolBarTool(wxToolBar *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + Init(); + } + ~wxToolBarTool(); + + bool CreateButtonCell(); + + // is this a radio button? + // + // unlike GetKind(), can be called for any kind of tools, not just buttons + bool IsRadio() const { return IsButton() && GetKind() == wxITEM_RADIO; } + + NSRect GetFrameRect() + { return m_frameRect; } + void SetFrameRect(NSRect frameRect) + { m_frameRect = frameRect; } + void DrawTool(NSView *nsview); + + NSButtonCell *GetNSButtonCell() + { return m_cocoaNSButtonCell; } +protected: + void Init(); + NSButtonCell *m_cocoaNSButtonCell; + NSRect m_frameRect; +}; + +// ======================================================================== +// wxToolBarTool +// ======================================================================== +void wxToolBarTool::Init() +{ + m_cocoaNSButtonCell = NULL; + m_frameRect = NSZeroRect; +} + +wxToolBarTool::~wxToolBarTool() +{ + DisassociateNSActionCell(m_cocoaNSButtonCell); + [m_cocoaNSButtonCell release]; +} + +bool wxToolBarTool::CreateButtonCell() +{ + NSImage *nsimage = [m_bmpNormal.GetNSImage(true) retain]; + m_cocoaNSButtonCell = [[NSButtonCell alloc] initTextCell:nil]; + [m_cocoaNSButtonCell setImage:nsimage]; + NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:wxNSStringWithWxString(m_label) attributes:[NSDictionary dictionaryWithObject:[NSFont labelFontOfSize:0.0] forKey:NSFontAttributeName]]; +// [m_cocoaNSButtonCell setTitle:wxNSStringWithWxString(m_label)]; + [m_cocoaNSButtonCell setAttributedTitle:[attributedTitle autorelease]]; + + // Create an alternate image in the style of NSToolBar + if(nsimage) + { + NSImage *alternateImage = [[NSImage alloc] initWithSize:[nsimage size]]; + [alternateImage lockFocus]; + // Paint the entire image with solid black at 50% transparency + NSRect imageRect = NSZeroRect; + imageRect.size = [alternateImage size]; + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.5] set]; + NSRectFill(imageRect); + // Composite the original image with the alternate image + [nsimage compositeToPoint:NSZeroPoint operation:NSCompositeDestinationAtop]; + [alternateImage unlockFocus]; + [m_cocoaNSButtonCell setAlternateImage:alternateImage]; + [alternateImage release]; + } + [nsimage release]; + + NSMutableAttributedString *alternateTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[m_cocoaNSButtonCell attributedTitle]]; + [alternateTitle applyFontTraits:NSBoldFontMask range:NSMakeRange(0,[alternateTitle length])]; + [m_cocoaNSButtonCell setAttributedAlternateTitle:alternateTitle]; + [alternateTitle release]; + + // ---- + [m_cocoaNSButtonCell setImagePosition:NSImageBelow]; +// [m_cocoaNSButtonCell setBezeled:NO]; + [m_cocoaNSButtonCell setButtonType:NSMomentaryChangeButton]; + [m_cocoaNSButtonCell setBordered:NO]; +// [m_cocoaNSButtonCell setHighlightsBy:NSContentsCellMask|NSPushInCellMask]; +// [m_cocoaNSButtonCell setShowsStateBy:NSContentsCellMask|NSPushInCellMask]; + AssociateNSActionCell(m_cocoaNSButtonCell); + return true; +} + +void wxToolBarTool::DrawTool(NSView *nsview) +{ + [m_cocoaNSButtonCell drawWithFrame:m_frameRect inView:nsview]; +} + +// ======================================================================== +// wxToolBar +// ======================================================================== +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) + +//----------------------------------------------------------------------------- +// wxToolBar construction +//----------------------------------------------------------------------------- + +void wxToolBar::Init() +{ + m_owningFrame = NULL; +} + +wxToolBar::~wxToolBar() +{ +} + +bool wxToolBar::Create( wxWindow *parent, + wxWindowID winid, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name ) +{ + // Call wxControl::Create so we get a wxNonControlNSControl + return wxToolBarBase::Create(parent,winid,pos,size,style,wxDefaultValidator,name); +} + +wxToolBarToolBase *wxToolBar::CreateTool(int toolid, + const wxString& text, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + wxItemKind kind, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarTool(this, toolid, text, bitmap1, bitmap2, kind, + clientData, shortHelpString, longHelpString); +} + +wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) +{ + return new wxToolBarTool(this, control); +} + +void wxToolBar::SetWindowStyleFlag( long style ) +{ + wxToolBarBase::SetWindowStyleFlag(style); +} + +bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) +{ + return true; +} + +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) +{ + Realize(); + return true; +} + +bool wxToolBar::Cocoa_drawRect(const NSRect &rect) +{ + wxToolBarToolsList::compatibility_iterator node; + for(node = m_tools.GetFirst(); node; node = node->GetNext()) + { + wxToolBarTool *tool = static_cast(node->GetData()); + tool->DrawTool(m_cocoaNSView); + } + return wxToolBarBase::Cocoa_drawRect(rect); +} + +static const NSSize toolPadding = { 4.0, 4.0 }; + +static NSRect AddToolPadding(NSRect toolRect) +{ + toolRect.origin.x -= toolPadding.width; + toolRect.size.width += 2.0*toolPadding.width; + toolRect.origin.y -= toolPadding.height; + toolRect.size.height += 2.0*toolPadding.height; + return toolRect; +} + +bool wxToolBar::Cocoa_mouseDragged(WX_NSEvent theEvent) +{ + if(m_mouseDownTool && [m_cocoaNSView + mouse:[m_cocoaNSView convertPoint:[theEvent locationInWindow] + fromView:nil] + inRect:AddToolPadding(m_mouseDownTool->GetFrameRect())]) + { + NSButtonCell *buttonCell = m_mouseDownTool->GetNSButtonCell(); + if(buttonCell) + { + [buttonCell setHighlighted: YES]; + if([buttonCell trackMouse: theEvent + inRect:AddToolPadding(m_mouseDownTool->GetFrameRect()) ofView:m_cocoaNSView + untilMouseUp:NO]) + { + m_mouseDownTool = NULL; + wxLogDebug("Button was clicked after drag!"); + } + [buttonCell setHighlighted: NO]; + } + } + return wxToolBarBase::Cocoa_mouseDragged(theEvent); +} + +bool wxToolBar::Cocoa_mouseDown(WX_NSEvent theEvent) +{ + wxToolBarTool *tool = CocoaFindToolForPosition([m_cocoaNSView convertPoint:[theEvent locationInWindow] fromView:nil]); + if(tool) + { + NSButtonCell *buttonCell = tool->GetNSButtonCell(); + if(buttonCell) + { + m_mouseDownTool = tool; + [buttonCell setHighlighted: YES]; + if([buttonCell trackMouse: theEvent + inRect:AddToolPadding(tool->GetFrameRect()) ofView:m_cocoaNSView + untilMouseUp:NO]) + { + m_mouseDownTool = NULL; + wxLogDebug("Button was clicked!"); + } + [buttonCell setHighlighted: NO]; + } + } + return wxToolBarBase::Cocoa_mouseDown(theEvent); +} + +bool wxToolBar::Realize() +{ + wxToolBarToolsList::compatibility_iterator node; + NSSize totalSize = NSZeroSize; + // This is for horizontal, TODO: vertical + for(node = m_tools.GetFirst(); node; node = node->GetNext()) + { + wxToolBarTool *tool = static_cast(node->GetData()); + if(tool->IsControl()) + { + totalSize.width = ceil(totalSize.width); + wxControl *control = tool->GetControl(); + wxSize controlSize = control->GetSize(); + control->SetPosition(wxPoint((wxCoord)totalSize.width,0)); + totalSize.width += controlSize.x; + if(controlSize.y > totalSize.height) + totalSize.height = controlSize.y; + } + else if(tool->IsSeparator()) + { + totalSize.width += 2.0; + } + else + { + NSButtonCell *buttonCell = tool->GetNSButtonCell(); + NSSize toolSize = [buttonCell cellSize]; + tool->SetFrameRect(NSMakeRect(totalSize.width+toolPadding.width,toolPadding.height,toolSize.width,toolSize.height)); + toolSize.width += 2.0*toolPadding.width; + toolSize.height += 2.0*toolPadding.height; + totalSize.width += toolSize.width; + if(toolSize.height > totalSize.height) + totalSize.height = toolSize.height; + } + } + m_bestSize = wxSize((wxCoord)ceil(totalSize.width),(wxCoord)ceil(totalSize.height)); + if(m_owningFrame) + m_owningFrame->UpdateFrameNSView(); + return true; +} + +wxSize wxToolBar::DoGetBestSize() const +{ + return m_bestSize; +} + +// ---------------------------------------------------------------------------- +// wxToolBar tools state +// ---------------------------------------------------------------------------- + +void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable) +{ +} + +void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle ) +{ +} + +void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) +{ +} + +// ---------------------------------------------------------------------------- +// wxToolBar geometry +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const +{ + return NULL; +} + +wxToolBarTool *wxToolBar::CocoaFindToolForPosition(const NSPoint& pos) const +{ + wxToolBarToolsList::compatibility_iterator node; + for(node = m_tools.GetFirst(); node; node = node->GetNext()) + { + wxToolBarTool *tool = static_cast(node->GetData()); + if(tool->IsControl()) + { + // TODO + } + else if(tool->IsSeparator()) + { // Do nothing + } + else + { + if([m_cocoaNSView mouse:pos inRect:AddToolPadding(tool->GetFrameRect())]) + return tool; + } + } + return NULL; +} + +void wxToolBar::SetMargins( int x, int y ) +{ +} + +void wxToolBar::SetToolSeparation( int separation ) +{ + m_toolSeparation = separation; +} + +void wxToolBar::SetToolShortHelp( int id, const wxString& helpString ) +{ +} + +// ---------------------------------------------------------------------------- +// wxToolBar idle handling +// ---------------------------------------------------------------------------- + +void wxToolBar::OnInternalIdle() +{ +} + +#endif // wxUSE_TOOLBAR_NATIVE