int structPitchEditor :: v_click (double xWC, double yWC, bool dummy) { Pitch pitch = (Pitch) our data; double dyUnv = Graphics_dyMMtoWC (d_graphics, HEIGHT_UNV); double dyIntens = Graphics_dyMMtoWC (d_graphics, HEIGHT_INTENS); double frequency = (yWC - dyUnv) / (1 - dyIntens - dyUnv) * pitch -> ceiling, tmid; double minimumDf = 1e30; int cand, bestCandidate = -1; long ibestFrame; Pitch_Frame bestFrame; ibestFrame = Sampled_xToNearestIndex (pitch, xWC); if (ibestFrame < 1) ibestFrame = 1; if (ibestFrame > pitch -> nx) ibestFrame = pitch -> nx; bestFrame = & pitch -> frame [ibestFrame]; tmid = Sampled_indexToX (pitch, ibestFrame); for (cand = 1; cand <= bestFrame -> nCandidates; cand ++) { double df = frequency - bestFrame -> candidate [cand]. frequency; if (fabs (df) < minimumDf) { minimumDf = fabs (df); bestCandidate = cand; } } if (bestCandidate != -1) { double bestFrequency = bestFrame -> candidate [bestCandidate]. frequency; double distanceWC = (frequency - bestFrequency) / pitch -> ceiling * (1 - dyIntens - dyUnv); double dx_mm = Graphics_dxWCtoMM (our d_graphics, xWC - tmid), dy_mm = Graphics_dyWCtoMM (our d_graphics, distanceWC); if (bestFrequency < pitch -> ceiling && // above ceiling: ignore ((bestFrequency <= 0.0 && fabs (xWC - tmid) <= 0.5 * pitch -> dx && frequency <= 0.0) || // voiceless: click within frame (bestFrequency > 0.0 && dx_mm * dx_mm + dy_mm * dy_mm <= RADIUS * RADIUS))) // voiced: click within circle { struct structPitch_Candidate help = bestFrame -> candidate [1]; Editor_save (this, L"Change path"); bestFrame -> candidate [1] = bestFrame -> candidate [bestCandidate]; bestFrame -> candidate [bestCandidate] = help; FunctionEditor_redraw (this); our broadcastDataChanged (); our d_startSelection = our d_endSelection = tmid; // cursor will snap to candidate return 1; } else { return PitchEditor_Parent :: v_click (xWC, yWC, dummy); // move cursor or drag selection } } return PitchEditor_Parent :: v_click (xWC, yWC, dummy); // move cursor or drag selection }
void structTableEditor :: v_draw () { Table table = static_cast<Table> (data); double spacing = 2.0; // millimetres at both edges double columnWidth, cellWidth; /* * We fit 200 rows in 40 inches, which is 14.4 points per row. */ long rowmin = topRow, rowmax = rowmin + 197; long colmin = leftColumn, colmax = colmin + (kTableEditor_MAXNUM_VISIBLE_COLUMNS - 1); if (rowmax > table -> rows.size) rowmax = table -> rows.size; if (colmax > table -> numberOfColumns) colmax = table -> numberOfColumns; Graphics_clearWs (graphics.get()); Graphics_setTextAlignment (graphics.get(), Graphics_CENTRE, Graphics_HALF); Graphics_setWindow (graphics.get(), 0.0, 1.0, rowmin + 197.5, rowmin - 2.5); Graphics_setColour (graphics.get(), Graphics_SILVER); Graphics_fillRectangle (graphics.get(), 0.0, 1.0, rowmin - 2.5, rowmin - 0.5); Graphics_setColour (graphics.get(), Graphics_BLACK); Graphics_line (graphics.get(), 0.0, rowmin - 0.5, 1.0, rowmin - 0.5); Graphics_setWindow (graphics.get(), 0.0, Graphics_dxWCtoMM (graphics.get(), 1.0), rowmin + 197.5, rowmin - 2.5); /* * Determine the width of the column with the row numbers. */ columnWidth = Graphics_textWidth (graphics.get(), U"row"); for (long irow = rowmin; irow <= rowmax; irow ++) { cellWidth = Graphics_textWidth (graphics.get(), Melder_integer (irow)); if (cellWidth > columnWidth) columnWidth = cellWidth; } columnLeft [0] = columnWidth + 2 * spacing; Graphics_setColour (graphics.get(), Graphics_SILVER); Graphics_fillRectangle (graphics.get(), 0.0, columnLeft [0], rowmin - 0.5, rowmin + 197.5); Graphics_setColour (graphics.get(), Graphics_BLACK); Graphics_line (graphics.get(), columnLeft [0], rowmin - 0.5, columnLeft [0], rowmin + 197.5); /* * Determine the width of the columns. */ for (long icol = colmin; icol <= colmax; icol ++) { const char32 *columnLabel = table -> columnHeaders [icol]. label; columnWidth = Graphics_textWidth (graphics.get(), Melder_integer (icol)); if (! columnLabel) columnLabel = U""; cellWidth = Graphics_textWidth (graphics.get(), columnLabel); if (cellWidth > columnWidth) columnWidth = cellWidth; for (long irow = rowmin; irow <= rowmax; irow ++) { const char32 *cell = Table_getStringValue_Assert (table, irow, icol); Melder_assert (cell); if (cell [0] == U'\0') cell = U"?"; cellWidth = Graphics_textWidth (graphics.get(), cell); if (cellWidth > columnWidth) columnWidth = cellWidth; } columnRight [icol - colmin] = columnLeft [icol - colmin] + columnWidth + 2 * spacing; if (icol < colmax) columnLeft [icol - colmin + 1] = columnRight [icol - colmin]; } /* Text can be "graphic" or not. */ Graphics_setPercentSignIsItalic (our graphics.get(), our p_useTextStyles); Graphics_setNumberSignIsBold (our graphics.get(), our p_useTextStyles); Graphics_setCircumflexIsSuperscript (our graphics.get(), our p_useTextStyles); Graphics_setUnderscoreIsSubscript (our graphics.get(), our p_useTextStyles); /* * Show the row numbers. */ Graphics_text (graphics.get(), columnLeft [0] / 2, rowmin - 1, U"row"); for (long irow = rowmin; irow <= rowmax; irow ++) { Graphics_text (graphics.get(), columnLeft [0] / 2, irow, irow); } /* * Show the column labels. */ for (long icol = colmin; icol <= colmax; icol ++) { double mid = (columnLeft [icol - colmin] + columnRight [icol - colmin]) / 2; const char32 *columnLabel = table -> columnHeaders [icol]. label; if (! columnLabel || columnLabel [0] == U'\0') columnLabel = U"?"; Graphics_text (graphics.get(), mid, rowmin - 2, icol); Graphics_text (graphics.get(), mid, rowmin - 1, columnLabel); } /* * Show the cell contents. */ for (long irow = rowmin; irow <= rowmax; irow ++) { for (long icol = colmin; icol <= colmax; icol ++) { double mid = (columnLeft [icol - colmin] + columnRight [icol - colmin]) / 2; const char32 *cell = Table_getStringValue_Assert (table, irow, icol); Melder_assert (cell); if (cell [0] == U'\0') cell = U"?"; Graphics_text (graphics.get(), mid, irow, cell); } } }