#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(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, &QMacToolBarItem::activated, action, [=] { emit action->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, &QMacToolBarItem::activated, action, [=] { emit action->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::setFocus(Qt::FocusReason reason) { Q_UNUSED(reason) [((NSTextField *)nstextfield) becomeFirstResponder]; } void *YACReaderMacOSXSearchLineEdit::getNSTextField() { return nstextfield; } QString YACReaderMacOSXSearchLineEdit::text() { return QString::fromNSString([((NSTextField *)nstextfield) stringValue]); } void YACReaderMacOSXSearchLineEdit::clear() { [((NSTextField *)nstextfield) setStringValue:@""]; emit filterChanged(""); } 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, &QAction::toggled, this, &MacToolBarItemWrapper::actionToggled); connect(toolbaritem, &QMacToolBarItem::activated, action, &QAction::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()); }