Пример #1
0
void ImageView::mousePressEvent(QMouseEvent *event)
{
    switch (m_mouseMode) {
        case MM_ZOOM:
            m_rubberBand->setGeometry(0, 0, 0, 0);
            if (event->modifiers() & Qt::ControlModifier) {
                m_rubberBand->hide();
            } else {
                m_rubberBandOrigin = event->pos();
                m_rubberBand->show();
            }
            break;
        case MM_MINMAX:
            m_minMaxLens->show();
            //this->repaint(this->m_minMaxLens->geometry());
            this->repaint(0, 0, -1, -1);
            this->m_minMaxLens->setGeometry(QRect());
            m_minMaxLensOrigin = event->pos();
            break;
        case MM_PICK:
            if (visibleRegion().contains(event->pos())) {
                int x = event->x();
                int y = event->y();
                this->canvasToImage(x, y);
                emit picked(x, y);
            }
            break;
        default:
            break;
    }
}
Пример #2
0
void aHistLineEdit::ColourPickerPopUp()
{
  kscolourpicker *kscp = new("kscolourpicker") kscolourpicker();
  connect(kscp, SIGNAL(picked( QString )), 
          this, SLOT(slot_insert( QString )));
  kscp->show();
}
Пример #3
0
void dtkColorGrid::mouseMoveEvent ( QMouseEvent * event )
{
    //if (!hasFocus()) setFocus();

    QWidget::mouseMoveEvent(event);

    d->pos = event->pos();

    int c = d->cellSize+1;
    d->row = d->pos.y() / c;
    d->col = d->pos.x() / c;

    int i = index();
    if (i != d->idx)
    {
        d->idx = i;
        repaint();

        QToolTip::hideText();

        if (d->idx != -1) {
            emit highlighted(d->hlColor);

            QToolTip::showText(event->globalPos(), d->hlColor.name(), this);

            if (d->pickDrag && event->buttons() & Qt::LeftButton) {
                d->selColor = d->hlColor;
                emit picked(d->selColor);
                //emit accepted();
            }
        }
    }

}
Пример #4
0
	void Render(double time)
	{
		gl.Clear().ColorBuffer().DepthBuffer();

		auto camera = CamMatrixf::Orbiting(
			Vec3f(),
			16.0,
			FullCircles(time * 0.1),
			Degrees(SineWave(time / 20.0) * 30)
		);

		// use the picking program
		pick_prog.Use();
		Uniform<Mat4f>(pick_prog, "CameraMatrix").Set(camera);

		// query the number of values written to the feedabck buffer
		GLuint picked_count = 0;
		{
			Query::Execution<GLuint> query_exec(
				count_query,
				Query::Target::
				TransformFeedbackPrimitivesWritten,
				picked_count
			);
			TransformFeedback::Activator xfb_act(
				TransformFeedbackPrimitiveType::Points
			);
			// draw 36 instances of the cube
			// the vertex shader will take care of their placement
			cube_instr.Draw(cube_indices, 36);
			//
			xfb_act.Finish();
			query_exec.WaitForResult();
		}

		std::map<GLfloat, GLint> picked_objs;
		{
			picked_instances.Bind(Buffer::Target::TransformFeedback);
			BufferTypedMap<DepthAndID> picked_instances_map(
				Buffer::Target::TransformFeedback,
				BufferMapAccess::Read
			);
			picked_objs.insert(
				picked_instances_map.Data(),
				picked_instances_map.Data()+picked_count
			);
		}

		draw_prog.Use();

		Uniform<GLint> picked(draw_prog, "Picked");
		if(picked_objs.empty()) picked = -1;
		else picked = picked_objs.begin()->second;
		Uniform<Mat4f>(draw_prog, "CameraMatrix").Set(camera);

		// draw 36 instances of the cube
		// the vertex shader will take care of their placement
		cube_instr.Draw(cube_indices, 36);
	}
