25#include <wx/graphics.h>
29#define SCROLL_SENSIBILITY 20
34CustomGrid::CustomGrid(wxWindow* parent, wxWindowID
id,
const wxPoint& pos,
35 const wxSize& size,
long style,
const wxString& name)
36 : wxGrid(parent, id, pos, size, style, name) {
38 SetTable(
new wxGridStringTable(0, 0),
true, wxGridSelectRows);
41 EnableGridLines(
true);
42 EnableDragGridSize(
false);
44 EnableDragColMove(
false);
45 EnableDragColSize(
false);
46 EnableDragRowSize(
false);
48 wxFileConfig* pConf = GetOCPNConfigObject();
50 pConf->SetPath(_T(
"/Settings/GRIB"));
51 m_IsDigit = pConf->Read(_T(
"GribDataTableRowPref"), _T(
"XXX"));
53 if (m_IsDigit.Len() != wxString(_T(
"XXX")).Len()) m_IsDigit = _T(
"XXX");
55 for (
unsigned int i = 0; i < m_IsDigit.Len(); i++) {
56 m_NumRow.push_back(wxNOT_FOUND);
57 m_NumRowVal.push_back(std::vector<double>());
61 SetLabelFont(labelfont);
62 wxColour colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
63 if (colour.Red() > 128) {
64 GetGlobalColor(_T(
"DILG0"), &colour);
65 GetGlobalColor(_T(
"GREEN1"), &m_greenColour);
66 GetGlobalColor(_T(
"DILG1"), &m_greyColour);
68 GetGlobalColor(_T(
"GREEN2"), &m_greenColour);
69 m_greyColour = colour;
71 SetLabelBackgroundColour(colour);
74 GetTextExtent(_T(
"Ab"), &w,
nullptr, 0, 0, &labelfont);
75 double x = (double)w * 6.5;
76 SetRowLabelSize((
int)x);
83 Connect(wxEVT_SCROLLWIN_THUMBTRACK,
84 wxScrollEventHandler(CustomGrid::OnScroll),
nullptr,
this);
85 Connect(wxEVT_SIZE, wxSizeEventHandler(CustomGrid::OnResize),
nullptr,
this);
86 Connect(wxEVT_GRID_LABEL_LEFT_CLICK,
87 wxGridEventHandler(CustomGrid::OnLabeClick),
nullptr,
this);
89 GetGridWindow()->Connect(wxEVT_LEFT_DOWN,
90 wxMouseEventHandler(CustomGrid::OnMouseEvent),
92 GetGridWindow()->Connect(wxEVT_LEFT_UP,
93 wxMouseEventHandler(CustomGrid::OnMouseEvent),
95 GetGridWindow()->Connect(wxEVT_MOTION,
96 wxMouseEventHandler(CustomGrid::OnMouseEvent),
99 m_tRefreshTimer.Connect(wxEVT_TIMER,
100 wxTimerEventHandler(CustomGrid::OnRefreshTimer),
104CustomGrid::~CustomGrid() {
105 wxFileConfig* pConf = GetOCPNConfigObject();
107 pConf->SetPath(_T (
"/Settings/GRIB" ));
108 pConf->Write(_T (
"GribDataTableRowPref" ), m_IsDigit);
114void CustomGrid::DrawColLabel(wxDC& dc,
int col) {
116 dc.SetFont(m_labelFont);
117 if (col == m_gParent->m_pIndex) {
118 dc.SetBrush(wxBrush(m_greenColour, wxBRUSHSTYLE_SOLID));
119 dc.SetPen(wxPen(m_greenColour, 1));
121 dc.SetBrush(wxBrush(m_labelBackgroundColour, wxBRUSHSTYLE_SOLID));
122 dc.SetPen(wxPen(m_labelBackgroundColour, 1));
125 wxRect tRect(GetColLeft(col), 1, GetColWidth(col) - 2, m_colLabelHeight - 2);
126 dc.DrawRectangle(tRect);
128 dc.SetPen(GetDefaultGridLinePen());
129 dc.DrawLine(GetColLeft(col) - 1, 0, GetColRight(col), 0);
130 if (col > -1 && (col == 0 || GetColLabelValue(col).BeforeFirst(
'-') !=
131 GetColLabelValue(col - 1).BeforeFirst(
'-')))
132 dc.SetPen(wxPen(*wxBLACK, 4));
133 dc.DrawLine(GetColLeft(col) - 1, 0, GetColLeft(col) - 1, m_colLabelHeight);
134 if (col == m_numCols - 1) {
135 dc.SetPen(wxPen(*wxBLACK, 4));
136 dc.DrawLine(GetColRight(col), 0, GetColRight(col), m_colLabelHeight);
139 dc.DrawLabel(GetColLabelValue(col), tRect,
140 wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
143void CustomGrid::DrawRowLabel(wxDC& dc,
int row) {
145 dc.SetFont(m_labelFont);
146 dc.SetPen(GetDefaultGridLinePen());
147 dc.SetBrush(wxBrush(m_labelBackgroundColour, wxBRUSHSTYLE_SOLID));
148 int w = dc.GetTextExtent(_T(
"Speed")).x;
149 wxString label1, label2;
150 label1 = GetRowLabelValue(row).BeforeFirst(
',', &label2);
153 if (GetNumberRows() > row + 2 &&
154 label1 == GetRowLabelValue(row + 2).BeforeFirst(
',')) {
156 if (IsRowVisible(row + 2)) label1 = _T(
" ");
159 else if (GetNumberRows() > row + 1 &&
160 label1 == GetRowLabelValue(row + 1).BeforeFirst(
',')) {
163 label1 == GetRowLabelValue(row - 1).BeforeFirst(
',')) {
164 if (!IsRowVisible(row + 1)) label1 = _T(
" ");
168 else if (row > 1 && label1 == GetRowLabelValue(row - 2).BeforeFirst(
',')) {
169 if (IsRowVisible(row - 1)) label1 = _T(
" ");
172 else if (row > 0 && label1 == GetRowLabelValue(row - 1).BeforeFirst(
',')) {
173 if (IsRowVisible(row - 1)) label1 = _T(
" ");
176 wxRect aRect(5, GetRowTop(row), m_rowLabelWidth - w, GetRowHeight(row));
177 dc.DrawLabel(label1, aRect, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
179 wxRect bRect(m_rowLabelWidth - w, GetRowTop(row), w, GetRowHeight(row));
180 dc.SetFont(wxFont(m_labelFont).Scale(0.85));
181 dc.DrawLabel(label2, bRect, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
184 dc.DrawLine(0, GetRowBottom(row) - 1, m_rowLabelWidth,
185 GetRowBottom(row) - 1);
186 dc.DrawLine(0, GetRowTop(row), 0, GetRowBottom(row));
187 dc.DrawLine(m_rowLabelWidth - 1, GetRowTop(row), m_rowLabelWidth - 1,
191void CustomGrid::DrawCornerLabel(wxDC& dc) {
192 dc.SetPen(GetDefaultGridLinePen());
193 dc.SetBrush(wxBrush(m_labelBackgroundColour, wxBRUSHSTYLE_SOLID));
194 wxRect rect(0, 0, m_rowLabelWidth, m_colLabelHeight);
195 dc.DrawRectangle(rect);
197 double hc = m_colLabelHeight;
198 double hb = wxBitmap(now).GetHeight();
199 double scfac = ((hc / hb) * 4) / 4;
200 wxBitmap bmp = m_gParent->GetScaledBitmap(wxBitmap(now), _T(
"now"), scfac);
202 int x = (m_rowLabelWidth - bmp.GetWidth()) / 2;
203 int y = (m_colLabelHeight == bmp.GetHeight())
205 : wxMax(0, (m_colLabelHeight - bmp.GetHeight()) / 2);
206 dc.DrawBitmap(bmp, x, y);
209void CustomGrid::OnScroll(wxScrollEvent& event) {
210 m_tRefreshTimer.Start(10, wxTIMER_ONE_SHOT);
214void CustomGrid::OnRefreshTimer(wxTimerEvent& event) { ForceRefresh(); }
216void CustomGrid::OnResize(wxSizeEvent& event) {
217 m_tRefreshTimer.Start(10, wxTIMER_ONE_SHOT);
221void CustomGrid::OnLabeClick(wxGridEvent& event) {
222 int row =
event.GetRow();
223 int col =
event.GetCol();
224 wxPoint p =
event.GetPosition();
226 if (row == wxNOT_FOUND && event.GetCol() == wxNOT_FOUND) {
228 int frow = 0, fcol = 0;
229 GetFirstVisibleCell(frow, fcol);
231 MakeCellVisible(frow, m_numCols - 1);
232 MakeCellVisible(frow, m_gParent->m_pIndex);
233 }
else if (row != wxNOT_FOUND && col == wxNOT_FOUND) {
234 int idx = GetRowIndex(row);
235 if (idx != wxNOT_FOUND) {
236 if (m_IsDigit.GetChar(idx) ==
'X')
237 m_IsDigit.SetChar(idx,
'.');
239 m_IsDigit.SetChar(idx,
'X');
240 for (
int c = 0; c < m_numCols; c++) {
241 double value = m_NumRowVal[idx][c];
244 if (idx == R_CURRENT && m_IsDigit.GetChar(idx) ==
'X' &&
245 value != GRIB_NOTDEF) {
247 if (value >= 360) value -= 360;
248 if (value < 0) value += 360;
251 row, c,
new CustomRenderer(value, m_IsDigit.GetChar(idx) ==
'X'));
253 m_tRefreshTimer.Start(10, wxTIMER_ONE_SHOT);
258int CustomGrid::GetRowIndex(
int row) {
259 int idx = wxNOT_FOUND;
260 for (
unsigned int i = 0; i < m_NumRow.size(); i++) {
261 if (m_NumRow[i] == row) idx = i;
266void CustomGrid::SetNumericalRow(
int row,
int col,
int datatype,
double value) {
267 m_NumRow[datatype] = row;
268 m_NumRowVal[datatype].push_back(value);
271 if (datatype == R_CURRENT && m_IsDigit.GetChar(datatype) ==
'X' &&
272 value != GRIB_NOTDEF) {
274 if (value >= 360) value -= 360;
275 if (value < 0) value += 360;
278 row, col,
new CustomRenderer(value, m_IsDigit.GetChar(datatype) ==
'X'));
281void CustomGrid::OnMouseEvent(wxMouseEvent& event) {
282 static wxPoint s_pevt;
283 wxPoint pevt =
event.GetPosition();
285 if (!m_bLeftDown && event.LeftIsDown()) {
288 }
else if (m_bLeftDown && !event.LeftIsDown()) {
290 if (HasCapture()) ReleaseMouse();
293 if (event.LeftDown()) s_pevt = pevt;
294 if (event.LeftUp()) {
295 if (HasCapture()) ReleaseMouse();
298 if (event.Dragging()) {
299 int frow, fcol, lrow, lcol;
300 GetFirstVisibleCell(frow, fcol);
301 GetLastVisibleCell(lrow, lcol);
302 if (pevt != s_pevt) {
304 int diff = pevt.x - s_pevt.x;
306 if (diff > SCROLL_SENSIBILITY) {
309 MakeCellVisible(frow, fcol - 1);
314 else if (-diff > SCROLL_SENSIBILITY) {
316 if (lcol < m_numCols - 1) {
317 MakeCellVisible(frow, lcol + 1);
322 diff = pevt.y - s_pevt.y;
323 if (diff > SCROLL_SENSIBILITY) {
326 MakeCellVisible(frow - 1, fcol);
331 else if (-diff > SCROLL_SENSIBILITY) {
333 if (lrow < m_numRows - 1) {
334 MakeCellVisible(lrow + 1, fcol);
335 MakeCellVisible(frow + 1,
341 if (rfh) m_tRefreshTimer.Start(10, wxTIMER_ONE_SHOT);
346bool CustomGrid::IsRowVisible(
int row) {
347 for (
int i = 0; i < m_numCols; i++) {
348 if (IsVisible(row, i,
false))
return true;
354void CustomGrid::GetFirstVisibleCell(
int& frow,
int& fcol) {
357 for (fcol = 0; fcol < m_numCols; fcol++) {
358 for (frow = 0; frow < m_numRows; frow++) {
359 if (IsVisible(frow, fcol)) {
369void CustomGrid::GetLastVisibleCell(
int& lrow,
int& lcol) {
371 lrow = wxMax(m_numRows - 1, 0);
372 for (lcol = wxMax(m_numCols - 1, 0); lcol > -1; lcol--) {
373 for (lrow = m_numRows - 1; lrow > -1; lrow--) {
374 if (IsVisible(lrow, lcol)) {
386void CustomRenderer::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
387 const wxRect& rect,
int row,
int col,
389 dc.SetPen(wxPen(attr.GetBackgroundColour(), 1));
390 dc.SetBrush(wxBrush(attr.GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
391 dc.DrawRectangle(rect);
392 if (m_IsDigit || m_dDir == GRIB_NOTDEF) {
393 wxString text(wxEmptyString);
394 if (m_dDir != GRIB_NOTDEF) text.Printf(_T(
"%03d%c"), (
int)m_dDir, 0x00B0);
395 dc.DrawLabel(text, rect,
396 wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
398 double si = sin((m_dDir - 90) * M_PI / 180.);
399 double co = cos((m_dDir - 90) * M_PI / 180.);
401 int i = rect.GetTopLeft().x + (rect.GetWidth() / 2);
402 int j = rect.GetTopLeft().y + (rect.GetHeight() / 2);
404 int arrowSize = rect.GetHeight() - 3;
405 int dec = -arrowSize / 2;
407#if wxUSE_GRAPHICS_CONTEXT
408 wxGraphicsContext* gdc;
409 wxClientDC* cdc =
new wxClientDC(
dynamic_cast<wxWindow*
>(&grid));
410 cdc =
dynamic_cast<wxClientDC*
>(&dc);
412 gdc = wxGraphicsContext::Create(*cdc);
419 for (
int c = 0; c < grid.GetNumberCols(); c++) {
420 for (r = 0; r < grid.GetNumberRows(); r++) {
421 if (grid.IsVisible(r, c)) {
423 i -= (c * grid.GetColSize(0));
424 j -= (r * grid.GetRowHeight(0));
431 gdc->SetPen(wxPen(attr.GetTextColour(), 3));
432 gdc->SetBrush(wxBrush(attr.GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
434 double ii, jj, kk, ll;
435 GetArrowsPoints(si, co, i, j, dec, 0, dec + arrowSize, 0, ii, jj, kk, ll);
436 gdc->StrokeLine(ii, jj, kk, ll);
437 GetArrowsPoints(si, co, i, j, dec - 3, 0, dec + 5, 3, ii, jj, kk, ll);
438 gdc->StrokeLine(ii, jj, kk, ll);
439 GetArrowsPoints(si, co, i, j, dec - 3, 0, dec + 5, -3, ii, jj, kk, ll);
440 gdc->StrokeLine(ii, jj, kk, ll);
445 dc.SetPen(wxPen(attr.GetTextColour(), 3));
446 double ii, jj, kk, ll;
447 GetArrowsPoints(si, co, i, j, dec, 0, dec + arrowSize, 0, ii, jj, kk, ll);
448 dc.DrawLine((
int)ii, (
int)jj, (
int)kk, (
int)ll);
449 GetArrowsPoints(si, co, i, j, dec - 3, 0, dec + 5, 3, ii, jj, kk, ll);
450 dc.DrawLine((
int)ii, (
int)jj, (
int)kk, (
int)ll);
451 GetArrowsPoints(si, co, i, j, dec - 3, 0, dec + 5, -3, ii, jj, kk, ll);
452 dc.DrawLine((
int)ii, (
int)jj, (
int)kk, (
int)ll);
457void CustomRenderer::GetArrowsPoints(
double si,
double co,
int di,
int dj,
458 int i,
int j,
int k,
int l,
double& ii,
459 double& jj,
double& kk,
double& ll) {
460 ii = (i * co - j * si + 0.5) + di;
461 jj = (i * si + j * co + 0.5) + dj;
462 kk = (k * co - l * si + 0.5) + di;
463 ll = (k * si + l * co + 0.5) + dj;
Specialized Grid Control for GRIB Data Display.
GRIB Data Table View and Export Interface.
wxFont GetOCPNGUIScaledFont_PlugIn(wxString item)
Gets a uniquely scaled font copy for responsive UI elements.