📄 sequence_viewer_widget.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: sequence_viewer_widget.cpp,v $ * PRODUCTION Revision 1000.2 2004/06/01 18:29:15 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.42 * PRODUCTION * =========================================================================== *//* $Id: sequence_viewer_widget.cpp,v 1000.2 2004/06/01 18:29:15 gouriano Exp $* ===========================================================================** PUBLIC DOMAIN NOTICE* National Center for Biotechnology Information** This software/database is a "United States Government Work" under the* terms of the United States Copyright Act. It was written as part of* the author's official duties as a United States Government employee and* thus cannot be copyrighted. This software/database is freely available* to the public for use. The National Library of Medicine and the U.S.* Government have not placed any restriction on its use or reproduction.** Although all reasonable efforts have been taken to ensure the accuracy* and reliability of the software and data, the NLM and the U.S.* Government do not and cannot warrant the performance or results that* may be obtained by using this software or data. The NLM and the U.S.* Government disclaim all warranties, express or implied, including* warranties of performance, merchantability or fitness for any particular* purpose.** Please cite the author in any work or product based on this material.** ===========================================================================** Authors: Paul Thiessen** File Description:* Classes to display sequences and alignments with wxWindows front end** ===========================================================================*/#ifdef _MSC_VER#pragma warning(disable:4018) // disable signed/unsigned mismatch warning in MSVC#endif#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include "sequence_viewer_widget.hpp"#include "viewable_alignment.hpp"#include "cn3d_tools.hpp"USING_NCBI_SCOPE;////////////////////////////////////////////////////////////////////////////////////////// These are definitions of the sequence and title drawing areas //////////////////////////////////////////////////////////////////////////////////////////class SequenceViewerWidget_TitleArea : public wxWindow{public: // constructor (same as wxWindow) SequenceViewerWidget_TitleArea( wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize ); // destructor ~SequenceViewerWidget_TitleArea(void); void ShowTitles(ViewableAlignment *newAlignment); void SetCharacterFont(wxFont *font, int newCellHeight); void SetBackgroundColor(const wxColor& backgroundColor);private: void OnPaint(wxPaintEvent& event); void OnMouseEvent(wxMouseEvent& event); const SequenceViewerWidget_SequenceArea *sequenceArea; ViewableAlignment *alignment; int highlightedTitleRow; wxColor currentBackgroundColor; wxFont *titleFont; int cellHeight, nTitles, maxTitleWidth; DECLARE_EVENT_TABLE()public: int GetMaxTitleWidth(void) const { return maxTitleWidth; } void SetSequenceArea(const SequenceViewerWidget_SequenceArea *seqA) { sequenceArea = seqA; }};class SequenceViewerWidget_SequenceArea : public wxScrolledWindow{ friend class SequenceViewerWidget;public: // constructor (same as wxScrolledWindow) SequenceViewerWidget_SequenceArea( wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxHSCROLL | wxVSCROLL, const wxString& name = "scrolledWindow" ); // destructor ~SequenceViewerWidget_SequenceArea(void); // stuff from parent widget bool AttachAlignment(ViewableAlignment *newAlignment, int initX, int initY); void SetMouseMode(SequenceViewerWidget::eMouseMode mode); void SetBackgroundColor(const wxColor& backgroundColor); void SetCharacterFont(wxFont *font); void SetRubberbandColor(const wxColor& rubberbandColor); ///// everything else below here is part of the actual implementation /////private: void OnPaint(wxPaintEvent& event); void OnMouseEvent(wxMouseEvent& event); void OnScrollWin(wxScrollWinEvent& event); SequenceViewerWidget_TitleArea *titleArea; ViewableAlignment *alignment; wxBitmap *bitmap; // for memoryDC/Blit wxFont *currentFont; // character font wxColor currentBackgroundColor; // background for whole window wxColor currentRubberbandColor; // color of rubber band SequenceViewerWidget::eMouseMode mouseMode; // mouse mode int cellWidth, cellHeight; // dimensions of cells in pixels int areaWidth, areaHeight; // dimensions of the alignment (virtual area) in cells void DrawCell(wxDC& dc, int x, int y, int vsX, int vsY, bool redrawBackground); // draw a single cell enum eRubberbandType { eSolid, eDot }; eRubberbandType currentRubberbandType; void DrawLine(wxDC& dc, int x1, int y1, int x2, int y2); void DrawRubberband(wxDC& dc, // draw rubber band around cells int fromX, int fromY, int toX, int toY, int vsX, int vsY); void MoveRubberband(wxDC &dc, int fromX, int fromY, // change rubber band int prevToX, int prevToY, int toX, int toY, int vsX, int vsY); void RemoveRubberband(wxDC& dc, int fromX, int fromY, // remove rubber band int toX, int toY, int vsX, int vsY); DECLARE_EVENT_TABLE()public: int GetCellHeight(void) const { return cellHeight; } int GetAreaHeight(void) const { return areaHeight; } void SetTitleArea(SequenceViewerWidget_TitleArea *titleA) { titleArea = titleA; } SequenceViewerWidget::eMouseMode GetMouseMode(void) const { return mouseMode; }};//////////////////////////////////////////////////////////////////////////////////// This is the implementation of the sequence drawing area ////////////////////////////////////////////////////////////////////////////////////BEGIN_EVENT_TABLE(SequenceViewerWidget_SequenceArea, wxScrolledWindow) EVT_PAINT (SequenceViewerWidget_SequenceArea::OnPaint) EVT_MOUSE_EVENTS (SequenceViewerWidget_SequenceArea::OnMouseEvent) EVT_SCROLLWIN (SequenceViewerWidget_SequenceArea::OnScrollWin)END_EVENT_TABLE()SequenceViewerWidget_SequenceArea::SequenceViewerWidget_SequenceArea( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxScrolledWindow(parent, -1, pos, size, style, name), alignment(NULL), currentFont(NULL), titleArea(NULL), bitmap(NULL){ // set default background color currentBackgroundColor = *wxWHITE; // set default mouse mode mouseMode = SequenceViewerWidget::eSelectRectangle; // set default rubber band color currentRubberbandColor = *wxRED;}SequenceViewerWidget_SequenceArea::~SequenceViewerWidget_SequenceArea(void){ if (currentFont) delete currentFont; if (bitmap) delete bitmap;}bool SequenceViewerWidget_SequenceArea::AttachAlignment( ViewableAlignment *newAlignment, int initX, int initY){ alignment = newAlignment; if (alignment) { // set size of virtual area alignment->GetSize(&areaWidth, &areaHeight); if (areaWidth <= 0 || areaHeight <= 0) return false;// TESTMSG(Info << "area height " << areaHeight); // "+1" to make sure last real column and row are always visible, even // if visible area isn't exact multiple of cell size SetScrollbars( cellWidth, cellHeight, areaWidth + 1, areaHeight + 1, initX, initY); alignment->MouseOver(-1, -1); } else { // remove scrollbars// areaWidth = areaHeight = 2;// SetScrollbars(10, 10, 2, 2, 0, 0); //can't do this without crash on win98... ? } return true;}void SequenceViewerWidget_SequenceArea::SetBackgroundColor(const wxColor& backgroundColor){ currentBackgroundColor = backgroundColor;}void SequenceViewerWidget_SequenceArea::SetCharacterFont(wxFont *font){ if (!font) return; wxClientDC dc(this); dc.SetFont(wxNullFont); if (currentFont) delete currentFont; currentFont = font; dc.SetFont(*currentFont); wxCoord chW, chH; dc.SetMapMode(wxMM_TEXT); dc.GetTextExtent("A", &chW, &chH); cellWidth = chW + 1; cellHeight = chH; // need to reset scrollbars and virtual area size AttachAlignment(alignment, 0, 0);}void SequenceViewerWidget_SequenceArea::SetMouseMode(SequenceViewerWidget::eMouseMode mode){ mouseMode = mode;}void SequenceViewerWidget_SequenceArea::SetRubberbandColor(const wxColor& rubberbandColor){ currentRubberbandColor = rubberbandColor;}void SequenceViewerWidget_SequenceArea::OnPaint(wxPaintEvent& event){ // adjust bitmap size to match client area size if (!bitmap || bitmap->GetWidth() != GetClientSize().GetWidth() || bitmap->GetHeight() != GetClientSize().GetHeight()) { if (bitmap) delete bitmap; bitmap = new wxBitmap(GetClientSize().GetWidth(), GetClientSize().GetHeight()); } wxMemoryDC memDC; memDC.SelectObject(*bitmap); int vsX, vsY, updLeft, updRight, updTop, updBottom, firstCellX, firstCellY, lastCellX, lastCellY, x, y; static int prevVsY = -1; memDC.BeginDrawing(); // set font for characters if (alignment) { memDC.SetFont(*currentFont); memDC.SetMapMode(wxMM_TEXT); // characters to be drawn transparently over background memDC.SetBackgroundMode(wxTRANSPARENT); // get upper left corner of visible area GetViewStart(&vsX, &vsY); // returns coordinates in scroll units (cells)// TRACEMSG("vsX=" << vsX << " vsY=" << vsY); if (vsY != prevVsY) { if (titleArea) titleArea->Refresh(); prevVsY = vsY; } } // get the update rect list, so that we can draw *only* the cells // in the part of the window that needs redrawing; update region // coordinates are relative to the visible part of the drawing area wxRegionIterator upd(GetUpdateRegion()); for (; upd; ++upd) {// TRACEMSG("upd: x=" << upd.GetX() << " y=" << upd.GetY() <<// " w=" << upd.GetW() << " h=" << upd.GetH()); // draw background memDC.SetPen(*(wxThePenList-> FindOrCreatePen(currentBackgroundColor, 1, wxSOLID))); memDC.SetBrush(*(wxTheBrushList-> FindOrCreateBrush(currentBackgroundColor, wxSOLID))); memDC.DrawRectangle(upd.GetX(), upd.GetY(), upd.GetW(), upd.GetH()); if (!alignment) continue; // figure out which cells contain the corners of the update region // get coordinates of update region corners relative to virtual area updLeft = vsX*cellWidth + upd.GetX(); updTop = vsY*cellHeight + upd.GetY(); updRight = updLeft + upd.GetW() - 1; updBottom = updTop + upd.GetH() - 1; // firstCell[X,Y] is upper leftmost cell to draw, and is the cell // that contains the upper left corner of the update region firstCellX = updLeft / cellWidth; firstCellY = updTop / cellHeight; // lastCell[X,Y] is the lower rightmost cell displayed; including partial // cells if the visible area isn't an exact multiple of cell size. (It // turns out to be very difficult to only display complete cells...) lastCellX = updRight / cellWidth; lastCellY = updBottom / cellHeight; // restrict to size of virtual area, if visible area is larger // than the virtual area if (lastCellX >= areaWidth) lastCellX = areaWidth - 1; if (lastCellY >= areaHeight) lastCellY = areaHeight - 1; // draw cells// TESTMSG("drawing cells " << firstCellX << ',' << firstCellY// << " to " << lastCellX << ',' << lastCellY); for (y=firstCellY; y<=lastCellY; ++y) { for (x=firstCellX; x<=lastCellX; ++x) { DrawCell(memDC, x, y, vsX, vsY, false); } } } memDC.EndDrawing(); // Blit from memory DC to paintDC to avoid flicker wxPaintDC paintDC(this); paintDC.Blit(0, 0, GetClientSize().GetWidth(), GetClientSize().GetHeight(), &memDC, 0,0, wxCOPY);// TRACEMSG("Blit 0, 0, " << GetClientSize().GetWidth() << ", " << GetClientSize().GetHeight());}void SequenceViewerWidget_SequenceArea::DrawCell(wxDC& dc, int x, int y, int vsX, int vsY, bool redrawBackground){ char character; wxColor color, cellBackgroundColor; bool drawBackground, drawChar; drawChar = alignment->GetCharacterTraitsAt(x, y, &character, &color, &drawBackground, &cellBackgroundColor); // adjust x,y into visible area coordinates x = (x - vsX) * cellWidth; y = (y - vsY) * cellHeight; // if necessary, redraw background with appropriate color if ((drawChar && drawBackground) || redrawBackground) { if (drawChar && drawBackground) { dc.SetPen(*(wxThePenList->FindOrCreatePen(cellBackgroundColor, 1, wxSOLID))); dc.SetBrush(*(wxTheBrushList->FindOrCreateBrush(cellBackgroundColor, wxSOLID))); } else { dc.SetPen(*(wxThePenList->FindOrCreatePen(currentBackgroundColor, 1, wxSOLID))); dc.SetBrush(*(wxTheBrushList->FindOrCreateBrush(currentBackgroundColor, wxSOLID))); } dc.DrawRectangle(x, y, cellWidth, cellHeight); } if (!drawChar) return; // set character color dc.SetTextForeground(color); // measure character size wxString buf(character); wxCoord chW, chH; dc.GetTextExtent(buf, &chW, &chH); // draw character in the middle of the cell dc.DrawText(buf, x + (cellWidth - chW)/2, y + (cellHeight - chH)/2 );}static inline void min_max(int a, int b, int *c, int *d){ if (a <= b) { *c = a; *d = b; } else { *c = b; *d = a; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -