29#include <wx/arrimpl.cpp>
48#include "androidUTIL.h"
55WX_DEFINE_OBJARRAY(RectArray);
57#define PIANO_EVENT_TIMER 73566
58#define DEFERRED_KEY_CLICK_DOWN 1
59#define DEFERRED_KEY_CLICK_UP 2
60#define INFOWIN_TIMEOUT 3
65BEGIN_EVENT_TABLE(
Piano, wxEvtHandler)
66EVT_TIMER(PIANO_EVENT_TIMER, Piano::onTimerEvent)
70 m_parentCanvas = parent;
75 m_hover_icon_last = -1;
79 m_gotPianoDown =
false;
88 m_pInVizIconBmp = NULL;
89 m_pPolyIconBmp = NULL;
90 m_pSkewIconBmp = NULL;
91 m_pTmercIconBmp = NULL;
93 SetColorScheme(GLOBAL_COLOR_SCHEME_RGB);
95 m_eventTimer.SetOwner(
this, PIANO_EVENT_TIMER);
97 m_tex = m_tex_piano_height = 0;
98 m_piano_mode = PIANO_MODE_LEGACY;
102 if (m_pInVizIconBmp)
delete m_pInVizIconBmp;
103 if (m_pPolyIconBmp)
delete m_pPolyIconBmp;
104 if (m_pSkewIconBmp)
delete m_pSkewIconBmp;
105 if (m_pTmercIconBmp)
delete m_pTmercIconBmp;
106 if (m_pVizIconBmp)
delete m_pVizIconBmp;
109void Piano::Paint(
int y, wxDC &dc, wxDC *shapeDC) {
111 Paint(y, odc, shapeDC);
114void Piano::Paint(
int y,
ocpnDC &dc, wxDC *shapeDC) {
116 shapeDC->SetBackground(*wxBLACK_BRUSH);
117 shapeDC->SetBrush(*wxWHITE_BRUSH);
118 shapeDC->SetPen(*wxWHITE_PEN);
123 if (!style->chartStatusWindowTransparent) {
124 dc.SetPen(*wxTRANSPARENT_PEN);
125 dc.SetBrush(m_backBrush);
126 dc.DrawRectangle(0, y, m_parentCanvas->GetClientSize().x, GetHeight());
131 int nKeys = m_composite_array.size();
133 wxPen ppPen(GetGlobalColor(
"CHBLK"), 1, wxPENSTYLE_SOLID);
136 for (
int i = 0; i < nKeys; i++) {
137 int chart_family = m_composite_array[i].chart_family;
138 int chart_type = m_composite_array[i].chart_type;
140 bool selected = IsAnyActiveChartInPianoKeyElement(m_composite_array[i]);
142 if (chart_type == CHART_TYPE_CM93 || chart_type == CHART_TYPE_CM93COMP) {
144 dc.SetBrush(m_scBrush);
146 dc.SetBrush(m_cBrush);
147 }
else if (chart_type == CHART_TYPE_MBTILES) {
149 dc.SetBrush(m_tileBrush);
151 dc.SetBrush(m_utileBrush);
152 }
else if (chart_family == CHART_FAMILY_VECTOR) {
154 dc.SetBrush(m_svBrush);
156 dc.SetBrush(m_vBrush);
159 dc.SetBrush(m_srBrush);
161 dc.SetBrush(m_rBrush);
164 if (m_bBusy) dc.SetBrush(m_unavailableBrush);
166 wxRect box = KeyRect[i];
170 dc.DrawRoundedRectangle(box.x, box.y, box.width, box.height,
173 shapeDC->DrawRoundedRectangle(box.x, box.y, box.width, box.height,
176 dc.DrawRectangle(box.x, box.y, box.width, box.height);
177 if (shapeDC) shapeDC->DrawRectangle(box);
180 if (IsAllEclipsedChartInPianoKeyElement(m_composite_array[i])) {
182 dc.SetBrush(m_backBrush);
184 dc.DrawRoundedRectangle(box.x + w, box.y + w, box.width - (2 * w),
185 box.height - (2 * w), box.height / 5 - 1);
190 if (InArray(m_noshow_index_array, key_db_index) && m_pInVizIconBmp &&
191 m_pInVizIconBmp->IsOk())
192 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pInVizIconBmp),
193 box.x + 4, box.y + 3,
false);
196 if (InArray(m_skew_index_array, key_db_index) && m_pSkewIconBmp &&
197 m_pSkewIconBmp->IsOk())
198 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pSkewIconBmp),
199 box.x + box.width - m_pSkewIconBmp->GetWidth() - 4,
203 if (InArray(m_tmerc_index_array, key_db_index) && m_pTmercIconBmp &&
204 m_pTmercIconBmp->IsOk())
205 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pTmercIconBmp),
206 box.x + box.width - m_pTmercIconBmp->GetWidth() - 4,
210 if (InArray(m_poly_index_array, key_db_index) && m_pPolyIconBmp &&
211 m_pPolyIconBmp->IsOk())
212 dc.DrawBitmap(ConvertTo24Bit(dc.GetBrush().GetColour(), *m_pPolyIconBmp),
213 box.x + box.width - m_pPolyIconBmp->GetWidth() - 4,
220static void SetColor(
unsigned char color[4],
const wxBrush &brush)
222 const wxColour &c = brush.GetColour();
223 color[0] = c.Red(), color[1] = c.Green(), color[2] = c.Blue(), color[3] = 255;
230void Piano::BuildGLTexture() {
234 if (!m_pInVizIconBmp || !m_pTmercIconBmp || !m_pSkewIconBmp ||
242 if (style->chartStatusWindowTransparent)
243 tbackBrush = wxColour(1, 1, 1);
245 tbackBrush = m_backBrush;
247 wxBrush brushes[] = {m_scBrush, m_cBrush, m_svBrush,
248 m_vBrush, m_srBrush, m_rBrush,
249 m_tileBrush, m_utileBrush, m_unavailableBrush};
254 m_texPitch = ((2 * m_ref) + (2 * m_pad));
256 m_tex_piano_height = h;
257 m_texw = m_texPitch * 3;
259 m_texh = ((
sizeof brushes) / (
sizeof *brushes)) * h;
262 m_texh = NextPow2(m_texh);
263 m_texw = NextPow2(m_texw);
265 if (!m_tex) glGenTextures(1, (GLuint *)&m_tex);
267 glBindTexture(GL_TEXTURE_2D, m_tex);
268 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
271 wxBitmap bmp(m_texw, m_texh);
274 dc.SetPen(*wxTRANSPARENT_PEN);
275 dc.SetBrush(tbackBrush);
276 dc.DrawRectangle(0, 0, m_texw, m_texh);
279 double nominal_line_width_pix = floor(g_Platform->GetDisplayDPmm() / 2.0);
281 nominal_line_width_pix = wxMax(1.0, nominal_line_width_pix);
284 wxPen ppPen(GetGlobalColor(
"CHBLK"), nominal_line_width_pix,
287 for (
unsigned int b = 0; b < (
sizeof brushes) / (
sizeof *brushes); b++) {
288 unsigned int x = 0, y = h * b;
290 dc.SetBrush(brushes[b]);
293 dc.DrawRectangle(x + m_pad, y + v, 2 * m_ref, h - 2 * v);
296 dc.DrawRoundedRectangle(x + m_pad, y + v, 2 * m_ref, h - 2 * v, m_radius);
301 dc.DrawRoundedRectangle(x + m_pad, y + v, 2 * m_ref, h - 2 * v, m_radius);
302 dc.SetBrush(m_backBrush);
303 dc.DrawRoundedRectangle(x + m_pad + w, y + v + w, (2 * m_ref) - (2 * w),
305 m_radius * (h - 2 * v - 2 * w) /
309 dc.SelectObject(wxNullBitmap);
311 wxImage image = bmp.ConvertToImage();
313 unsigned char *data =
new unsigned char[4 * m_texw * m_texh], *d = data,
314 *e = image.GetData(), *a = image.GetAlpha();
315 for (
unsigned int i = 0; i < m_texw * m_texh; i++) {
316 if (style->chartStatusWindowTransparent && e[0] == 1 && e[1] == 1 &&
322 memcpy(d, e, 3), d += 4, e += 3;
325 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_texw, m_texh, 0, GL_RGBA,
326 GL_UNSIGNED_BYTE, data);
330 wxBitmap *bitmaps[] = {m_pInVizIconBmp, m_pTmercIconBmp, m_pSkewIconBmp,
333 for (
unsigned int i = 0; i < 4; i++) {
334 int iw = bitmaps[i]->GetWidth(), ih = bitmaps[i]->GetHeight();
336 wxImage im = bitmaps[i]->ConvertToImage();
337 unsigned char *data =
new unsigned char[4 * iw * ih], *d = data,
338 *e = im.GetData(), *a = im.GetAlpha();
339 for (
int j = 0; j < iw * ih; j++) {
340 memcpy(d, e, 3), d += 3, e += 3;
344 int off = ((
sizeof brushes) / (
sizeof *brushes)) * h + m_ref * i;
345 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, off, iw, ih, GL_RGBA, GL_UNSIGNED_BYTE,
352void Piano::DrawGL(
int off) {
return DrawGLSL(off); }
353void Piano::DrawGLSL(
int off) {
355 unsigned int w = m_parentCanvas->GetClientSize().x *
356 m_parentCanvas->GetContentScaleFactor();
358 unsigned int endx = 0;
360 if (
static_cast<int>(m_tex_piano_height) != h) BuildGLTexture();
362 if (
static_cast<int>(m_tex_piano_height) != h)
return;
364 int y1 = off, y2 = y1 + h;
366 int nKeys = m_composite_array.size();
370 float *texcoords =
new float[(nKeys * 3 + 1) * 4 * 2],
371 *coords =
new float[(nKeys * 3 + 1) * 4 * 2];
376 for (
int i = 0; i < nKeys; i++) {
378 int chart_family = m_composite_array[i].chart_family;
379 int chart_type = m_composite_array[i].chart_type;
381 if (chart_type == CHART_TYPE_CM93 || chart_type == CHART_TYPE_CM93COMP)
383 else if (chart_type == CHART_TYPE_MBTILES)
385 else if (chart_family == CHART_FAMILY_VECTOR)
390 if (!IsAnyActiveChartInPianoKeyElement(m_composite_array[i]))
393 wxRect box = KeyRect[i];
394 float y = h * b, v1 = (y + .5) / m_texh, v2 = (y + h - .5) / m_texh;
398 const float texcord[6] = {0,
403 (float)m_texPitch - 1};
407 if (IsAllEclipsedChartInPianoKeyElement(m_composite_array[i]))
416 int x1 = box.x, x2 = x1 + box.width, w = 2 * uindex + 1;
417 while (x1 + w > x2 - w && uindex > 0) uindex--, w -= 2;
421 int x[6] = {x1 - 3, x1 + m_ref, x2 - m_ref, x2 + 3};
425 int avg = (x[1] + x[2]) / 2;
429 for (
int i = 0; i < 3; i++) {
430 float u1 = ((uindex * m_texPitch) + texcord[2 * i] + .5) / m_texw,
431 u2 = ((uindex * m_texPitch) + texcord[2 * i + 1] + .5) / m_texw;
432 int x1 = x[i], x2 = x[i + 1];
433 texcoords[tc++] = u1, texcoords[tc++] = v1, coords[vc++] = x1,
435 texcoords[tc++] = u2, texcoords[tc++] = v1, coords[vc++] = x2,
437 texcoords[tc++] = u2, texcoords[tc++] = v2, coords[vc++] = x2,
439 texcoords[tc++] = u1, texcoords[tc++] = v2, coords[vc++] = x1,
447 if (!style->chartStatusWindowTransparent && endx < w) {
448 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = endx,
450 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = w,
452 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = w,
454 texcoords[tc++] = 0, texcoords[tc++] = 0, coords[vc++] = endx,
458 glBindTexture(GL_TEXTURE_2D, m_tex);
460 glEnable(GL_TEXTURE_2D);
463 m_parentCanvas->GetglCanvas()->RenderTextures(
464 m_parentCanvas->GetglCanvas()->m_gldc, coords, texcoords, vc / 2,
465 m_parentCanvas->GetpVP());
471 if (GetPianoMode() == PIANO_MODE_LEGACY) {
473 for (
int i = 0; i < nKeys; i++) {
474 int key_db_index = m_composite_array[i].dbindex_list[0];
476 if (-1 == key_db_index)
continue;
478 wxRect box = KeyRect[i];
480 wxBitmap *bitmaps[] = {m_pInVizIconBmp, m_pTmercIconBmp, m_pSkewIconBmp,
483 if (InArray(m_noshow_index_array, key_db_index))
486 if (InArray(m_skew_index_array, key_db_index))
488 else if (InArray(m_tmerc_index_array, key_db_index))
490 else if (InArray(m_poly_index_array, key_db_index))
496 int x1, y1, iw = bitmaps[index]->GetWidth(),
497 ih = bitmaps[index]->GetHeight();
498 if (InArray(m_noshow_index_array, key_db_index))
499 x1 = box.x + 4, y1 = box.y + 3;
501 x1 = box.x + box.width - iw - 4, y1 = box.y + 2;
504 int x2 = x1 + iw, y2 = y1 + ih;
506 wxBrush brushes[] = {m_scBrush, m_cBrush, m_svBrush,
507 m_vBrush, m_srBrush, m_rBrush,
508 m_tileBrush, m_utileBrush, m_unavailableBrush};
510 float yoff = ((
sizeof brushes) / (
sizeof *brushes)) * h + 16 * index;
511 float u1 = 0, u2 = (float)iw / m_texw;
512 float v1 = yoff / m_texh, v2 = (yoff + ih) / m_texh;
514 texcoords[tc++] = u1, texcoords[tc++] = v1, coords[vc++] = x1,
516 texcoords[tc++] = u2, texcoords[tc++] = v1, coords[vc++] = x2,
518 texcoords[tc++] = u2, texcoords[tc++] = v2, coords[vc++] = x2,
520 texcoords[tc++] = u1, texcoords[tc++] = v2, coords[vc++] = x1,
523 glEnable(GL_TEXTURE_2D);
524 glBindTexture(GL_TEXTURE_2D, m_tex);
527 m_parentCanvas->GetglCanvas()->RenderTextures(
528 m_parentCanvas->GetglCanvas()->m_gldc, coords, texcoords, vc / 2,
529 m_parentCanvas->GetpVP());
534 glDisable(GL_TEXTURE_2D);
540void Piano::SetColorScheme(ColorScheme cs) {
543 m_backBrush = wxBrush(GetGlobalColor(
"UIBDR"), wxBRUSHSTYLE_SOLID);
545 m_rBrush = wxBrush(GetGlobalColor(
"BLUE2"),
548 wxBrush(GetGlobalColor(
"BLUE1"), wxBRUSHSTYLE_SOLID);
550 m_vBrush = wxBrush(GetGlobalColor(
"GREEN2"),
552 m_svBrush = wxBrush(GetGlobalColor(
"GREEN1"),
555 m_utileBrush = wxBrush(GetGlobalColor(
"VIO01"),
558 wxBrush(GetGlobalColor(
"VIO02"), wxBRUSHSTYLE_SOLID);
560 m_cBrush = wxBrush(GetGlobalColor(
"YELO2"),
563 wxBrush(GetGlobalColor(
"YELO1"), wxBRUSHSTYLE_SOLID);
565 m_unavailableBrush = wxBrush(GetGlobalColor(
"UINFD"),
568 m_tex_piano_height = 0;
571void Piano::ShowBusy(
bool busy) {
578 for (
auto &index : m_active_index_array) {
579 auto found = find(pke.dbindex_list.begin(), pke.dbindex_list.end(), index);
580 if (found != pke.dbindex_list.end())
return true;
586 bool bfound_all =
true;
587 for (
auto &index : pke.dbindex_list) {
588 auto found = find(m_eclipsed_index_array.begin(),
589 m_eclipsed_index_array.end(), index);
590 if (found == m_eclipsed_index_array.end()) bfound_all =
false;
595void Piano::SetKeyArray(std::vector<int> ¢er_array,
596 std::vector<int> &full_array) {
599 if (center_array.size()) {
600 int refd = m_parentCanvas->GetCharWidth();
602 int nkeys = center_array.size();
603 int key_width = (m_width_avail / refd) / nkeys;
605 m_piano_mode = PIANO_MODE_COMPOSITE;
606 m_key_array = full_array;
608 m_piano_mode = PIANO_MODE_LEGACY;
609 m_key_array = center_array;
612 m_piano_mode = PIANO_MODE_LEGACY;
617 m_composite_array.clear();
619 if (m_piano_mode == PIANO_MODE_COMPOSITE) {
620 for (
size_t i = 0; i < m_key_array.size(); i++) {
622 ChartData->GetChartTableEntry(m_key_array[i]);
623 int scale = cte.GetScale();
624 auto order = std::pow(10, std::floor(std::log10(
scale)));
627 int chart_type = cte.GetChartType();
628 int chart_family = cte.GetChartFamily();
634 if ((cte.GetChartFamily() == CHART_FAMILY_VECTOR) ||
635 ((cte.GetChartFamily() == CHART_FAMILY_RASTER) &&
636 (cte.GetChartType() != CHART_TYPE_MBTILES))) {
638 return ((
scale == pke.chart_scale) &&
639 (chart_family == pke.chart_family));
641 auto found = find_if(m_composite_array.begin(), m_composite_array.end(),
643 if (found == m_composite_array.end()) {
645 new_pke.chart_scale =
scale;
646 new_pke.chart_family = (ChartFamilyEnum)cte.GetChartFamily();
647 new_pke.chart_type = (ChartTypeEnum)cte.GetChartType();
648 new_pke.dbindex_list.push_back(m_key_array[i]);
649 m_composite_array.push_back(new_pke);
652 ex_pke.dbindex_list.push_back(m_key_array[i]);
656 new_pke.chart_scale =
scale;
657 new_pke.chart_family = (ChartFamilyEnum)cte.GetChartFamily();
658 new_pke.chart_type = (ChartTypeEnum)cte.GetChartType();
659 new_pke.dbindex_list.push_back(m_key_array[i]);
660 m_composite_array.push_back(new_pke);
664 for (
size_t i = 0; i < m_key_array.size(); i++) {
666 ChartData->GetChartTableEntry(m_key_array[i]);
667 int scale = cte.GetScale();
668 int chart_type = cte.GetChartType();
670 new_pke.chart_scale =
scale;
671 new_pke.chart_family = (ChartFamilyEnum)cte.GetChartFamily();
672 new_pke.chart_type = (ChartTypeEnum)cte.GetChartType();
673 new_pke.dbindex_list.push_back(m_key_array[i]);
674 m_composite_array.push_back(new_pke);
679 std::sort(m_composite_array.begin(), m_composite_array.end(),
681 return a.chart_scale < b.chart_scale;
685void Piano::SetNoshowIndexArray(std::vector<int> array) {
686 m_noshow_index_array = array;
689void Piano::AddNoshowIndexArray(std::vector<int> array) {
690 for (
unsigned int i = 0; i < array.size(); i++) {
691 m_noshow_index_array.push_back(array[i]);
695void Piano::SetActiveKeyArray(std::vector<int> array) {
696 m_active_index_array = array;
699void Piano::SetEclipsedIndexArray(std::vector<int> array) {
700 m_eclipsed_index_array = array;
703void Piano::SetSkewIndexArray(std::vector<int> array) {
704 m_skew_index_array = array;
707void Piano::SetTmercIndexArray(std::vector<int> array) {
708 m_tmerc_index_array = array;
711void Piano::SetPolyIndexArray(std::vector<int> array) {
712 m_poly_index_array = array;
715bool Piano::InArray(std::vector<int> &array,
int key) {
716 for (
unsigned int ino = 0; ino < array.size(); ino++)
717 if (array[ino] == key)
return true;
721wxString Piano::GetStateHash() {
724 for (
unsigned int i = 0; i < m_key_array.size(); i++) {
726 a.Printf(
"%dK", m_key_array[i]);
729 for (
unsigned int i = 0; i < m_noshow_index_array.size(); i++) {
731 a.Printf(
"%dN", m_noshow_index_array[i]);
734 for (
unsigned int i = 0; i < m_active_index_array.size(); i++) {
736 a.Printf(
"%dA", m_active_index_array[i]);
739 for (
unsigned int i = 0; i < m_eclipsed_index_array.size(); i++) {
741 a.Printf(
"%dE", m_eclipsed_index_array[i]);
744 for (
unsigned int i = 0; i < m_skew_index_array.size(); i++) {
746 a.Printf(
"%dW", m_skew_index_array[i]);
749 for (
unsigned int i = 0; i < m_tmerc_index_array.size(); i++) {
751 a.Printf(
"%dM", m_tmerc_index_array[i]);
754 for (
unsigned int i = 0; i < m_poly_index_array.size(); i++) {
756 a.Printf(
"%dP", m_poly_index_array[i]);
763wxString &Piano::GenerateAndStoreNewHash() {
764 m_hash = GetStateHash();
768wxString &Piano::GetStoredHash() {
return m_hash; }
770void Piano::FormatKeys() {
772 int width = m_parentCanvas->GetClientSize().x;
774 if (g_bopengl) width *= m_parentCanvas->GetContentScaleFactor();
776 width *= m_parentCanvas->GetContentScaleFactor();
780 wxSize mui_tool_size = g_StyleManager->GetCurrentStyle()->GetToolSize();
782 mui_tool_size = wxSize(mui_tool_size.x * 1.25, mui_tool_size.y * 1.25);
784 int mui_bar_width_est = mui_tool_size.x * 8 * g_toolbar_scalefactor;
786 if (m_parentCanvas->GetClientSize().x < m_parentCanvas->GetClientSize().y) {
797 m_width_avail = width;
799 int height = GetHeight();
801 int nKeys = m_composite_array.size();
802 int kw = style->chartStatusIconWidth;
804 if (!kw) kw = width / nKeys;
813 for (
int i = 0; i < nKeys; i++) {
814 wxRect r((i * kw) + 3, 2, kw - 6, height - 4);
815 KeyRect.push_back(r);
816 m_width = r.x + r.width;
822wxPoint Piano::GetKeyOrigin(
int key_index) {
823 if ((key_index >= 0) && (key_index <= (
int)m_key_array.size() - 1)) {
824 wxRect box = KeyRect[key_index];
825 return wxPoint(box.x, box.y);
827 return wxPoint(-1, -1);
830bool Piano::MouseEvent(wxMouseEvent &event) {
832 event.GetPosition(&x, &y);
841 int ytop = m_parentCanvas->GetCanvasHeight() - GetHeight();
843 if (!g_bopengl) ytop = m_parentCanvas->GetClientSize().y - GetHeight();
846 if (event.Leaving() || (y < ytop) || (x > GetWidth())) {
847 if (m_bleaving)
return false;
855 int sel_dbindex = -1;
857 for (
int i = 0; i < m_nRegions; i++) {
858 if (KeyRect[i].Contains(x, 6)) {
860 sel_dbindex = m_key_array[i];
866 if (event.LeftDown()) {
867 if (-1 != sel_index) {
868 m_action = DEFERRED_KEY_CLICK_DOWN;
870 m_eventTimer.Start(10, wxTIMER_ONE_SHOT);
873 if (event.LeftUp()) {
874 if (-1 != sel_index) {
875 m_click_sel_index = sel_index;
876 if (!m_eventTimer.IsRunning()) {
877 m_action = DEFERRED_KEY_CLICK_UP;
878 m_eventTimer.Start(10, wxTIMER_ONE_SHOT);
881 }
else if (event.RightDown()) {
882 if (sel_index != m_hover_last) {
884 m_parentCanvas->HandlePianoRollover(
885 sel_index, m_composite_array[sel_index].dbindex_list,
886 m_composite_array[sel_index].dbindex_list.size(),
887 m_composite_array[sel_index].chart_scale);
888 m_hover_last = sel_index;
893 }
else if (event.ButtonUp()) {
894 m_parentCanvas->ClearPianoRollover();
899 m_parentCanvas->ClearPianoRollover();
901 }
else if (event.LeftDown()) {
902 if (-1 != sel_index) {
903 m_parentCanvas->HandlePianoClick(
904 sel_index, m_composite_array[sel_index].dbindex_list);
906 m_parentCanvas->Raise();
909 }
else if (event.RightDown()) {
910 if (-1 != sel_index) {
911 m_parentCanvas->HandlePianoRClick(
912 x, y, sel_index, m_composite_array[sel_index].dbindex_list);
913 m_parentCanvas->Raise();
916 }
else if (!event.ButtonUp()) {
917 if (sel_index != m_hover_last) {
919 m_parentCanvas->HandlePianoRollover(
920 sel_index, m_composite_array[sel_index].dbindex_list,
921 m_composite_array[sel_index].dbindex_list.size(),
922 m_composite_array[sel_index].chart_scale);
924 m_hover_last = sel_index;
943void Piano::ResetRollover() {
945 m_hover_icon_last = -1;
947 m_gotPianoDown =
false;
950int Piano::GetHeight() {
953 if (g_bopengl) height *= m_parentCanvas->GetContentScaleFactor();
956 double size_mult = exp(g_GUIScaleFactor * 0.0953101798043);
958 height = wxMin(height, 100);
959 height = wxMax(height, 10);
961 height *= g_Platform->GetDisplayDensityFactor();
964 height = wxMax(height, 4 * g_Platform->GetDisplayDPmm());
972int Piano::GetWidth() {
return m_width; }
974void Piano::onTimerEvent(wxTimerEvent &event) {
976 case DEFERRED_KEY_CLICK_DOWN:
977 m_gotPianoDown =
true;
979 case DEFERRED_KEY_CLICK_UP:
981 if ((m_hover_last >= 0) || !m_gotPianoDown) {
982 m_parentCanvas->ClearPianoRollover();
985 m_parentCanvas->HandlePianoClick(
987 m_composite_array[m_click_sel_index].dbindex_list);
988 m_gotPianoDown =
false;
991 case INFOWIN_TIMEOUT:
992 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.