Пример #5
0
void dtkColorGrid::mouseReleaseEvent ( QMouseEvent * event )
{
    if (!hasFocus()) setFocus();

    if (d->clickMode == CM_RELEASE && event->button() == Qt::LeftButton && d->hlColor.isValid()) {
        d->selColor = d->hlColor;
        emit picked(d->selColor);
        emit accepted();
    }
}
Пример #6
0
//Implements the VBLAST decoding, a nulling and cancelling decoder
Matrix vblast_decoder(Matrix H, int NUM_TX, int NUM_RX, Matrix y, double scale, int PAM)
{
	Matrix y_VBLAST = y;
	Matrix picked(NUM_TX,1);
	Matrix VBLAST_OUT(NUM_TX,1);
	int i;
	for(i=0;i<NUM_TX;i++) picked(i,0) = 0;
	for(i=0;i<NUM_TX;i++)
	{
		int dim_left = NUM_TX - i;
		Matrix W(dim_left,NUM_RX);
		Matrix H_VBLAST(NUM_RX,dim_left);
		int upto = 0;
		for(int k = 0;k< NUM_TX; k++)
		{
			if(picked(k,0) == 0)
			{
				for(int j = 0;j < NUM_RX; j++)
					H_VBLAST(j,upto) = H(j,k);
				upto++;
			}
		}
		W = !( (~H_VBLAST) * H_VBLAST ) * (~H_VBLAST);
		int up_to = 0;
		int smallest_w = get_smallest(NUM_TX, NUM_RX, W, picked, up_to);
		picked(smallest_w,0) = 1;
		Matrix w_smallest(NUM_RX,1);
		Matrix h_smallest(NUM_RX,1);
		for(int j= 0;j< NUM_RX; j++)
		{
			w_smallest(j,0) = W(up_to,j);
			h_smallest(j,0) = H_VBLAST(j,up_to);
		}
		Matrix temp_VBLAST = (~w_smallest) * y_VBLAST;
		temp_VBLAST(0,0) = temp_VBLAST(0,0)/scale;
		Matrix VBLAST_sym = get_Eq_bits(1,temp_VBLAST,PAM);
		VBLAST_OUT(smallest_w,0) = VBLAST_sym(0,0);
		VBLAST_sym(0,0) = VBLAST_sym(0,0) * scale;
		y_VBLAST = y_VBLAST - ( h_smallest * VBLAST_sym );
	}
	return VBLAST_OUT;
}
Пример #7
0
int FileBrowser::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QSplitter::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: picked((*reinterpret_cast< const QString(*)>(_a[1]))); break;
        case 1: onItemChanged((*reinterpret_cast< QListWidgetItem*(*)>(_a[1])),(*reinterpret_cast< QListWidgetItem*(*)>(_a[2]))); break;
        case 2: onSelectionChanged(); break;
        default: ;
        }
        _id -= 3;
    }
    return _id;
}
Пример #8
0
/*!
 * \breif nms Non-maximum suppression
 * the algorithm is from https://github.com/ShaoqingRen/SPP_net/blob/master/nms%2Fnms_mex.cpp
 *
 * \param rects     area of faces
 * \param scores    score of faces
 * \param overlap   overlap threshold
 * \return          picked index
 */
