29#include <wx/arrimpl.cpp>
49#include "androidUTIL.h"
56WX_DEFINE_OBJARRAY(RectArray);
58#define PIANO_EVENT_TIMER 73566
59#define DEFERRED_KEY_CLICK_DOWN 1
60#define DEFERRED_KEY_CLICK_UP 2
61#define INFOWIN_TIMEOUT 3
66BEGIN_EVENT_TABLE(
Piano, wxEvtHandler)
67EVT_TIMER(PIANO_EVENT_TIMER, Piano::onTimerEvent)
71 m_parentCanvas = parent;
76 m_hover_icon_last = -1;
80 m_gotPianoDown =
false;
89 m_pInVizIconBmp = NULL;
90 m_pPolyIconBmp = NULL;
91 m_pSkewIconBmp = NULL;
92 m_pTmercIconBmp = NULL;
94 SetColorScheme(GLOBAL_COLOR_SCHEME_RGB);
96 m_eventTimer.SetOwner(
this, PIANO_EVENT_TIMER);
98 m_tex = m_tex_piano_height = 0;
99 m_piano_mode = PIANO_MODE_LEGACY;
103 if (m_pInVizIconBmp)
delete m_pInVizIconBmp;
104 if (m_pPolyIconBmp)
delete m_pPolyIconBmp;
105 if (m_pSkewIconBmp)
delete m_pSkewIconBmp;
106 if (m_pTmercIconBmp)
delete m_pTmercIconBmp;
107 if (m_pVizIconBmp)
delete m_pVizIconBmp;
110void Piano::Paint(
int y, wxDC &dc, wxDC *shapeDC) {
112 Paint(y, odc, shapeDC);
115void Piano::Paint(
int y,
ocpnDC &dc, wxDC *shapeDC) {
117 shapeDC->SetBackground(*wxBLACK_BRUSH);
118 shapeDC->SetBrush(*wxWHITE_BRUSH);
119 shapeDC->SetPen(*wxWHITE_PEN);
124 if (!style->chartStatusWindowTransparent) {
125 dc.SetPen(*wxTRANSPARENT_PEN);
126 dc.SetBrush(m_backBrush);
127 dc.DrawRectangle(0, y, m_parentCanvas->GetClientSize().x, GetHeight());
132 int nKeys = m_composite_array.size();
134 wxPen ppPen(GetGlobalColor(
"CHBLK"), 1, wxPENSTYLE_SOLID);
137 for (
int i = 0; i < nKeys; i++) {
138 int chart_family = m_composite_array[i].chart_family;
139 int chart_type = m_composite_array[i].chart_type;
141 bool selected = IsAnyActiveChartInPianoKeyElement(m_composite_array[i]);
143 if (chart_type == CHART_TYPE_CM93 || chart_type == CHART_TYPE_CM93COMP) {
145 dc.SetBrush(m_scBrush);
147 dc.SetBrush(m_cBrush);
148 }
else if (chart_type == CHART_TYPE_MBTILES) {
150 dc.SetBrush(m_tileBrush);
152 dc.SetBrush(m_utileBrush);
153 }
else if (chart_family == CHART_FAMILY_VECTOR) {
155 dc.SetBrush(m_svBrush);
157 dc.SetBrush(m_vBrush);
160 dc.SetBrush(m_srBrush);
162 dc.SetBrush(m_rBrush);
165 if (m_bBusy) dc.SetBrush(m_unavailableBrush);
167 wxRect box = KeyRect[i];
171 dc.DrawRoundedRectangle(box.x, box.y, box.width, box.height,
174 shapeDC->DrawRoundedRectangle(box.x, box.y, box.width, box.height,
177 dc.DrawRectangle(box.x, box.y, box.width, box.height);
178 if (shapeDC) shapeDC->DrawRectangle(box);
181 if (IsAllEclipsedChartInPianoKeyElement(m_composite_array[i])) {
183 dc.SetBrush(m_backBrush);
185 dc.DrawRoundedRectangle(box.x + w, box.y + w, box.width - (2 * w),
186 box.height - (2 * w), box.height / 5 - 1);
191 if (InArray(m_noshow_index_array, key_db_index) && m_pInVizIconBmp &&
192 m_pInVizIconBmp->IsOk())
193 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pInVizIconBmp),
194 box.x + 4, box.y + 3,
false);
197 if (InArray(m_skew_index_array, key_db_index) && m_pSkewIconBmp &&
198 m_pSkewIconBmp->IsOk())
199 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pSkewIconBmp),
200 box.x + box.width - m_pSkewIconBmp->GetWidth() - 4,
204 if (InArray(m_tmerc_index_array, key_db_index) && m_pTmercIconBmp &&
205 m_pTmercIconBmp->IsOk())
206 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pTmercIconBmp),
207 box.x + box.width - m_pTmercIconBmp->GetWidth() - 4,
211 if (InArray(m_poly_index_array, key_db_index) && m_pPolyIconBmp &&
212 m_pPolyIconBmp->IsOk())
213 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pPolyIconBmp),
214 box.x + box.width - m_pPolyIconBmp->GetWidth() - 4,
221static void SetColor(
unsigned char color[4],
const wxBrush &brush)
223 const wxColour &c = brush.GetColour();
224 color[0] = c.Red(), color[1] = c.Green(), color[2] = c.Blue(), color[3] = 255;
231void Piano::BuildGLTexture() {
235 if (!m_pInVizIconBmp || !m_pTmercIconBmp || !m_pSkewIconBmp ||
243 if (style->chartStatusWindowTransparent)
244 tbackBrush = wxColour(1, 1, 1);
246 tbackBrush = m_backBrush;
248 wxBrush brushes[] = {m_scBrush, m_cBrush, m_svBrush,
249 m_vBrush, m_srBrush, m_rBrush,
250 m_tileBrush, m_utileBrush, m_unavailableBrush};
255 m_texPitch = ((2 * m_ref) + (2 * m_pad));
257 m_tex_piano_height = h;
258 m_texw = m_texPitch * 3;
260 m_texh = ((
sizeof brushes) / (
sizeof *brushes)) * h;
263 m_texh = NextPow2(m_texh);
264 m_texw = NextPow2(m_texw);
266 if (!m_tex) glGenTextures(1, (GLuint *)&m_tex);
268 glBindTexture(GL_TEXTURE_2D, m_tex);
269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
272 wxBitmap bmp(m_texw, m_texh);
275 dc.SetPen(*wxTRANSPARENT_PEN);
276 dc.SetBrush(tbackBrush);
277 dc.DrawRectangle(0, 0, m_texw, m_texh);
280 double nominal_line_width_pix = floor(g_Platform->GetDisplayDPmm() / 2.0);
282 nominal_line_width_pix = wxMax(1.0, nominal_line_width_pix);
285 wxPen ppPen(GetGlobalColor(
"CHBLK"), nominal_line_width_pix,
288 for (
unsigned int b = 0; b < (
sizeof brushes) / (
sizeof *brushes); b++) {
289 unsigned int x = 0, y = h * b;
291 dc.SetBrush(brushes[b]);
294 dc.DrawRectangle(x + m_pad, y + v, 2 * m_ref, h - 2 * v);
297 dc.DrawRoundedRectangle(x + m_pad, y + v, 2 * m_ref, h - 2 * v, m_radius);
302 dc.DrawRoundedRectangle(x + m_pad, y + v, 2 * m_ref, h - 2 * v, m_radius);
303 dc.SetBrush(m_backBrush);
304 dc.DrawRoundedRectangle(x + m_pad + w, y + v + w, (2 * m_ref) - (2 * w),
306 m_radius * (h - 2 * v - 2 * w) /
310 dc.SelectObject(wxNullBitmap);
312 wxImage image = bmp.ConvertToImage();
314 unsigned char *data =
new unsigned char[4 * m_texw * m_texh], *d = data,
315 *e = image.GetData(), *a = image.GetAlpha();
316 for (
unsigned int i = 0; i < m_texw * m_texh; i++) {
317 if (style->chartStatusWindowTransparent && e[0] == 1 && e[1] == 1 &&
323 memcpy(d, e, 3), d += 4, e += 3;
326 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_texw, m_texh, 0, GL_RGBA,
327 GL_UNSIGNED_BYTE, data);
331 wxBitmap *bitmaps[] = {m_pInVizIconBmp, m_pTmercIconBmp, m_pSkewIconBmp,
334 for (
unsigned int i = 0; i < 4; i++) {
335 int iw = bitmaps[i]->GetWidth(), ih = bitmaps[i]->GetHeight();
337 wxImage im = bitmaps[i]->ConvertToImage();
338 unsigned char *data =
new unsigned char[4 * iw * ih], *d = data,
339 *e = im.GetData(), *a = im.GetAlpha();
340 for (
int j = 0; j < iw * ih; j++) {
341 memcpy(d, e, 3), d += 3, e += 3;
345 int off = ((
sizeof brushes) / (
sizeof *brushes)) * h + m_ref * i;
346 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, off, iw, ih, GL_RGBA, GL_UNSIGNED_BYTE,
353void Piano::DrawGL(
int off) {
return DrawGLSL(off); }
354void Piano::DrawGLSL(
int off) {
356 unsigned int w = m_parentCanvas->GetClientSize().x *
357 m_parentCanvas->GetContentScaleFactor();
359 unsigned int endx = 0;
361 if (
static_cast<int>(m_tex_piano_height) != h) BuildGLTexture();
363 if (
static_cast<int>(m_tex_piano_height) != h)
return;
365 int y1 = off, y2 = y1 + h;
367 int nKeys = m_composite_array.size();
371 float *texcoords =
new float[(nKeys * 3 + 1) * 4 * 2],
372 *coords =
new float[(nKeys * 3 + 1) * 4 * 2];
377 for (
int i = 0; i < nKeys; i++) {
379 int chart_family = m_composite_array[i].chart_family;
380 int chart_type = m_composite_array[i].chart_type;
382 if (chart_type == CHART_TYPE_CM93 || chart_type == CHART_TYPE_CM93COMP)
384 else if (chart_type == CHART_TYPE_MBTILES)
386 else if (chart_family == CHART_FAMILY_VECTOR)
391 if (!IsAnyActiveChartInPianoKeyElement(m_composite_array[i]))
394 wxRect box = KeyRect[i];
395 float y = h * b, v1 = (y + .5) / m_texh, v2 = (y + h - .5) / m_texh;
399 const float texcord[6] = {0,
404 (float)m_texPitch - 1};
408 if (IsAllEclipsedChartInPianoKeyElement(m_composite_array[i]))
417 int x1 = box.x, x2 = x1 + box.width, w = 2 * uindex + 1;
418 while (x1 + w > x2 - w && uindex > 0) uindex--, w -= 2;
422 int x[6] = {x1 - 3, x1 + m_ref, x2 - m_ref, x2 + 3};
426 int avg = (x[1] + x[2]) / 2;
430 for (
int i = 0; i < 3; i++) {
431 float u1 = ((uindex * m_texPitch) + texcord[2 * i] + .5) / m_texw,
432 u2 = ((uindex * m_texPitch) + texcord[2 * i + 1] + .5) / m_texw;
433 int x1 = x[i], x2 = x[i + 1];
434 texcoords[tc++] = u1, texcoords[tc++] = v1, coords[vc++] = x1,
436 texcoords[tc++] = u2, texcoords[tc++] = v1, coords[vc++] = x2,
438 texcoords[tc++] = u2, texcoords[tc++] = v2, coords[vc++] = x2,
440 texcoords[tc++] = u1, texcoords[tc++] = v2, coords[vc++] = x1,
448 if (!style->chartStatusWindowTransparent && endx < w) {
449 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = endx,
451 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = w,
453 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = w,
455 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = endx,
459 glBindTexture(GL_TEXTURE_2D, m_tex);
461 glEnable(GL_TEXTURE_2D);
464 m_parentCanvas->GetglCanvas()->RenderTextures(
465 m_parentCanvas->GetglCanvas()->m_gldc, coords, texcoords, vc / 2,
466 m_parentCanvas->GetpVP());
472 if (GetPianoMode() == PIANO_MODE_LEGACY) {
474 for (
int i = 0; i < nKeys; i++) {
475 int key_db_index = m_composite_array[i].dbindex_list[0];
477 if (-1 == key_db_index)
continue;
479 wxRect box = KeyRect[i];
481 wxBitmap *bitmaps[] = {m_pInVizIconBmp, m_pTmercIconBmp, m_pSkewIconBmp,
484 if (InArray(m_noshow_index_array, key_db_index))
487 if (InArray(m_skew_index_array, key_db_index))
489 else if (InArray(m_tmerc_index_array, key_db_index))
491 else if (InArray(m_poly_index_array, key_db_index))
497 int x1, y1, iw = bitmaps[index]->GetWidth(),
498 ih = bitmaps[index]->GetHeight();
499 if (InArray(m_noshow_index_array, key_db_index))
500 x1 = box.x + 4, y1 = box.y + 3;
502 x1 = box.x + box.width - iw - 4, y1 = box.y + 2;
505 int x2 = x1 + iw, y2 = y1 + ih;
507 wxBrush brushes[] = {m_scBrush, m_cBrush, m_svBrush,
508 m_vBrush, m_srBrush, m_rBrush,
509 m_tileBrush, m_utileBrush, m_unavailableBrush};
511 float yoff = ((
sizeof brushes) / (
sizeof *brushes)) * h + 16 * index;
512 float u1 = 0, u2 = (float)iw / m_texw;
513 float v1 = yoff / m_texh, v2 = (yoff + ih) / m_texh;
515 texcoords[tc++] = u1, texcoords[tc++] = v1, coords[vc++] = x1,
517 texcoords[tc++] = u2, texcoords[tc++] = v1, coords[vc++] = x2,
519 texcoords[tc++] = u2, texcoords[tc++] = v2, coords[vc++] = x2,
521 texcoords[tc++] = u1, texcoords[tc++] = v2, coords[vc++] = x1,
524 glEnable(GL_TEXTURE_2D);
525 glBindTexture(GL_TEXTURE_2D, m_tex);
528 m_parentCanvas->GetglCanvas()->RenderTextures(
529 m_parentCanvas->GetglCanvas()->m_gldc, coords, texcoords, vc / 2,
530 m_parentCanvas->GetpVP());
535 glDisable(GL_TEXTURE_2D);
541void Piano::SetColorScheme(ColorScheme cs) {
544 m_backBrush = wxBrush(GetGlobalColor(
"UIBDR"), wxBRUSHSTYLE_SOLID);
546 m_rBrush = wxBrush(GetGlobalColor(
"BLUE2"),
549 wxBrush(GetGlobalColor(
"BLUE1"), wxBRUSHSTYLE_SOLID);
551 m_vBrush = wxBrush(GetGlobalColor(
"GREEN2"),
553 m_svBrush = wxBrush(GetGlobalColor(
"GREEN1"),
556 m_utileBrush = wxBrush(GetGlobalColor(
"VIO01"),
559 wxBrush(GetGlobalColor(
"VIO02"), wxBRUSHSTYLE_SOLID);
561 m_cBrush = wxBrush(GetGlobalColor(
"YELO2"),
564 wxBrush(GetGlobalColor(
"YELO1"), wxBRUSHSTYLE_SOLID);
566 m_unavailableBrush = wxBrush(GetGlobalColor(
"UINFD"),
569 m_tex_piano_height = 0;
572void Piano::ShowBusy(
bool busy) {
579 for (
auto &index : m_active_index_array) {
580 auto found = find(pke.dbindex_list.begin(), pke.dbindex_list.end(), index);
581 if (found != pke.dbindex_list.end())
return true;
587 bool bfound_all =
true;
588 for (
auto &index : pke.dbindex_list) {
589 auto found = find(m_eclipsed_index_array.begin(),
590 m_eclipsed_index_array.end(), index);
591 if (found == m_eclipsed_index_array.end()) bfound_all =
false;
596void Piano::SetKeyArray(std::vector<int> ¢er_array,
597 std::vector<int> &full_array) {
600 if (center_array.size()) {
601 int refd = m_parentCanvas->GetCharWidth();
603 int nkeys = center_array.size();
604 int key_width = (m_width_avail / refd) / nkeys;
606 m_piano_mode = PIANO_MODE_COMPOSITE;
607 m_key_array = full_array;
609 m_piano_mode = PIANO_MODE_LEGACY;
610 m_key_array = center_array;
613 m_piano_mode = PIANO_MODE_LEGACY;
618 m_composite_array.clear();
620 if (m_piano_mode == PIANO_MODE_COMPOSITE) {
621 for (
size_t i = 0; i < m_key_array.size(); i++) {
623 ChartData->GetChartTableEntry(m_key_array[i]);
624 int scale = cte.GetScale();
625 auto order = std::pow(10, std::floor(std::log10(
scale)));
628 int chart_type = cte.GetChartType();
629 int chart_family = cte.GetChartFamily();
635 if ((cte.GetChartFamily() == CHART_FAMILY_VECTOR) ||
636 ((cte.GetChartFamily() == CHART_FAMILY_RASTER) &&
637 (cte.GetChartType() != CHART_TYPE_MBTILES))) {
639 return ((
scale == pke.chart_scale) &&
640 (chart_family == pke.chart_family));
642 auto found = find_if(m_composite_array.begin(), m_composite_array.end(),
644 if (found == m_composite_array.end()) {
646 new_pke.chart_scale =
scale;
647 new_pke.chart_family = (ChartFamilyEnum)cte.GetChartFamily();
648 new_pke.chart_type = (ChartTypeEnum)cte.GetChartType();
649 new_pke.dbindex_list.push_back(m_key_array[i]);
650 m_composite_array.push_back(new_pke);
653 ex_pke.dbindex_list.push_back(m_key_array[i]);
657 new_pke.chart_scale =
scale;
658 new_pke.chart_family = (ChartFamilyEnum)cte.GetChartFamily();
659 new_pke.chart_type = (ChartTypeEnum)cte.GetChartType();
660 new_pke.dbindex_list.push_back(m_key_array[i]);
661 m_composite_array.push_back(new_pke);
665 for (
size_t i = 0; i < m_key_array.size(); i++) {
667 ChartData->GetChartTableEntry(m_key_array[i]);
668 int scale = cte.GetScale();
669 int chart_type = cte.GetChartType();
671 new_pke.chart_scale =
scale;
672 new_pke.chart_family = (ChartFamilyEnum)cte.GetChartFamily();
673 new_pke.chart_type = (ChartTypeEnum)cte.GetChartType();
674 new_pke.dbindex_list.push_back(m_key_array[i]);
675 m_composite_array.push_back(new_pke);
680 std::sort(m_composite_array.begin(), m_composite_array.end(),
682 return a.chart_scale < b.chart_scale;
686void Piano::SetNoshowIndexArray(std::vector<int> array) {
687 m_noshow_index_array = array;
690void Piano::AddNoshowIndexArray(std::vector<int> array) {
691 for (
unsigned int i = 0; i < array.size(); i++) {
692 m_noshow_index_array.push_back(array[i]);
696void Piano::SetActiveKeyArray(std::vector<int> array) {
697 m_active_index_array = array;
700void Piano::SetEclipsedIndexArray(std::vector<int> array) {
701 m_eclipsed_index_array = array;
704void Piano::SetSkewIndexArray(std::vector<int> array) {
705 m_skew_index_array = array;
708void Piano::SetTmercIndexArray(std::vector<int> array) {
709 m_tmerc_index_array = array;
712void Piano::SetPolyIndexArray(std::vector<int> array) {
713 m_poly_index_array = array;
716bool Piano::InArray(std::vector<int> &array,
int key) {
717 for (
unsigned int ino = 0; ino < array.size(); ino++)
718 if (array[ino] == key)
return true;
722wxString Piano::GetStateHash() {
725 for (
unsigned int i = 0; i < m_key_array.size(); i++) {
727 a.Printf(
"%dK", m_key_array[i]);
730 for (
unsigned int i = 0; i < m_noshow_index_array.size(); i++) {
732 a.Printf(
"%dN", m_noshow_index_array[i]);
735 for (
unsigned int i = 0; i < m_active_index_array.size(); i++) {
737 a.Printf(
"%dA", m_active_index_array[i]);
740 for (
unsigned int i = 0; i < m_eclipsed_index_array.size(); i++) {
742 a.Printf(
"%dE", m_eclipsed_index_array[i]);
745 for (
unsigned int i = 0; i < m_skew_index_array.size(); i++) {
747 a.Printf(
"%dW", m_skew_index_array[i]);
750 for (
unsigned int i = 0; i < m_tmerc_index_array.size(); i++) {
752 a.Printf(
"%dM", m_tmerc_index_array[i]);
755 for (
unsigned int i = 0; i < m_poly_index_array.size(); i++) {
757 a.Printf(
"%dP", m_poly_index_array[i]);
764wxString &Piano::GenerateAndStoreNewHash() {
765 m_hash = GetStateHash();
769wxString &Piano::GetStoredHash() {
return m_hash; }
771void Piano::FormatKeys() {
773 int width = m_parentCanvas->GetClientSize().x;
775 if (g_bopengl) width *= m_parentCanvas->GetContentScaleFactor();
777 width *= m_parentCanvas->GetContentScaleFactor();
781 wxSize mui_tool_size = g_StyleManager->GetCurrentStyle()->GetToolSize();
783 mui_tool_size = wxSize(mui_tool_size.x * 1.25, mui_tool_size.y * 1.25);
785 int mui_bar_width_est = mui_tool_size.x * 8 * g_toolbar_scalefactor;
787 if (m_parentCanvas->GetClientSize().x < m_parentCanvas->GetClientSize().y) {
798 m_width_avail = width;
800 int height = GetHeight();
802 int nKeys = m_composite_array.size();
803 int kw = style->chartStatusIconWidth;
805 if (!kw) kw = width / nKeys;
814 for (
int i = 0; i < nKeys; i++) {
815 wxRect r((i * kw) + 3, 2, kw - 6, height - 4);
816 KeyRect.push_back(r);
817 m_width = r.x + r.width;
823wxPoint Piano::GetKeyOrigin(
int key_index) {
824 if ((key_index >= 0) && (key_index <= (
int)m_key_array.size() - 1)) {
825 wxRect box = KeyRect[key_index];
826 return wxPoint(box.x, box.y);
828 return wxPoint(-1, -1);
831bool Piano::MouseEvent(wxMouseEvent &event) {
833 event.GetPosition(&x, &y);
842 int ytop = m_parentCanvas->GetCanvasHeight() - GetHeight();
844 if (!g_bopengl) ytop = m_parentCanvas->GetClientSize().y - GetHeight();
847 if (event.Leaving() || (y < ytop) || (x > GetWidth())) {
848 if (m_bleaving)
return false;
856 int sel_dbindex = -1;
858 for (
int i = 0; i < m_nRegions; i++) {
859 if (KeyRect[i].Contains(x, 6)) {
861 sel_dbindex = m_key_array[i];
867 if (event.LeftDown()) {
868 if (-1 != sel_index) {
869 m_action = DEFERRED_KEY_CLICK_DOWN;
871 m_eventTimer.Start(10, wxTIMER_ONE_SHOT);
874 if (event.LeftUp()) {
875 if (-1 != sel_index) {
876 m_click_sel_index = sel_index;
877 if (!m_eventTimer.IsRunning()) {
878 m_action = DEFERRED_KEY_CLICK_UP;
879 m_eventTimer.Start(10, wxTIMER_ONE_SHOT);
882 }
else if (event.RightDown()) {
883 if (sel_index != m_hover_last) {
885 m_parentCanvas->HandlePianoRollover(
886 sel_index, m_composite_array[sel_index].dbindex_list,
887 m_composite_array[sel_index].dbindex_list.size(),
888 m_composite_array[sel_index].chart_scale);
889 m_hover_last = sel_index;
894 }
else if (event.ButtonUp()) {
895 m_parentCanvas->ClearPianoRollover();
900 m_parentCanvas->ClearPianoRollover();
902 }
else if (event.LeftDown()) {
903 if (-1 != sel_index) {
904 m_parentCanvas->HandlePianoClick(
905 sel_index, m_composite_array[sel_index].dbindex_list);
907 m_parentCanvas->Raise();
910 }
else if (event.RightDown()) {
911 if (-1 != sel_index) {
912 m_parentCanvas->HandlePianoRClick(
913 x, y, sel_index, m_composite_array[sel_index].dbindex_list);
914 m_parentCanvas->Raise();
917 }
else if (!event.ButtonUp()) {
918 if (sel_index != m_hover_last) {
920 m_parentCanvas->HandlePianoRollover(
921 sel_index, m_composite_array[sel_index].dbindex_list,
922 m_composite_array[sel_index].dbindex_list.size(),
923 m_composite_array[sel_index].chart_scale);
925 m_hover_last = sel_index;
944void Piano::ResetRollover() {
946 m_hover_icon_last = -1;
948 m_gotPianoDown =
false;
951int Piano::GetHeight() {
954 if (g_bopengl) height *= m_parentCanvas->GetContentScaleFactor();
957 double size_mult = exp(g_GUIScaleFactor * 0.0953101798043);
959 height = wxMin(height, 100);
960 height = wxMax(height, 10);
962 height *= g_Platform->GetDisplayDensityFactor();
965 height = wxMax(height, 4 * g_Platform->GetDisplayDPmm());
973int Piano::GetWidth() {
return m_width; }
975void Piano::onTimerEvent(wxTimerEvent &event) {
977 case DEFERRED_KEY_CLICK_DOWN:
978 m_gotPianoDown =
true;
980 case DEFERRED_KEY_CLICK_UP:
982 if ((m_hover_last >= 0) || !m_gotPianoDown) {
983 m_parentCanvas->ClearPianoRollover();
986 m_parentCanvas->HandlePianoClick(
988 m_composite_array[m_click_sel_index].dbindex_list);
989 m_gotPianoDown =
false;
992 case INFOWIN_TIMEOUT:
993 m_parentCanvas->ClearPianoRollover();
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
Generic Chart canvas base.
ChartCanvas - Main chart display and interaction component.
Device context class that can use either wxDC or OpenGL for drawing.
Global color handling by name.
Global variables stored in configuration file.
Extern C linked utilities.
OpenGL chart rendering canvas.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
PlugIn Object Definition/API.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
Layer to use wxDC or opengl.
Represents an entry in the chart table, containing information about a single chart.