GraphicsPortItem::GraphicsPortItem(GraphicsClientItemsClient *client_, const QString &fullPortName_, int style_, QFont font_, int padding, QGraphicsItem *parent) :
    QGraphicsPathItem(parent),
    client(client_),
    fullPortName(fullPortName_),
    shortPortName(fullPortName.split(":")[1]),
    dataType(client->getPortType(fullPortName)),
    isInput(client->getPortFlags(fullPortName) & JackPortIsInput),
    style(style_),
    font(font_),
    showMenu(false)
{
    bool gradient = false;
    QColor captionColor(0xfc, 0xf9, 0xc2);
    setPen(QPen(QBrush(Qt::black), 2));
    setBrush(QBrush(captionColor));
    setFlags(QGraphicsItem::ItemSendsScenePositionChanges);
    setCursor(Qt::ArrowCursor);
    font.setStyleStrategy(QFont::PreferAntialias);
    QFontMetrics fontMetrics(font);
    int portPadding = padding;

    QGraphicsSimpleTextItem *portTextItem = new QGraphicsSimpleTextItem(shortPortName, this);
    portTextItem->setFont(font);
    portTextItem->setPos(portPadding, 0);
    portRect = portTextItem->boundingRect().adjusted(-portPadding, -portPadding, portPadding, portPadding).translated(portTextItem->pos());

    QPainterPath portPath;
    if (style == 0) {
        portPath = portPath.united(EllipsePath(portRect));
    } else if (style == 1) {
        portPath = portPath.united(SpeechBubblePath(portRect, portRect.height() / 4, portRect.height() / 4, Qt::AbsoluteSize));
    } else if (style == 2) {
        portPath = portPath.united(RoundedRectanglePath(portRect, portPadding + fontMetrics.height() / 2, portPadding + fontMetrics.height() / 2));
    } else if (style == 3) {
        portPath = portPath.united(RectanglePath(portRect));
    }
    setPath(portPath);

    // register the port registration callback at the jack server:
    QObject::connect(client, SIGNAL(portRegistered(QString,QString,int)), this, SLOT(onPortRegistered(QString,QString,int)), Qt::QueuedConnection);
    QObject::connect(client, SIGNAL(portUnregistered(QString,QString,int)), this, SLOT(onPortUnregistered(QString,QString,int)), Qt::QueuedConnection);
    QObject::connect(client, SIGNAL(portConnected(QString,QString)), this, SLOT(onPortConnected(QString,QString)), Qt::QueuedConnection);
    QObject::connect(client, SIGNAL(portDisconnected(QString,QString)), this, SLOT(onPortDisconnected(QString,QString)), Qt::QueuedConnection);

    if (gradient) {
        QLinearGradient gradient(portRect.topLeft(), portRect.bottomRight());
        gradient.setColorAt(0, Qt::white);
        gradient.setColorAt(1, QColor("wheat"));
        setBrush(QBrush(gradient));
    }

    // create the context menu:
    connectMenu = contextMenu.addMenu("Connect");
    disconnectMenu = contextMenu.addMenu("Disconnect");
    // create the entries in connect- and disconnect-menus, as well as graphical representations of existing connections:
    QStringList connectedPorts = client->getConnectedPorts(fullPortName);
    QSet<QString> connectedPortsSet;
    for (int i = 0; i < connectedPorts.size(); i++) {
        // create an entry in the disconnect-menu:
        QAction *action = disconnectMenu->addAction(connectedPorts[i]);
        action->setData(connectedPorts[i]);
        QObject::connect(action, SIGNAL(triggered()), this, SLOT(onDisconnectAction()));
        mapPortNamesToActions[connectedPorts[i]] = action;
        connectedPortsSet.insert(connectedPorts[i]);
        // create a graphical representation of the connection:
        if (isInput) {
            client->getPortConnectionItem(connectedPorts[i], fullPortName)->setPos(fullPortName, getConnectionScenePos());
        } else {
            client->getPortConnectionItem(fullPortName, connectedPorts[i])->setPos(fullPortName, getConnectionScenePos());
        }
    }
    // get all available ports that can be connected to this:
    QStringList connectablePorts = client->getPorts(0, dataType.toAscii().data(), isInput ? JackPortIsOutput : JackPortIsInput);
    for (int i = 0; i < connectablePorts.size(); i++) {
        // skip ports that are already connected:
        if (!connectedPortsSet.contains(connectablePorts[i])) {
            // create an entry in the connect-menu:
            QAction *action = connectMenu->addAction(connectablePorts[i]);
            action->setData(connectablePorts[i]);
            QObject::connect(action, SIGNAL(triggered()), this, SLOT(onConnectAction()));
            mapPortNamesToActions[connectablePorts[i]] = action;
        }
    }
    disconnectMenu->setEnabled(disconnectMenu->actions().size());
    connectMenu->setEnabled(connectMenu->actions().size());
}
Example #2
0
CalendarGraphicsItem::CalendarGraphicsItem(CalendarControl * cc, QGraphicsItem * parent)
  : QGraphicsRectItem(0.0, 0.0, __width, __height, parent)
{
  _controller = cc;

  QDate today = QDate::currentDate();
  QDate firstMonthDay = QDate(today.year(), today.month(), 1);
  QDate firstCalendarDay = firstMonthDay.addDays(firstMonthDay.dayOfWeek() * -1);
  if(firstMonthDay.dayOfWeek() < 2)
    firstCalendarDay = firstCalendarDay.addDays(-7);

  _selectedDay = today;

  QString prev = QObject::tr("<");
  QString prevprev = QObject::tr("<<");
  QString next = QObject::tr(">");
  QString nextnext = QObject::tr(">>");

  QGraphicsSimpleTextItem * textItem;
  QGraphicsRectItem * rectItem;

  rectItem = new QGraphicsRectItem(0.0, 0.0, __width, __titleHeight, this);
  rectItem->setBrush(blackFill);
  _items.insert("titleBackground", rectItem);

  textItem = new QGraphicsSimpleTextItem(today.toString("MMMM yyyy"), this);
  textItem->setFont(monthfont);
  textItem->setZValue(2);
  textItem->setBrush(whiteFill);
  QPointF ct = rectItem->boundingRect().center();
  QRectF rt = textItem->boundingRect();
  textItem->setPos(ct.x() - (rt.width() / 2),
                   ct.y() - (rt.height() / 2));
  _items.insert("title", textItem);

  qreal offset = 0.1 * __dpi;
  qreal nw = 0;
  GraphicsTextButtonItem * tbtnItem = 0;
  tbtnItem = new GraphicsTextButtonItem(prevprev, this);
  tbtnItem->setFont(navfont);
  tbtnItem->setZValue(3);
  tbtnItem->setBrush(Qt::lightGray);
  tbtnItem->setRolloverBrush(Qt::green);
  tbtnItem->scale(0.5, 1);
  tbtnItem->setReceiver(this);
  rt = tbtnItem->boundingRect();
  tbtnItem->setPos(offset, ct.y() - (rt.height() / 2));
  nw = rt.width();
  _items.insert("fastrewind", tbtnItem);

  tbtnItem = new GraphicsTextButtonItem(nextnext, this);
  tbtnItem->setFont(navfont);
  tbtnItem->setZValue(3);
  tbtnItem->setBrush(Qt::lightGray);
  tbtnItem->setRolloverBrush(Qt::green);
  tbtnItem->scale(0.5, 1);
  tbtnItem->setReceiver(this);
  rt = tbtnItem->boundingRect();
  tbtnItem->setPos(rectItem->boundingRect().right() - offset - (rt.width() / 2), ct.y() - (rt.height() / 2));
  nw = qMax(nw, rt.width()) / 2;
  offset += (nw * 1.5);
  _items.insert("fastforward", tbtnItem);

  tbtnItem = new GraphicsTextButtonItem(prev, this);
  tbtnItem->setFont(navfont);
  tbtnItem->setZValue(3);
  tbtnItem->setBrush(Qt::lightGray);
  tbtnItem->setRolloverBrush(Qt::green);
  tbtnItem->scale(0.5, 1);
  tbtnItem->setReceiver(this);
  rt = tbtnItem->boundingRect();
  tbtnItem->setPos(offset, ct.y() - (rt.height() / 2));
  _items.insert("rewind", tbtnItem);

  tbtnItem = new GraphicsTextButtonItem(next, this);
  tbtnItem->setFont(navfont);
  tbtnItem->setZValue(3);
  tbtnItem->setBrush(Qt::lightGray);
  tbtnItem->setRolloverBrush(Qt::green);
  tbtnItem->scale(0.5, 1);
  tbtnItem->setReceiver(this);
  rt = tbtnItem->boundingRect();
  tbtnItem->setPos(rectItem->boundingRect().right() - offset - (rt.width() / 2), ct.y() - (rt.height() / 2));
  _items.insert("forward", tbtnItem);

  QDate date;
  qreal dayWidth = __width / 7.0;
  QApplication::setOverrideCursor(Qt::WaitCursor);
  for(int wday = 0; wday < 7; wday++)
  {
    for(int week = 0; week < 6; week++)
    {
      date = firstCalendarDay.addDays((7 * week) + wday);

      if(0 == week)
      {
        rectItem = new QGraphicsRectItem(wday * dayWidth, 0.5 * __dpi, dayWidth, 0.25 * __dpi, this);
        _items.insert(QString("weekday%1").arg(week), rectItem);
        textItem = new QGraphicsSimpleTextItem(date.toString("dddd"), this);
        textItem->setFont(wdayfont);
        textItem->setZValue(2);
        ct = rectItem->boundingRect().center();
        rt = textItem->boundingRect();
        textItem->setPos(ct.x() - (rt.width() / 2),
                         ct.y() - (rt.height() / 2));
        _items.insert(QString("weekday%1Text").arg(week), textItem);
      }

      QBrush fill;
      QBrush dayFill = blackFill;
      if(date == _selectedDay)
        fill = selectedFill;
      else if(date.month() != today.month())
      {
        fill = nonMonthFill;
        dayFill = nonMonthDayFill;
      }
      else if(date == today)
        fill = todayFill;
      else if(date.dayOfWeek() > 5)
        fill = weekendFill;

      rectItem = new QGraphicsRectItem(wday * dayWidth, (0.75  + (1.25 * week)) * __dpi, dayWidth, 1.25 * __dpi, this);
      rectItem->setBrush(fill);
      _items.insert(QString("day%1").arg((7 * week) + wday), rectItem);
      rt = QRectF(rectItem->pos(), rectItem->boundingRect().size());
      double offset = rt.width() / 3;
      textItem = new QGraphicsSimpleTextItem(QString::number(date.day()), this);
      textItem->setFont(dayfont);
      textItem->setZValue(2);
      textItem->setBrush(dayFill);
      textItem->setPos(rectItem->boundingRect().topLeft());
      textItem->moveBy(5.0, 5.0);
      _items.insert(QString("day%1Number").arg((7 * week) + wday), textItem);

      rt = QRectF(textItem->pos(), textItem->boundingRect().size());

      QString additionalText;
      if(_controller)
        additionalText = _controller->contents(date);
      textItem = new QGraphicsSimpleTextItem(additionalText, this);
      textItem->setFont(notesfont);
      textItem->setZValue(2);
      textItem->setBrush(dayFill);
      textItem->setPos(rt.left() + offset,
                       rt.top() + (rt.height() * 1.5));
      _items.insert(QString("day%1Text").arg((7 * week) + wday), textItem);
    }
  }
  QApplication::restoreOverrideCursor();
}
void GraphicsClientItem::initItem()
{
    // delete all children (except the inner item):
    QList<QGraphicsItem*> children = childItems();
    for (int i = 0; i < children.size(); i++) {
        if (children[i] != controlsItem) {
            if (GraphicsPortItem *portItem = dynamic_cast<GraphicsPortItem*>(children[i])) {
                portItem->deleteLater();
            } else {
                delete children[i];
            }
        }
    }

    bool gradient = false;
    QFont commandsFont = font;
    commandsFont.setBold(true);
    commandsFont.setStyleStrategy(QFont::PreferAntialias);
    QFontMetrics fontMetrics(font);
    int portPadding = fontMetrics.height() / 3;
    int padding = fontMetrics.height() + portPadding * 2;

    QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem(clientName, this);
    textItem->setFont(font);
    textItem->setPos(padding, padding);
    QStringList inputPorts = clientItemsClient->getPorts(QString(QRegExp::escape(clientName) + ":.*").toAscii().data(), 0, JackPortIsInput);
    QList<GraphicsPortItem*> inputPortItems;
    int inputPortsWidth = -portPadding;
    int minimumInputPortWidth = 0;
    for (int i = 0; i < inputPorts.size(); i++) {
        inputPortItems.append(new GraphicsPortItem(clientItemsClient, inputPorts[i], 3, font, portPadding, this));
        if (isMacroItem()) {
            QPen pen = inputPortItems.back()->pen();
            pen.setColor(QColor("steelblue"));
            inputPortItems.back()->setPen(pen);
        }
        inputPortsWidth += inputPortItems[i]->getRect().width() + portPadding;
        if ((i == 0) || (inputPortItems[i]->getRect().width() < minimumInputPortWidth)) {
            minimumInputPortWidth = inputPortItems[i]->getRect().width();
        }
    }
    QStringList outputPorts = clientItemsClient->getPorts(QString(QRegExp::escape(clientName) + ":.*").toAscii().data(), 0, JackPortIsOutput);
    QList<GraphicsPortItem*> outputPortItems;
    int outputPortsWidth = -portPadding;
    int minimumOutputPortWidth = 0;
    for (int i = 0; i < outputPorts.size(); i++) {
        outputPortItems.append(new GraphicsPortItem(clientItemsClient, outputPorts[i], 3, font, portPadding, this));
        if (isMacroItem()) {
            QPen pen = outputPortItems.back()->pen();
            pen.setColor(QColor("steelblue"));
            outputPortItems.back()->setPen(pen);
        }
        outputPortsWidth += outputPortItems[i]->getRect().width() + portPadding;
        if ((i == 0) || (outputPortItems[i]->getRect().width() < minimumOutputPortWidth)) {
            minimumOutputPortWidth = outputPortItems[i]->getRect().width();
        }
    }

    rect = (textItem->boundingRect().translated(textItem->pos())).adjusted(-padding, -padding, padding, padding);
//    if (rect.width() < inputPortsWidth + (portPadding - minimumInputPortWidth) * 2) {
//        rect.setWidth(inputPortsWidth + (portPadding - minimumInputPortWidth) * 2);
//    }
//    if (rect.width() < outputPortsWidth + (portPadding - minimumOutputPortWidth) * 2) {
//        rect.setWidth(outputPortsWidth + (portPadding - minimumOutputPortWidth) * 2);
//    }
    if (rect.width() < inputPortsWidth) {
        rect.setWidth(inputPortsWidth);
    }
    if (rect.width() < outputPortsWidth) {
        rect.setWidth(outputPortsWidth);
    }
    if (gradient) {
        QLinearGradient gradient(rect.topLeft(), rect.bottomRight());
        gradient.setColorAt(0, Qt::white);
        gradient.setColorAt(1, QColor(0xfc, 0xf9, 0xc2));//QColor("royalblue").lighter());
        setBrush(QBrush(gradient));
    }

    QPainterPath bodyPath;
    if (clientStyle == 0) {
        bodyPath = EllipsePath(rect);
    } else if (clientStyle == 1) {
        bodyPath = SpeechBubblePath(rect, rect.height() / 4, rect.height() / 4, Qt::AbsoluteSize);
    } else if (clientStyle == 2){
        bodyPath = RoundedRectanglePath(rect, padding + fontMetrics.height(), padding + fontMetrics.height());
    } else if (clientStyle == 3) {
        bodyPath = RectanglePath(rect);
    }

    for (int i = 0, x = (inputPortsWidth > rect.width() ? (rect.width() - inputPortsWidth) / 2 : 0); i < inputPorts.size(); i++) {
        GraphicsPortItem *portItem = inputPortItems[i];
        portItem->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
        portItem->setPos(x, 0);
        QRectF portRect(portItem->getRect().translated(portItem->pos()));

        QPainterPath portPath;
        portPath.addRect(QRectF(portRect.topLeft(), 0.5 * (portRect.topRight() + portRect.bottomRight())));
        int portStyle = (portItem->isAudioType() ? audioPortStyle : midiPortStyle);
        if (portStyle == 0) {
            portPath += EllipsePath(portRect);
        } else if (portStyle == 1) {
            portPath += SpeechBubblePath(portRect, 0.7, 0.7);
        } else if (portStyle == 2) {
            portPath += RoundedRectanglePath(portRect, portPadding + fontMetrics.height() / 2, portPadding + fontMetrics.height() / 2);
        } else if (portStyle == 3) {
            portPath += RectanglePath(portRect);
        }
        bodyPath -= portPath;

        x += portRect.width() + portPadding;
    }
    for (int i = 0, x = (outputPortsWidth > rect.width() ? (rect.width() - outputPortsWidth) / 2 : 0); i < outputPorts.size(); i++) {
        GraphicsPortItem *portItem = outputPortItems[i];
        portItem->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
        portItem->setPos(x, rect.height() - fontMetrics.height());
        QRectF portRect(portItem->getRect().translated(portItem->pos()));

        QPainterPath portPath;
        portPath.addRect(QRectF(0.5 * (portRect.topLeft() + portRect.bottomLeft()), portRect.bottomRight()));
        int portStyle = (portItem->isAudioType() ? audioPortStyle : midiPortStyle);
        if (portStyle == 0) {
            portPath += EllipsePath(portRect);
        } else if (portStyle == 1) {
            portPath += SpeechBubblePath(portRect, 0.7, 0.7);
        } else if (portStyle == 2) {
            portPath += RoundedRectanglePath(portRect, portPadding + fontMetrics.height() / 2, portPadding + fontMetrics.height() / 2);
        } else if (portStyle == 3) {
            portPath += RectanglePath(portRect);
        }
        bodyPath -= portPath;

        x += portRect.width() + portPadding;
    }
    QPainterPath combinedPath = bodyPath;

    setPath(combinedPath);
}