static vector<int> nms(const vector<Rect>& rects, const vector<double>& scores, \
                       double overlap) {
  const int n = rects.size();
  vector<double> areas(n);

  typedef std::multimap<double, int> ScoreMapper;
  ScoreMapper map;
  for (int i = 0; i < n; i++) {
    map.insert(ScoreMapper::value_type(scores[i], i));
    areas[i] = rects[i].width*rects[i].height;
  }

  int picked_n = 0;
  vector<int> picked(n);
  while (map.size() != 0) {
    int last = map.rbegin()->second; // get the index of maximum score value
    picked[picked_n] = last;
    picked_n++;

    for (ScoreMapper::iterator it = map.begin(); it != map.end();) {
      int idx = it->second;
      double x1 = std::max(rects[idx].x, rects[last].x);
      double y1 = std::max(rects[idx].y, rects[last].y);
      double x2 = std::min(rects[idx].x + rects[idx].width, rects[last].x + rects[last].width);
      double y2 = std::min(rects[idx].y + rects[idx].height, rects[last].y + rects[last].height);
      double w = std::max(0., x2 - x1);
      double h = std::max(0., y2 - y1);
      double ov = w*h / (areas[idx] + areas[last] - w*h);
      if (ov > overlap) {
        ScoreMapper::iterator tmp = it;
        tmp++;
        map.erase(it);
        it = tmp;
      }
      else{
        it++;
      }
    }
  }

  picked.resize(picked_n);
  return picked;
}
Пример #9
0
int MenuBar::handle(int event) {
  const MenuItem* v;
  if (menu() && menu()->text) switch (event) {
  case FL_ENTER:
  case FL_LEAVE:
    return 1;
  case FL_PUSH:
    v = 0;
  J1:
    v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
    picked(v);
    return 1;
  case FL_SHORTCUT:
    if (visible_r()) {
      v = menu()->find_shortcut();
      if (v && v->submenu()) goto J1;
    }
    return test_shortcut() != 0;
  }
  return 0;
}
Пример #10
0
CHoloPropagLargeEditor::CHoloPropagLargeEditor(const QString & hist_file, QWidget *parent)
  : QWidget(parent),
    m_HoloPropagLarge_proc(),
    m_caption(0),
    m_cfg_file(0),
    m_binary_file(0),
    m_pb_run(0),
    m_pb_reload(0),
    m_pb_save(0),
    m_HoloPropagLarge_output(0),
    m_entry_Lambda(0),
    m_entry_Pitch(0),
    m_entry_ForceSettings(0),
    m_entry_RandomizePhase(0),
    m_entry_ImageContainsIntensity(0),
    m_entry_ImageContainsAmplitude(0),
    m_entry_ImageContainsPhase(0),
    m_entry_Input(0),
    m_entry_Target(0),
    m_entry_ImageIntensityMaximum(0),
    m_entry_ImageIntensityMinimum(0),
    m_entry_Frame(0),
    m_entry_FrameX(0),
    m_entry_FrameY(0),
    m_entry_FrameRemove(0),
    m_entry_Operations(0)
{
  /* set up DFtoHologram process */
  m_HoloPropagLarge_proc.setProcessChannelMode(QProcess::MergedChannels);  // redirect stderr to stdout
  connect(&m_HoloPropagLarge_proc, SIGNAL(readyReadStandardOutput()), SLOT(handleStdoutRead()));
  connect(&m_HoloPropagLarge_proc, SIGNAL(error(QProcess::ProcessError)), SLOT(handleProcessError(QProcess::ProcessError)));
  connect(&m_HoloPropagLarge_proc, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(handleProcessFinished(int, QProcess::ExitStatus)));

  /* create UI */
  m_caption = new QLabel(tr("HoloPropagLarge Editor"));
  m_caption->setAlignment(Qt::AlignCenter);
  m_caption->setStyleSheet("font-size: 16px; font-weight: bold;");

  m_HoloPropagLarge_output = new QTextEdit;

  QVBoxLayout *vl = new QVBoxLayout;
  vl->addSpacing(20);
  vl->addWidget(m_caption);
  vl->addSpacing(30);
  vl->addWidget(createSystemInfo());
  vl->addWidget(createGroupEntries());
  vl->addWidget(createGroupImageContains());
  vl->addWidget(createGroupFrame());
  vl->addWidget(createGroupOperations());
  vl->addWidget(m_HoloPropagLarge_output, 1);
  vl->addLayout(createButtons());
  setLayout(vl);

  if (!hist_file.isNull())
  {
    /* reload the config' history */
    loadHistory(hist_file);

    /* realod the first config file */
    reload();
  }

  /* connect a signal for automatic reloading each time a
     new config is picked */
  connect(m_cfg_file, SIGNAL(picked()), SLOT(reload()));
}
Пример #11
0
void CanvasPicker::select( const QPoint &pos, Qt::KeyboardModifiers modifiers )
{
	m_selectionPoint = pos;
	m_previousPoint = pos;

    double minDistanceMarkers = 10e10;
	double minDistanceKnots = 10e10;

	MarkerItem* markerWithMinDistance = 0;
	KnotItem* knotWithMinDistance = 0;

	int selectionType = -1;

	PlotWidget* plotWidget = dynamic_cast<PlotWidget*>( plot() );

	const QwtScaleMap xMap = plot()->canvasMap( QwtPlot::xBottom );
    const QwtScaleMap yMap = plot()->canvasMap( QwtPlot::yLeft );

    const QwtPlotItemList& itemList = plot()->itemList();
    for ( QwtPlotItemIterator it = itemList.begin(); it != itemList.end(); ++it )
    {
        if ( ( *it )->rtti() == Globals::Rtti_PlotMarker )
        {
            MarkerItem* marker = static_cast<MarkerItem*>( *it );

			const double deltaX = xMap.transform( marker->xValue() ) - pos.x();
			const double deltaY = yMap.transform( marker->yValue() ) - pos.y();
			const double distance = qSqrt( qwtSqr( deltaX ) + qwtSqr( deltaY ) );
            if ( distance < minDistanceMarkers )
			{
				minDistanceMarkers = distance;
				markerWithMinDistance = marker;
			}
		}
		else if ( ( *it )->rtti() == Globals::Rtti_PlotKnot )
		{
			KnotItem* knot = static_cast<KnotItem*>( *it );

			const double distance = qAbs( xMap.transform( knot->coordinate() ) - pos.x() );

			if( distance < minDistanceKnots )
			{
				minDistanceKnots = distance;
				knotWithMinDistance = knot;
			}
		}
    }

	// Give a priority to the markers
	if( minDistanceMarkers < Globals::SELECTION_PIXEL_TOLERANCE && markerWithMinDistance != 0 )
	{
		m_itemToPick = markerWithMinDistance;
		selectionType = Globals::Rtti_PlotMarker;
	}
	else if(  minDistanceKnots < Globals::SELECTION_PIXEL_TOLERANCE && knotWithMinDistance != 0 )
	{
		m_itemToPick = knotWithMinDistance;
		selectionType = Globals::Rtti_PlotKnot;
	}

	if( selectionType == -1 )
	{
		emit picked( modifiers, 0 );
		return;
	}

	QList<QwtPlotItem*>& listOfSelectedItems = plotWidget->listOfSelectedItems( selectionType );

	if( listOfSelectedItems.count() == 0 )
	{
		// Select and allow the user to drag and drop.
		emit picked( modifiers, m_itemToPick );

		m_typeOfItemsToDrag = selectionType;
		m_dragAndDropInProgress = true;
		m_itemToPick = 0;
	}
	else
	{
		if( listOfSelectedItems.contains( m_itemToPick ) )
		{
			// We don't know yet whether the user wants to do a selection or a drag and drop operation.
			// The picking operation will be detected in CanvasPicker::release().

			m_typeOfItemsToDrag = selectionType;
			m_dragAndDropInProgress = true;
		}
		else
		{
			emit picked( modifiers, m_itemToPick );
			m_itemToPick = 0;

			if( listOfSelectedItems.count() == 1 )
			{
				m_typeOfItemsToDrag = selectionType;
				m_dragAndDropInProgress = true;
			}
		}
	}
}
Пример #12
0
// -------------------------------------------------------------------------- //
//
void Test_Interactions::testUpdateAndPickCustom()
{
    // Setup a list of custom rate processes.
    std::vector<CustomRateProcess> processes;

    // Setup a vector of dummy processes.
    std::vector<std::string> process_elements1(1);
    process_elements1[0] = "A";

    std::vector<std::string> process_elements2(1);
    process_elements2[0] = "B";

    std::vector<std::vector<double> > process_coordinates(1, std::vector<double>(3, 0.0));

    // Possible types.
    std::map<std::string, int> possible_types;
    possible_types["A"] = 0;
    possible_types["B"] = 1;
    possible_types["V"] = 2;

    const double rate = 1.0/13.7;
    Configuration c1(process_coordinates, process_elements1, possible_types);
    Configuration c2(process_coordinates, process_elements2, possible_types);
    std::vector<int> sites_vector(1,0);
    processes.push_back(CustomRateProcess(c1,c2,rate,sites_vector, 1.0));
    processes.push_back(CustomRateProcess(c1,c2,rate,sites_vector, 1.0));
    processes.push_back(CustomRateProcess(c1,c2,rate/2.0,sites_vector, 1.0));
    processes.push_back(CustomRateProcess(c1,c2,rate,sites_vector, 1.0));
    processes.push_back(CustomRateProcess(c1,c2,rate,sites_vector, 1.0));
    processes.push_back(CustomRateProcess(c1,c2,rate,sites_vector, 1.0));

    // Fake a matching by adding sites to the processes.

    // First process, 3 sites, total rate 12
    processes[0].addSite(12,  4.0);
    processes[0].addSite(123, 7.0);
    processes[0].addSite(332, 1.0);

    // Second process, 2 sites, total rate 4
    processes[1].addSite(19, 1.0);
    processes[1].addSite(12, 3.0);

    // Third process, 4 sites, total rate  3
    processes[2].addSite(19,  1.0/4.0);
    processes[2].addSite(12,  5.0/4.0);
    processes[2].addSite(234, 2.0/4.0);
    processes[2].addSite(991, 4.0/4.0);

    // The sixth process, one site, total rate 12.
    processes[5].addSite(992, 12.0);

    // Setup the interactions object.
    RateCalculator rc;
    Interactions interactions(processes, true, rc);

    // Update the probability table.
    interactions.updateProbabilityTable();

    // Check the values of the probability table.
    const std::vector<std::pair<double, int> > & probability_table = \
        interactions.probabilityTable();

    CPPUNIT_ASSERT_EQUAL( static_cast<int>(probability_table.size()),
                          static_cast<int>(processes.size()) );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( probability_table[0].first,  12.0, 1.0e-14 );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( probability_table[1].first,  16.0, 1.0e-14 );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( probability_table[2].first,  19.0, 1.0e-14 );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( probability_table[3].first,  19.0, 1.0e-14 );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( probability_table[4].first,  19.0, 1.0e-14 );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( probability_table[5].first,  31.0, 1.0e-14 );

    CPPUNIT_ASSERT_EQUAL( probability_table[0].second, 3 );
    CPPUNIT_ASSERT_EQUAL( probability_table[1].second, 2 );
    CPPUNIT_ASSERT_EQUAL( probability_table[2].second, 4 );
    CPPUNIT_ASSERT_EQUAL( probability_table[3].second, 0 );
    CPPUNIT_ASSERT_EQUAL( probability_table[4].second, 0 );
    CPPUNIT_ASSERT_EQUAL( probability_table[5].second, 1 );


    // Make sure to seed the random number generator before we test any
    // random dependent stuff.
    seedRandom(false, 131);

    // Pick processes from this table with enough statistics should give
    // the distribution proportional to the number of available sites,
    // but with the double rate for the third process should halve
    // this entry.
    std::vector<int> picked(6,0);
    const int n_loop = 1000000;
    for (int i = 0; i < n_loop; ++i)
    {
        const int p = interactions.pickProcessIndex();

        // Make sure the picked process is not negative or too large.
        CPPUNIT_ASSERT( p >= 0 );
        CPPUNIT_ASSERT( p < static_cast<int>(probability_table.size()) );
        ++picked[p];
    }

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked[0]/n_loop,
                                  12.0/31.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked[1]/n_loop,
                                  4.0/31.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked[2]/n_loop,
                                  3.0/31.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked[3]/n_loop,
                                  0.0/31.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked[4]/n_loop,
                                  0.0/31.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked[5]/n_loop,
                                  12.0/31.0,
                                  1.0e-2 );

    // Check that picking the process twice with two different access methods and
    // a seed reset inbetween gives a reference to the same object.
    seedRandom(false, 87);
    const int p = interactions.pickProcessIndex();
    const Process & proc1 = (*interactions.processes()[p]);

    seedRandom(false, 87);
    const Process & proc2 = (*interactions.pickProcess());
    CPPUNIT_ASSERT_EQUAL( &proc1, &proc2 );

    // Alter the total rate in one of the processes and re-run the picking.
    interactions.processes()[5]->removeSite(992);
    interactions.processes()[5]->addSite(992, 24.0);

    // Update the probability table.
    interactions.updateProbabilityTable();
    std::vector<int> picked2(6,0);
    for (int i = 0; i < n_loop; ++i)
    {
        const int p = interactions.pickProcessIndex();

        // Make sure the picked process is not negative or too large.
        CPPUNIT_ASSERT( p >= 0 );
        CPPUNIT_ASSERT( p < static_cast<int>(probability_table.size()) );
        ++picked2[p];
    }

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked2[0]/n_loop,
                                  12.0/43.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked2[1]/n_loop,
                                  4.0/43.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked2[2]/n_loop,
                                  3.0/43.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked2[3]/n_loop,
                                  0.0/43.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked2[4]/n_loop,
                                  0.0/43.0,
                                  1.0e-2 );

    CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0*picked2[5]/n_loop,
                                  24.0/43.0,
                                  1.0e-2 );

    // DONE
}
Пример #13
0
void dtkColorGrid::keyPressEvent ( QKeyEvent * event )
{
    QToolTip::hideText();

    switch (event->key()) {

        case Qt::Key_Right:
            if (d->idx == -1) {
                d->row = d->col = 0;
                d->idx = 0;
            } else {
                if (++d->col == d->widthInCells)
                { d->col = 0; d->row++; }
                d->idx = index();
                if (d->idx == -1) {
                    d->row = d->col = 0;
                    d->idx = 0;
                }
            }
            repaint();
            d->hlColor = d->colors->at(d->idx);
            emit highlighted(d->hlColor);
            event->accept();
            return;

        case Qt::Key_Left:
            if (d->idx == -1) {
                d->row = d->col = 0;
                d->idx = 0;
            } else {
                if (--d->col < 0)
                { d->col = d->widthInCells-1; d->row--; }
                d->idx = index();
                if (d->idx == -1) {
                    d->row = heightInCells()-1;
                    d->idx = d->colors->size()-1;
                    d->col = d->idx % d->widthInCells;
                }
            }
            repaint();
            d->hlColor = d->colors->at(d->idx);
            emit highlighted(d->hlColor);
            event->accept();
            return;

        case Qt::Key_Up:
            if (d->idx == -1) {
                d->row = d->col = 0;
                d->idx = 0;
            } else {
                int h = heightInCells()-1;
                if (--d->row < 0)
                {
                    d->row = h;
                    if (--d->col < 0) {
                        d->row = h;
                        d->idx = d->colors->size()-1;
                        d->col = d->idx % d->widthInCells;
                    }
                }
                d->idx = index();
                if (d->idx == -1 && d->row == h) {
                    d->row--;
                    d->idx = index();
                }
                if (d->idx == -1) {
                    d->row = h;
                    d->idx = d->colors->size()-1;
                    d->col = d->idx % d->widthInCells;
                }
            }
            repaint();
            d->hlColor = d->colors->at(d->idx);
            emit highlighted(d->hlColor);
            event->accept();
            return;

        case Qt::Key_Down:
            if (d->idx == -1) {
                d->row = d->col = 0;
                d->idx = 0;
            } else {
                int h = heightInCells()-1;
                if (++d->row > h)
                { d->row = 0; d->col++; }
                d->idx = index();
                if (d->idx == -1 && d->row == h) {
                    d->row = 0; d->col++;
                    d->idx = index();
                }
                if (d->idx == -1) {
                    d->row = d->col = 0;
                    d->idx = 0;
                }
            }
            repaint();
            d->hlColor = d->colors->at(d->idx);
            emit highlighted(d->hlColor);
            event->accept();
            return;

        case Qt::Key_Return:
            if (d->idx != -1) {
                emit picked(d->selColor = d->hlColor);
                emit accepted();
            }
            event->accept();
            return;

        case Qt::Key_Escape:
            emit rejected();
            event->accept();
            return;

        default:
            event->ignore();
    }

    return QWidget::keyPressEvent(event);
}