Logo Search packages:      
Sourcecode: kaconnect version File versions  Download package

connector.cpp

#include <stdio.h>
#include <qpainter.h>
#include <math.h>
#include <alsa/asoundlib.h>
#include "connector.h"
#include "portlistbox.h"
#include "qrect.h"

ConnectorWidget::ConnectorWidget(QWidget *parent, snd_seq_t *pseq) : QWidget(parent, 0) {

    int l1, l2;

    seq = pseq;
    for (l1 = 0; l1 < PORTLISTBOX_MAX_PORTS; l1++) {
        for (l2 = 0; l2 < PORTLISTBOX_MAX_PORTS; l2++) {
            connected[l1][l2] = false;
        }
    }
    r_portlist = 0;
    w_portlist = 0;
}
 
void ConnectorWidget::set_r_listBox(PortListBox *p_r_portlist) {
    
    r_portlist = p_r_portlist;
}
 
void ConnectorWidget::set_w_listBox(PortListBox *p_w_portlist) {
    
    w_portlist = p_w_portlist;
}
 
void ConnectorWidget::arrow(int x1, int y1, int x2, int y2) {

    QPainter p(this);
    float x, y, r, phi, psi;

    p.drawLine(x1, y1, x2, y2);
    r = ARROW_LENGTH;
    phi = ARROW_PHI * M_PI_4;
    psi = asin((float(x2) - float(x1)) / hypot(float(x2-x1), float(y2-y1))); 
    psi = (y2 > y1) ? psi : M_PI - psi;
    x = float(x2) - r * sin(psi-phi);
    y = float(y2) - r * cos(psi-phi);
    p.drawLine(x2, y2, int(x), int(y));
    x = float(x2) - r * sin(psi+phi);
    y = float(y2) - r * cos(psi+phi);
    p.drawLine(x2, y2, int(x), int(y));
}

void ConnectorWidget::paintEvent(QPaintEvent *) {

    QRect rect_rp, rect_wp;
    int delta, width;
    int l1, l2;

    if (!r_portlist)
        return;
    if (!w_portlist)
        return;
    width = this->width();
    for (l1 = 0; l1 < PORTLISTBOX_MAX_PORTS; l1++) {
        for (l2 = 0; l2 < PORTLISTBOX_MAX_PORTS; l2++) {
            if (connected[l1][l2] 
                && r_portlist->itemVisible(l1)
                && w_portlist->itemVisible(l2)) {
                rect_rp = r_portlist->itemRect(r_portlist->item(l1));
                rect_wp = w_portlist->itemRect(w_portlist->item(l2));
                delta = (rect_rp.top() - rect_rp.bottom()) >> 1; 
                arrow(0, rect_rp.bottom() + delta, 
                      width, rect_wp.bottom() + delta);
            };
        }
    }
}

void ConnectorWidget::move(int x, int y) {

    update();
}

void ConnectorWidget::checkEqual(int index) {

    bool equal = false;

    if (!r_portlist)
        return;
    if (!w_portlist)
        return;
    equal =  (r_portlist->client(r_portlist->currentItem())
         == w_portlist->client(w_portlist->currentItem()))
         && (r_portlist->port(r_portlist->currentItem())
         == w_portlist->port(w_portlist->currentItem()));
    emit isEqual(equal);
} 

void ConnectorWidget::updateConnector(int n) {

    int l1, l2;
    snd_seq_query_subscribe_t *subs;
    snd_seq_addr_t tmp_addr;

    if (!r_portlist)
        return;
    if (!w_portlist)
        return;
    snd_seq_query_subscribe_alloca(&subs);
    for (l1 = 0; l1 < PORTLISTBOX_MAX_PORTS; l1++) {
        for (l2 = 0; l2 < PORTLISTBOX_MAX_PORTS; l2++) {
            connected[l1][l2] = false;
        }
    }
    for (l1 = 0; l1 < r_portlist->count(); l1++) {
        tmp_addr.client = r_portlist->client(l1);
        tmp_addr.port = r_portlist->port(l1);   
        snd_seq_query_subscribe_set_type(subs, SND_SEQ_QUERY_SUBS_READ);
        snd_seq_query_subscribe_set_index(subs, 0);
        snd_seq_query_subscribe_set_root(subs, &tmp_addr);
        while (snd_seq_query_port_subscribers(seq, subs)>=0) {
            for (l2 = 0; l2 < w_portlist->count(); l2++) {
                tmp_addr = *snd_seq_query_subscribe_get_addr(subs);
                connected[l1][l2] 
                    |= (tmp_addr.client == w_portlist->client(l2))
                   && (tmp_addr.port == w_portlist->port(l2));       
            }
            snd_seq_query_subscribe_set_index(subs, snd_seq_query_subscribe_get_index(subs) + 1);
        }
    }
    update();
}

void ConnectorWidget::subscribe() {
    
    snd_seq_port_subscribe_t *subs;
    snd_seq_addr_t tmp_addr;

    if ((r_portlist->currentItem() >= 0) && (w_portlist->currentItem() >= 0)) {    
        snd_seq_port_subscribe_alloca(&subs);
        tmp_addr.client = r_portlist->client(r_portlist->currentItem()); 
        tmp_addr.port = r_portlist->port(r_portlist->currentItem()); 
        snd_seq_port_subscribe_set_sender(subs, &tmp_addr);
        tmp_addr.client = w_portlist->client(w_portlist->currentItem()); 
        tmp_addr.port = w_portlist->port(w_portlist->currentItem()); 
        snd_seq_port_subscribe_set_dest(subs, &tmp_addr);
        snd_seq_subscribe_port(seq, subs);
        updateConnector(0); 
    }
}

void ConnectorWidget::unsubscribe() {
    
    snd_seq_port_subscribe_t *subs;
    snd_seq_addr_t tmp_addr;

    if ((r_portlist->currentItem() >= 0) && (w_portlist->currentItem() >= 0)) {
        snd_seq_port_subscribe_alloca(&subs);
        tmp_addr.client = r_portlist->client(r_portlist->currentItem());
        tmp_addr.port = r_portlist->port(r_portlist->currentItem());    
        snd_seq_port_subscribe_set_sender(subs, &tmp_addr);
        tmp_addr.client = w_portlist->client(w_portlist->currentItem());
        tmp_addr.port = w_portlist->port(w_portlist->currentItem());    
        snd_seq_port_subscribe_set_dest(subs, &tmp_addr);
        snd_seq_unsubscribe_port(seq, subs);
        updateConnector(0); 
    }
}

Generated by  Doxygen 1.6.0   Back to index