Files
wxWidgets/src/cocoa/toolbar.mm
David Elliott 7dafb55fde Very basic wxToolBar implementation
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24883 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2003-12-16 15:36:56 +00:00

443 lines
14 KiB
Plaintext

/////////////////////////////////////////////////////////////////////////////
// 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 <AppKit/NSView.h>
#import <AppKit/NSButtonCell.h>
#import <AppKit/NSMatrix.h>
#import <AppKit/NSImage.h>
#import <AppKit/NSEvent.h>
#import <AppKit/NSColor.h>
#import <AppKit/NSAttributedString.h>
#import <AppKit/NSFont.h>
#include <math.h>
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<wxToolBarTool*>(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<wxToolBarTool*>(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<wxToolBarTool*>(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