Esempio n. 1
0
void CircuitWidget::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time)
{
    (void)info; //placate compiler...
    (void)selection_data; //placate compiler...
    if (!circuit) {
        context->drag_finish(false, false, time);
        return;
    }
    selections.clear();
    static_cast<QCViewer*>(win)->set_selection (selections);
    Gtk::Widget* widget = drag_get_source_widget(context);
    Gtk::Button* button = dynamic_cast<Gtk::Button*>(widget);
    if (button == NULL) {
        context->drag_finish(false, false, time);
        return;
    }

    shared_ptr<Gate> newgate;
    unsigned int target = 0;
    switch (static_cast<GateIcon*>(button->get_image())->type) {
    case GateIcon::NOT:
        newgate = shared_ptr<Gate>(new UGate ("X"));
        newgate->drawType = Gate::NOT;
        break;
    case GateIcon::R:
        newgate = shared_ptr<Gate>(new RGate (1.0, RGate::Z));
        break;
    case GateIcon::SWAP:
        newgate = shared_ptr<Gate>(new UGate ("F"));
        newgate->drawType = Gate::FRED;
        newgate->targets.push_back (target++);
        break;
    case GateIcon::MEASURE:
        newgate = shared_ptr<Gate>(new UGate("MEASURE",""));
        newgate->drawType = Gate::MEASURE;
        break;
    default:
        newgate = shared_ptr<Gate>(new UGate(static_cast<GateIcon*>(button->get_image ())->symbol));
        break;
    }
    if (newgate->targets.size () > circuit->numLines ()) {
        context->drag_finish (false, false, time);
        return;
    }
    newgate->targets.push_back(target++);
    Gtk::Allocation allocation = get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();
    // translate mouse click coords into circuit diagram coords
    double xx = (x - width/2.0 + ext.width/2.0)/scale + cx;
    double yy = (y - height/2.0 + ext.height/2.0)/scale + cy;
    vector<int> select_ids;
    string name;
    int pos = -1;
    getCircuitAndColPosition (xx, yy, circuit, rects, name, pos);
    if (name.compare("Main")==0||pos==-1||name.compare("")==0) {  //If the click is not in a subcircuit
        vector<unsigned int> para =  circuit->getGreedyParallel();
        unsigned int wire = getFirstWire (yy);
        if (wire + newgate->targets.size () - 1 >= circuit->numLines ()) {
            wire = circuit->numLines () - newgate->targets.size ();
        }
        for (unsigned int i = 0; i < newgate->targets.size(); i++) {
            newgate->targets[i] += wire;
        }
        if (columns.empty()||pos==-1) {
            insert_gate_at_front (newgate);
        } else if (pos >= (int)para.size()) {
            insert_gate_in_new_column (newgate, circuit->numGates(),circuit);
        } else {
            insert_gate_in_new_column (newgate, para.at(pos),circuit);
        }
        circuit->getGreedyParallel();
    } else {
        insert_gate_in_new_column (newgate, pos,circuit->subcircuits[name]);
        unsigned int wire = getFirstWire (yy);
        for (unsigned int i = 0; i < newgate->targets.size(); i++) newgate->targets[i] += wire;
    }
    context->drag_finish(true, false, time);
}