Esempio n. 1
0
RadarPanel::~RadarPanel() {
  wxAuiPaneInfo& pane = m_aui_mgr->GetPane(this);

  bool wasFloating = pane.IsFloating();
  if (!wasFloating) {
    pane.Float();
    m_aui_mgr->Update();
    pane = m_aui_mgr->GetPane(this);
  }

  wxPoint pos = pane.floating_pos;
  LOG_DIALOG(wxT("%s saved position %d,%d"), m_aui_name.c_str(), pos.x, pos.y);
  m_pi->m_settings.window_pos[m_ri->m_radar] = pos;

  if (!wasFloating) {
    pane.Dock();
    m_aui_mgr->Update();
    pane = m_aui_mgr->GetPane(this);
  }

  m_pi->m_perspective[m_ri->m_radar] = m_aui_mgr->SavePaneInfo(pane);
  if (m_ri->m_radar_canvas) {
    m_sizer->Detach(m_ri->m_radar_canvas);
    delete m_ri->m_radar_canvas;
    m_ri->m_radar_canvas = 0;
  }
  m_aui_mgr->DetachPane(this);
  m_aui_mgr->Update();
  LOG_DIALOG(wxT("BR24radar_pi: %s panel removed"), m_ri->m_name.c_str());
}
Esempio n. 2
0
bool RadarPanel::Create() {
  m_aui_mgr = GetFrameAuiManager();

  m_aui_name = wxString::Format(wxT("BR24radar_pi-%d"), m_ri->m_radar);
  wxAuiPaneInfo pane = wxAuiPaneInfo()
                           .Name(m_aui_name)
                           .Caption(m_ri->m_name)
                           .CaptionVisible(true)  // Show caption even when docked
                           .TopDockable(false)
                           .BottomDockable(false)
                           .RightDockable(true)
                           .LeftDockable(true)
                           .CloseButton(true)
                           .Gripper(false);

  m_sizer = new wxBoxSizer(wxHORIZONTAL);

  m_text = new wxStaticText(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
  m_sizer->Add(m_text, 0, wxEXPAND | wxALL, 0);
  SetSizer(m_sizer);

  DimeWindow(this);
  Fit();
  Layout();
  // SetMinSize(GetBestSize());

  m_best_size = wxGetDisplaySize();
  m_best_size.x /= 2;
  m_best_size.y /= 2;

  pane.MinSize(256, 256);
  pane.BestSize(m_best_size);
  pane.FloatingSize(512, 512);
  pane.FloatingPosition(m_pi->m_settings.window_pos[m_ri->m_radar]);
  pane.Float();
  pane.dock_proportion = 100000;  // Secret sauce to get panels to use entire bar

  m_aui_mgr->AddPane(this, pane);
  m_aui_mgr->Update();
  m_aui_mgr->Connect(wxEVT_AUI_PANE_CLOSE, wxAuiManagerEventHandler(RadarPanel::close), NULL, this);

  m_dock_size = 0;

  if (m_pi->m_perspective[m_ri->m_radar].length()) {
    // Do this first and it doesn't work if the pane starts docked.
    LOG_DIALOG(wxT("BR24radar_pi: Restoring panel %s to AUI control manager: %s"), m_aui_name.c_str(),
               m_pi->m_perspective[m_ri->m_radar].c_str());
    m_aui_mgr->LoadPaneInfo(m_pi->m_perspective[m_ri->m_radar], pane);
    m_aui_mgr->Update();
  } else {
    LOG_DIALOG(wxT("BR24radar_pi: Added panel %s to AUI control manager"), m_aui_name.c_str());
  }

  return true;
}
Esempio n. 3
0
void RadarPanel::close(wxAuiManagerEvent& event) {
  event.Skip();

  wxAuiPaneInfo* pane = event.GetPane();

  if (pane->window == this) {
    m_pi->m_settings.show_radar[m_ri->m_radar] = 0;
    LOG_DIALOG(wxT("BR24radar_pi: RadarPanel::close: show_radar[%d]=%d"), m_ri->m_radar, 0);
    m_pi->NotifyRadarWindowViz();
  } else {
    LOG_DIALOG(wxT("BR24radar_pi: RadarPanel::close: ignore close of window %s in window %s"), pane->name.c_str(),
               m_aui_name.c_str());
  }
}
Esempio n. 4
0
void RadarCanvas::OnSize(wxSizeEvent &evt) {
  wxSize parentSize = m_parent->GetSize();
  LOG_DIALOG(wxT("BR24radar_pi: %s resize OpenGL canvas to %d, %d"), m_ri->m_name.c_str(), parentSize.x, parentSize.y);
  Refresh(false);
  if (GetSize() != parentSize) {
    SetSize(parentSize);
  }
}
Esempio n. 5
0
void RadarCanvas::RenderCursor(int w, int h) {
  double distance;
  double bearing;

  if (m_ri->m_mouse_vrm != 0.0) {
    distance = m_ri->m_mouse_vrm * 1852.;
    bearing = m_ri->m_mouse_ebl;
  } else {
    if ((m_ri->m_mouse_lat == 0.0 && m_ri->m_mouse_lon == 0.0) || !m_pi->m_bpos_set) {
      return;
    }
    // Can't compute this upfront, ownship may move...
    distance = local_distance(m_pi->m_ownship_lat, m_pi->m_ownship_lon, m_ri->m_mouse_lat, m_ri->m_mouse_lon) * 1852.;
    bearing = local_bearing(m_pi->m_ownship_lat, m_pi->m_ownship_lon, m_ri->m_mouse_lat, m_ri->m_mouse_lon);
    if (!m_ri->IsDisplayNorthUp()) {
      bearing -= m_pi->m_hdt;
    }
    // LOG_DIALOG(wxT("BR24radar_pi: Chart Mouse vrm=%f ebl=%f"), distance / 1852.0, bearing);
  }
  double full_range = wxMax(w, h) / 2.0;

  int display_range = m_ri->GetDisplayRange();
  double range = distance * full_range / display_range;

#define CURSOR_SCALE 1

  double center_x = w / 2.0;
  double center_y = h / 2.0;
  double angle = deg2rad(bearing);
  double x = center_x + sin(angle) * range - CURSOR_WIDTH * CURSOR_SCALE / 2;
  double y = center_y - cos(angle) * range - CURSOR_WIDTH * CURSOR_SCALE / 2;

  // LOG_DIALOG(wxT("BR24radar_pi: draw cursor angle=%.1f bearing=%.1f"), rad2deg(angle), bearing);

  if (!m_cursor_texture) {
    glGenTextures(1, &m_cursor_texture);
    glBindTexture(GL_TEXTURE_2D, m_cursor_texture);
    FillCursorTexture();
    LOG_DIALOG(wxT("BR24radar_pi: generated cursor texture # %u"), m_cursor_texture);
  }

  glColor3f(1.0f, 1.0f, 1.0f);
  glBindTexture(GL_TEXTURE_2D, m_cursor_texture);
  glBegin(GL_QUADS);
  glTexCoord2i(0, 0);
  glVertex2i(x, y);
  glTexCoord2i(1, 0);
  glVertex2i(x + CURSOR_SCALE * CURSOR_WIDTH, y);
  glTexCoord2i(1, 1);
  glVertex2i(x + CURSOR_SCALE * CURSOR_WIDTH, y + CURSOR_SCALE * CURSOR_HEIGHT);
  glTexCoord2i(0, 1);
  glVertex2i(x, y + CURSOR_SCALE * CURSOR_HEIGHT);
  glEnd();
}
Esempio n. 6
0
void RadarCanvas::OnMouseClick(wxMouseEvent &event) {
  int x, y, w, h;

  event.GetPosition(&x, &y);
  GetClientSize(&w, &h);

  int center_x = w / 2;
  int center_y = h / 2;

  LOG_DIALOG(wxT("BR24radar_pi: %s Mouse clicked at %d, %d"), m_ri->m_name.c_str(), x, y);

  if (x >= w - m_menu_size.x && y < m_menu_size.y) {
    m_pi->ShowRadarControl(m_ri->m_radar, true);
  } else if ((x >= center_x - m_zoom_size.x / 2) && (x <= center_x + m_zoom_size.x / 2) &&
             (y > h - m_zoom_size.y + MENU_ROUNDING)) {
    if (x > center_x) {
      m_ri->AdjustRange(+1);
    } else {
        m_ri->AdjustRange(-1);
    }

  } else {
    double delta_x = x - center_x;
    double delta_y = y - center_y;

    double distance = sqrt(delta_x * delta_x + delta_y * delta_y);

    int display_range = m_ri->GetDisplayRange();

    double angle = fmod(rad2deg(atan2(delta_y, delta_x)) + 720. + 90., 360.0);

    double full_range = wxMax(w, h) / 2.0;

    double range = distance / (1852.0 * full_range / display_range);

    LOG_VERBOSE(wxT("BR24radar_pi: cursor in PPI at angle=%.1f range=%f heading=%.1f"), angle, range);
    m_ri->SetMouseVrmEbl(range, angle);
  }
  event.Skip();
}
Esempio n. 7
0
void RadarPanel::ShowFrame(bool visible) {
  LOG_DIALOG(wxT("BR24radar_pi %s: set visible %d"), m_ri->m_name.c_str(), visible);

  wxAuiPaneInfo& pane = m_aui_mgr->GetPane(this);

  if (!m_pi->m_opengl_mode && m_ri->m_radar_canvas) {
    m_sizer->Detach(m_ri->m_radar_canvas);
    delete m_ri->m_radar_canvas;
    m_ri->m_radar_canvas = 0;
    m_text->SetLabel(_("OpenGL mode required"));
    m_sizer->Show(m_text);
    DimeWindow(this);
    Fit();
    Layout();
  }
  if (visible) {
    if (m_pi->m_opengl_mode && !m_ri->m_radar_canvas) {
      LOG_DIALOG(wxT("BR24radar_pi %s: creating OpenGL canvas"), m_ri->m_name.c_str());
      m_ri->m_radar_canvas = new RadarCanvas(m_pi, m_ri, this, GetSize());
      if (!m_ri->m_radar_canvas) {
        m_text->SetLabel(_("Unable to create OpenGL canvas"));
        m_sizer->Show(m_text);
      } else {
        m_sizer->Hide(m_text);
        m_sizer->Add(m_ri->m_radar_canvas, 0, wxEXPAND | wxALL, 0);

        Fit();
        Layout();
      }
    }
  }

  if (visible) {
    m_pi->m_settings.show_radar[m_ri->m_radar] = 1;
    LOG_DIALOG(wxT("BR24radar_pi: RadarPanel::ShowFrame: show_radar[%d]=%d"), m_ri->m_radar, 1);
  }

  // What should have been a simple 'pane.Show(visible)' has devolved into a terrible hack.
  // When the entire dock row disappears because we're removing the last pane from it then the
  // next time we restore the dock gets its original size again. This is not want customers want.
  // So we store the size of the dock just before hiding the pane. This is done via parsing of the
  // perspective string, as there is no other way to access the dock information through wxAUI.

  if (!visible) {
    m_dock_size = 0;
    if (pane.IsDocked()) {
      m_dock = wxString::Format(wxT("|dock_size(%d,%d,%d)="), pane.dock_direction, pane.dock_layer, pane.dock_row);
      wxString perspective = m_aui_mgr->SavePerspective();

      int p = perspective.Find(m_dock);
      if (p != wxNOT_FOUND) {
        perspective = perspective.Mid(p + m_dock.length());
        perspective = perspective.BeforeFirst(wxT('|'));
        m_dock_size = wxAtoi(perspective);
        LOG_DIALOG(wxT("BR24radar_pi: %s: replaced=%s, saved dock_size = %d"), m_ri->m_name.c_str(), perspective.c_str(),
                   m_dock_size);
      }
    }
  } else {
    pane.Position(m_ri->m_radar);
  }

  pane.Show(visible);
  m_aui_mgr->Update();  // causes recursive calls on OS X when not in OpenGL mode

  if (visible && (m_dock_size > 0)) {
    // Now the reverse: take the new perspective string and replace the dock size of the dock that our pane is in and
    // reset it to the width it was before the hide.
    wxString perspective = m_aui_mgr->SavePerspective();

    int p = perspective.Find(m_dock);
    if (p != wxNOT_FOUND) {
      wxString newPerspective = perspective.Left(p);
      newPerspective << m_dock;
      newPerspective << m_dock_size;
      perspective = perspective.Mid(p + m_dock.length());
      newPerspective << wxT("|");
      newPerspective << perspective.AfterFirst(wxT('|'));

      m_aui_mgr->LoadPerspective(newPerspective);
      LOG_DIALOG(wxT("BR24radar_pi: %s: new perspective %s"), m_ri->m_name.c_str(), newPerspective.c_str());
    }
  }
}
Esempio n. 8
0
void RadarCanvas::OnMove(wxMoveEvent &evt) {
  wxPoint pos = m_parent->GetPosition();
  LOG_DIALOG(wxT("BR24radar_pi: %s move OpenGL canvas to %d, %d"), m_ri->m_name.c_str(), pos.x, pos.y);
}
Esempio n. 9
0
void RadarCanvas::Render(wxPaintEvent &evt) {
  int w, h;

  if (!IsShown() || !m_pi->m_initialized) {
    return;
  }

  GetClientSize(&w, &h);
  wxPaintDC(this);  // only to be used in paint events. use wxClientDC to paint
                    // outside the paint event

  if (!m_pi->m_opengl_mode) {
    LOG_DIALOG(wxT("BR24radar_pi: %s cannot render non-OpenGL mode"), m_ri->m_name.c_str());
    return;
  }
  if (!m_pi->m_opencpn_gl_context && !m_pi->m_opencpn_gl_context_broken) {
    LOG_DIALOG(wxT("BR24radar_pi: %s skip render as no context known yet"), m_ri->m_name.c_str());
    return;
  }
  LOG_DIALOG(wxT("BR24radar_pi: %s render OpenGL canvas %d by %d "), m_ri->m_name.c_str(), w, h);

  SetCurrent(*m_context);

  glPushMatrix();
  glPushAttrib(GL_ALL_ATTRIB_BITS);

  wxFont font = GetOCPNGUIScaledFont_PlugIn(_T("StatusBar"));
  m_FontNormal.Build(font);
  wxFont bigFont = GetOCPNGUIScaledFont_PlugIn(_T("Dialog"));
  bigFont.SetPointSize(bigFont.GetPointSize() + 2);
  bigFont.SetWeight(wxFONTWEIGHT_BOLD);
  m_FontBig.Build(bigFont);
  bigFont.SetPointSize(bigFont.GetPointSize() + 2);
  bigFont.SetWeight(wxFONTWEIGHT_NORMAL);
  m_FontMenu.Build(bigFont);
  bigFont.SetPointSize(bigFont.GetPointSize() + 10);
  bigFont.SetWeight(wxFONTWEIGHT_BOLD);
  m_FontMenuBold.Build(bigFont);

  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);                // Black Background
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clear the canvas
  glEnable(GL_TEXTURE_2D);                             // Enable textures
  glEnable(GL_COLOR_MATERIAL);
  glEnable(GL_BLEND);
  // glDisable(GL_DEPTH_TEST);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);  // Next two operations on the project matrix stack
  glLoadIdentity();             // Reset projection matrix stack
  glOrtho(0, w, h, 0, -1, 1);
  glMatrixMode(GL_MODELVIEW);  // Reset matrick stack target back to GL_MODELVIEW

  RenderRangeRingsAndHeading(w, h);
  Render_EBL_VRM(w, h);

  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);  // Next two operations on the project matrix stack
  glLoadIdentity();             // Reset projection matrix stack
  if (w >= h) {
    glScaled(1.0, (float)-w / h, 1.0);
  } else {
    glScaled((float)h / w, -1.0, 1.0);
  }
  glMatrixMode(GL_MODELVIEW);  // Reset matrick stack target back to GL_MODELVIEW

  m_ri->RenderRadarImage(wxPoint(0, 0), 1.0, 0.0, false);

  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);  // Next two operations on the project matrix stack
  glLoadIdentity();             // Reset projection matrix stack
  glOrtho(0, w, h, 0, -1, 1);
  glMatrixMode(GL_MODELVIEW);  // Reset matrick stack target back to GL_MODELVIEW

  glEnable(GL_TEXTURE_2D);

  RenderTexts(w, h);
  RenderCursor(w, h);

#ifdef NEVER
  glDisable(GL_TEXTURE_2D);

  glMatrixMode(GL_PROJECTION);  // Next two operations on the project matrix stack
  glLoadIdentity();             // Reset projection matrix stack
  glMatrixMode(GL_MODELVIEW);   // Reset matrick stack target back to GL_MODELVIEW
#endif

  glPopAttrib();
  glPopMatrix();
  glFlush();
  glFinish();
  SwapBuffers();

  if (m_pi->m_opencpn_gl_context) {
    SetCurrent(*m_pi->m_opencpn_gl_context);
  } else {
    SetCurrent(*m_zero_context);  // Make sure OpenCPN -at least- doesn't overwrite our context info
  }
}