#include "yacreader_macosx_toolbar.h" #include #include #include #include #include #import #import #import #import "shortcuts_manager.h" //---------------------------- //A custom items separator for NSToolbar @interface CustomSeparator : NSView @end @implementation CustomSeparator - (void) drawRect:(NSRect)rect { [[NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1] setFill]; NSRectFill(rect); [super drawRect:rect]; } @end //---------------------------- //Toolbar delegate, needed for allow disabled/enabled items @interface MyToolbarDelegate : NSObject { @public YACReaderMacOSXToolbar * mytoolbar; } - (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted; - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar; - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar; //- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar; - (IBAction)itemClicked:(id)sender; - (BOOL)validateToolbarItem:(NSToolbarItem *)theItem; @end @implementation MyToolbarDelegate - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar { Q_UNUSED(toolbar); NSMutableArray *array = [[NSMutableArray alloc] init]; QList items = mytoolbar->items(); foreach (const QMacToolBarItem * item, items) { [array addObject : item->nativeToolBarItem().itemIdentifier]; } return array; } - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar { Q_UNUSED(toolbar); NSMutableArray *array = [[NSMutableArray alloc] init]; QList items = mytoolbar->items(); foreach (const QMacToolBarItem * item, items) { [array addObject : item->nativeToolBarItem().itemIdentifier]; } return array; } /* - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar { Q_UNUSED(toolbar); NSMutableArray *array = [[NSMutableArray alloc] init]; QList items = mytoolbar->items(); foreach (const QMacToolBarItem * item, items) { [array addObject : item->nativeToolBarItem().itemIdentifier]; } return array; //NSMutableArray *array = toolbarPrivate->getItemIdentifiers(toolbarPrivate->items, true); //[array addObjectsFromArray:toolbarPrivate->getItemIdentifiers(toolbarPrivate->allowedItems, true)]; //return array; }*/ - (IBAction)itemClicked:(id)sender { if([sender respondsToSelector:@selector(itemIdentifier)]) { NSToolbarItem *item = reinterpret_cast(sender); QString identifier = QString::fromNSString([item itemIdentifier]); QMacToolBarItem *toolButton = reinterpret_cast(identifier.toULongLong()); Q_EMIT toolButton->activated(); } } - (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: (NSString *) itemIdentifier willBeInsertedIntoToolbar:(BOOL) willBeInserted { Q_UNUSED(toolbar); Q_UNUSED(willBeInserted); QList items = mytoolbar->items(); foreach (const QMacToolBarItem * item, items) { NSToolbarItem *toolbarItem = item->nativeToolBarItem(); if([toolbarItem.itemIdentifier isEqual:itemIdentifier]) { [toolbarItem setTarget:self]; [toolbarItem setAction:@selector(itemClicked:)]; return toolbarItem; } } return nil; } - (BOOL)validateToolbarItem:(NSToolbarItem *)theItem { QString identifier = QString::fromNSString(theItem.itemIdentifier); if(mytoolbar->actions.contains(identifier)) { return mytoolbar->actions.value(identifier)->isEnabled(); } else return NO; } @end //---------------------------- //detect changes in native text field //TODO implement validation and auto completion @interface MyTextFieldDelegate : NSObject { @public YACReaderMacOSXSearchLineEdit * mylineedit; } @end @implementation MyTextFieldDelegate - (void)controlTextDidChange:(NSNotification *)notification { NSTextField *textField = [notification object]; NSLog(@"%@",[textField stringValue]); Q_EMIT mylineedit->filterChanged(YACReader::NoModifiers, QString::fromNSString([textField stringValue])); } @end //---------------------------- YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QObject *parent) :viewSelector(0) { //setup native toolbar nativeToolBar= nativeToolbar(); [nativeToolBar setDisplayMode:NSToolbarDisplayModeIconOnly]; [nativeToolBar setAllowsUserCustomization:NO]; delegate = [[MyToolbarDelegate alloc] init]; ((MyToolbarDelegate *)delegate)->mytoolbar = this; [nativeToolBar setDelegate:(MyToolbarDelegate *)delegate]; #ifdef YACREADER_LIBRARY NSWindow *nswindow = (NSWindow*) qApp->platformNativeInterface()->nativeResourceForWindow("nswindow", ((QMainWindow*)parent)->windowHandle()); if([nswindow respondsToSelector:@selector(setTitleVisibility:)]) { yosemite = true; //TODO yosemite new constants are not found in compilation time [nswindow setTitleVisibility:NSWindowTitleHidden]; //TODO NSFullSizeContentViewWindowMask produces an offset in the windows' content //nswindow.styleMask |= 1 << 15; // NSFullSizeContentViewWindowMask; [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; //TODO figure out how to load specific images in Yosemite }else { [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; yosemite = false; } #else yosemite = false; [nativeToolBar setAutosavesConfiguration:YES]; //TODO this doesn't work [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; #endif } void YACReaderMacOSXToolbar::addAction(QAction *action) { QMacToolBarItem *toolBarItem = addItem(action->icon(),action->text()); if(action->data().toString() == TOGGLE_COMICS_VIEW_ACTION_YL) viewSelector = toolBarItem; connect(toolBarItem,SIGNAL(activated()),action, SIGNAL(triggered())); NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); actions.insert(QString::fromNSString(nativeItem.itemIdentifier),action); MacToolBarItemWrapper * wrapper = new MacToolBarItemWrapper(action,toolBarItem); //wrapper->actionToogled(true); } void YACReaderMacOSXToolbar::addDropDownItem(const QList &actions, const QAction *defaultAction) { //TODO } void YACReaderMacOSXToolbar::addSpace(int size) { QMacToolBarItem *toolBarItem = addItem(QIcon(),""); NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); static const NSRect frameRect = { { 0.0, 0.0 }, { CGFloat(size), 16.0 } }; NSView *view = [[NSView alloc] initWithFrame:frameRect]; [nativeItem setView:view]; } //reimplemented for convenience void YACReaderMacOSXToolbar::addSeparator() { //QMacToolBar::addSeparator(); QMacToolBarItem *toolBarItem = addItem(QIcon(),""); NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); static const NSRect frameRect = { { 0.0, 0.0 }, { 1, 16.0 } }; CustomSeparator *view = [[CustomSeparator alloc] initWithFrame:frameRect]; [nativeItem setView:view]; } void YACReaderMacOSXToolbar::addStretch() { QMacToolBarItem *toolBarItem = addItem(QIcon(),""); toolBarItem->setStandardItem(QMacToolBarItem::FlexibleSpace); } void YACReaderMacOSXToolbar::addWidget(QWidget *widget) { //TODO fix it /* QMacNativeWidget *nativeWidget = new QMacNativeWidget(); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(widget); nativeWidget->setLayout(layout); NSView *nativeWidgetView = reinterpret_cast(nativeWidget->winId()); QMacToolBarItem *toolBarItem = addItem(QIcon(),""); NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); [nativeItem setView:nativeWidgetView];*/ } void YACReaderMacOSXToolbar::show() { [nativeToolBar setVisible:YES]; } void YACReaderMacOSXToolbar::hide() { [nativeToolBar setVisible:NO]; } YACReaderMacOSXSearchLineEdit * YACReaderMacOSXToolbar::addSearchEdit() { QMacToolBarItem *toolBarItem = addItem(QIcon(),""); NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); YACReaderMacOSXSearchLineEdit * searchEdit = new YACReaderMacOSXSearchLineEdit(); if(yosemite) [nativeItem setView:(NSTextField *)searchEdit->getNSTextField()]; else { static const NSRect searchEditFrameRect = { { 0.0, 0.0 }, { 165, 26.0 } }; NSView * view = [[NSView alloc] initWithFrame:searchEditFrameRect]; [view addSubview:((NSTextField *)searchEdit->getNSTextField())]; [nativeItem setView:view]; } return searchEdit; } //deprecated QAction *YACReaderMacOSXToolbar::addFitToWidthSlider(QAction *attachToAction) { QMacToolBarItem *toolBarItem = addItem(QIcon(":/images/viewer_toolbar/toWidthSlider.png"),"fit to width slider"); NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); actions.insert(QString::fromNSString(nativeItem.itemIdentifier),attachToAction); QAction * action = new QAction("",attachToAction->parent()); connect(toolBarItem,SIGNAL(activated()), action, SIGNAL(triggered())); return action; } void YACReaderMacOSXToolbar::updateViewSelectorIcon(const QIcon &icon) { if(viewSelector) viewSelector->setIcon(icon); } YACReaderMacOSXSearchLineEdit::YACReaderMacOSXSearchLineEdit() :QObject() { NSRect searchEditFrameRect = { { 0.0, -3.0 }, { 165, 32.0 } }; //NSTextField * searchEdit = [[NSTextField alloc] initWithFrame:searchEditFrameRect]; NSTextField * searchEdit = [[NSSearchField alloc] initWithFrame:searchEditFrameRect]; //[searchEdit setBezelStyle:NSTextFieldRoundedBezel]; [[searchEdit cell] setPlaceholderString:@"type to search"]; MyTextFieldDelegate * delegate = [[MyTextFieldDelegate alloc] init]; delegate->mylineedit = this; [searchEdit setDelegate:delegate]; nstextfield = searchEdit; } void *YACReaderMacOSXSearchLineEdit::getNSTextField() { return nstextfield; } QString YACReaderMacOSXSearchLineEdit::text() { return QString::fromNSString([((NSTextField *)nstextfield) stringValue]); } void YACReaderMacOSXSearchLineEdit::clear() { [((NSTextField *)nstextfield) setStringValue:@""]; emit filterChanged(YACReader::NoModifiers, ""); } void YACReaderMacOSXSearchLineEdit::clearText() { //TODO be sure that this will not generate any event.... [((NSTextField *)nstextfield) setStringValue:@""]; } void YACReaderMacOSXSearchLineEdit::setDisabled(bool disabled) { [((NSTextField *)nstextfield) setEnabled:!disabled]; } void YACReaderMacOSXSearchLineEdit::setEnabled(bool enabled) { [((NSTextField *)nstextfield) setEnabled:enabled]; } MacToolBarItemWrapper::MacToolBarItemWrapper(QAction *action, QMacToolBarItem *toolbaritem) :action(action),toolbaritem(toolbaritem) { if(action->isCheckable()) { connect(action,SIGNAL(toggled(bool)),this,SLOT(actionToggled(bool))); connect(toolbaritem,SIGNAL(activated()), action, SLOT(toggle())); updateIcon(action->isChecked()); } } void MacToolBarItemWrapper::actionToggled(bool toogled) { updateIcon(toogled); } void MacToolBarItemWrapper::updateIcon(bool enabled) { if(enabled) { QIcon icon = action->icon(); QPixmap tempPixmap = icon.pixmap(QSize(24,24)); QPainter painter; painter.begin(&tempPixmap); painter.fillRect(QRect(3,21,18,1),QColor("#3F3F3F")); painter.fillRect(QRect(3,22,18,1),QColor("#6E6E6E")); painter.fillRect(QRect(3,23,18,1),QColor("#EEEEEE")); painter.end(); toolbaritem->setIcon(QIcon(tempPixmap)); } else toolbaritem->setIcon(action->icon()); }