coriolis/hurricane/src/viewer/View.cpp

1812 lines
50 KiB
C++

// ****************************************************************************************************
// File: View.cpp
// Authors: R. Escassut
// Copyright (c) BULL S.A. 2000-2004, All Rights Reserved
// ****************************************************************************************************
// 21-10-2003 Alignment BULL-LIP6 (Lip6 addded DisplaySlots) (added VisualMaps)
#include "View.h"
#include "DataBase.h"
#include "Cell.h"
#include "Technology.h"
#include "CompositeLayer.h"
#include "Selector.h"
#include "VisualMap.h"
#include "DisplaySlot.h"
#include "Go.h"
#include "Command.h"
#include "Error.h"
#include "Interruption.h"
namespace Hurricane {
// ****************************************************************************************************
// Variables
// ****************************************************************************************************
static View* DRAG_VIEW = NULL;
static unsigned DRAG_BUTTON = 0;
static bool IN_AUTO_SCROLL = false;
static unsigned SIZE = 0;
static GdkPoint* POINTS = NULL;
GdkColor View::_backgroundColor = { 0, 50*255, 50*255, 50*255 };
GdkColor View::_foregroundColor = { 0, 255*255, 255*255, 255*255 };
GdkColor View::_rubberColor = { 0, 192*255, 0*255, 192*255 };
GdkColor View::_phantomColor = { 0, 139*255, 134*255, 130*255 };
GdkColor View::_boundaryColor = { 0, 208*255, 199*255, 192*255 };
GdkColor View::_markerColor = { 0, 80*255, 250*255, 80*255 };
GdkColor View::_selectionDrawColor = { 0, 255*255, 255*255, 255*255 };
GdkColor View::_selectionFillColor = { 0, 255*255, 255*255, 255*255 };
GdkColor View::_gridColor = { 0, 255*255, 255*255, 255*255 };
GdkColor View::_spotColor = { 0, 255*255, 255*255, 255*255 };
GdkColor View::_ghostColor = { 0, 255*255, 255*255, 255*255 };
// ****************************************************************************************************
// Utilitarians
// ****************************************************************************************************
static GdkPixmap* GetPixmap(const ScreenUnit& width, const ScreenUnit& height)
// ***************************************************************************
{
static int WIDTH = 0;
static int HEIGHT = 0;
static GdkPixmap* PIXMAP = NULL;
if (!PIXMAP || (WIDTH < width) || (HEIGHT < height)) {
if (PIXMAP) gdk_pixmap_unref(PIXMAP);
WIDTH = width;
HEIGHT = height;
GdkWindow* window = gtk_get_window();
PIXMAP = gdk_pixmap_new(window, WIDTH, HEIGHT, gdk_window_get_visual(window)->depth);
}
return PIXMAP;
}
// ****************************************************************************************************
// Callbacks
// ****************************************************************************************************
static void OnExpose(GtkWidget* drawingArea, GdkEventExpose* event, View* view)
// ****************************************************************************
{
GdkRectangle area = event->area;
view->_OnExpose(area.x, area.y, area.width, area.height, (event->count == 0));
}
static void OnConfigure(GtkWidget* drawingArea, GdkEventConfigure* event, View* view)
// **********************************************************************************
{
view->_OnResize(event->width, event->height);
}
static void OnEnterNotify(GtkWidget* drawingArea, GdkEventCrossing* event, View* view)
// ***********************************************************************************
{
if (!DRAG_VIEW || (DRAG_VIEW == view)) {
ScreenUnit screenX = (ScreenUnit)event->x;
ScreenUnit screenY = (ScreenUnit)event->y;
Point position(GetOnGridUnit(view->GetX(screenX)), GetOnGridUnit(view->GetY(screenY)));
view->_OnMouseEnter(position);
}
}
static void OnMotionNotify(GtkWidget* drawingArea, GdkEventMotion* event, View* view)
// **********************************************************************************
{
if (!DRAG_VIEW || (DRAG_VIEW == view)) {
ScreenUnit screenX = (ScreenUnit)event->x;
ScreenUnit screenY = (ScreenUnit)event->y;
if ((DRAG_VIEW == view) && view->AutoScrollIsEnabled()) {
ScreenUnit screenDx = 0;
if (screenX < 0)
screenDx = screenX;
else
if (view->GetScreenWidth() < screenX)
screenDx = screenX - view->GetScreenWidth();
ScreenUnit screenDy = 0;
if (screenY < 0)
screenDy = screenY;
else
if (view->GetScreenHeight() < screenY)
screenDy = screenY - view->GetScreenHeight();
if (screenDx || screenDy) {
IN_AUTO_SCROLL = true;
view->Scroll(- view->GetSize(screenDx), view->GetSize(screenDy));
view->Update();
IN_AUTO_SCROLL = false;
}
screenX = (ScreenUnit)event->x;
screenY = (ScreenUnit)event->y;
}
Point position(GetOnGridUnit(view->GetX(screenX)), GetOnGridUnit(view->GetY(screenY)));
view->_OnMouseMove(position, event->state);
}
// to enable next pointer motion notify event
gint x, y;
GdkModifierType mt;
gdk_window_get_pointer(drawingArea->window, &x, &y, &mt);
// see GDK_POINTER_MOTION_HINT_MASK to understand previous lines
}
static void OnLeaveNotify(GtkWidget* drawingArea, GdkEventCrossing* event, View* view)
// ***********************************************************************************
{
if (!DRAG_VIEW || (DRAG_VIEW == view)) {
ScreenUnit screenX = (ScreenUnit)event->x;
ScreenUnit screenY = (ScreenUnit)event->y;
Point position(GetOnGridUnit(view->GetX(screenX)), GetOnGridUnit(view->GetY(screenY)));
view->_OnMouseLeave(position);
}
}
static void OnButtonPress(GtkWidget* drawingArea, GdkEventButton* event, View* view)
// *********************************************************************************
{
unsigned button = event->button;
ScreenUnit screenX = (ScreenUnit)event->x;
ScreenUnit screenY = (ScreenUnit)event->y;
Point position(GetOnGridUnit(view->GetX(screenX)), GetOnGridUnit(view->GetY(screenY)));
if ( ( button == 4 ) || ( button == 5 ) )
{
view->_OnButtonPress(button, position, event->state);
}
else if (!DRAG_VIEW) {
DRAG_BUTTON = button;
view->_OnButtonPress(button, position, event->state);
DRAG_VIEW = view;
}
}
static void OnButtonRelease(GtkWidget* drawingArea, GdkEventButton* event, View* view)
// ***********************************************************************************
{
unsigned button = event->button;
ScreenUnit screenX = (ScreenUnit)event->x;
ScreenUnit screenY = (ScreenUnit)event->y;
Point position(GetOnGridUnit(view->GetX(screenX)), GetOnGridUnit(view->GetY(screenY)));
if ( ( button == 4 ) || ( button == 5 ) )
{
view->_OnButtonRelease(button, position, event->state);
}
else if (DRAG_VIEW && ( button == DRAG_BUTTON ) ) {
view->_OnButtonRelease(button, position, event->state);
DRAG_VIEW = NULL;
}
}
// ****************************************************************************************************
// View implementation
// ****************************************************************************************************
View::View()
// *********
: Inherit(),
_frame(NULL),
_drawingArea(NULL),
_center(0, 0),
_scale(1),
_backCenter(0, 0),
_backScale(1),
_screenDx(0),
_screenDy(0),
_screenWidth(1),
_screenHeight(1),
_hasBeenExposed(false),
_screenUpdateArea(),
_clipBox(),
_drawable(NULL),
_backgroundGC(NULL),
_foregroundGC(NULL),
_phantomGC(NULL),
_boundaryGC(NULL),
_rubberGC(NULL),
_markerGC(NULL),
_selectionDrawGC(NULL),
_selectionFillGC(NULL),
_gridGC(NULL),
_spotGC(NULL),
_ghostGC(NULL),
_drawGC(NULL),
_fillGC(NULL),
_commandMap(),
_gridIsVisible(true),
_gridDisplayThreshold(6),
_autoScrollIsEnabled(true),
_doubleBufferingIsEnabled(false),
_phantomsAreVisible(true),
_boundariesAreVisible(true),
_rubbersAreVisible(false),
_markersAreVisible(true),
_cutPointsAreVisible(false),
_selectionIsVisible(true),
_displaySlotsAreVisible(true),
_visualMapsAreVisible(false),
_spotIsVisible(false),
_spotIsDrawable(false),
_spotPosition(),
_visibleBasicLayersMask(~0),
_selectorSet(),
_rubberDisplayType(),
_isTextVisible(false),
_nextOfCellViewSet(NULL)
{
}
Unit View::GetX(const ScreenUnit& screenX) const
// *********************************************
{
return GetUnit((screenX - _screenDx) / _scale);
}
Unit View::GetY(const ScreenUnit& screenY) const
// *********************************************
{
return GetUnit(((_screenHeight - screenY) - _screenDy) / _scale);
}
Unit View::GetSize(const ScreenUnit& screenSize) const
// ***************************************************
{
return GetUnit(screenSize / _scale);
}
Point View::GetPoint(const ScreenPoint& screenPoint) const
// *******************************************************
{
return Point(GetX(screenPoint.GetX()), GetY(screenPoint.GetY()));
}
Box View::GetBox(const ScreenBox& screenBox) const
// ***********************************************
{
return Box(GetX(screenBox.GetXMin()),
GetY(screenBox.GetYMin()),
GetX(screenBox.GetXMax()),
GetY(screenBox.GetYMax()));
}
ScreenUnit View::GetScreenX(const Unit& x) const
// *********************************************
{
return _screenDx + (ScreenUnit)(GetValue(x) * _scale);
}
ScreenUnit View::GetScreenY(const Unit& y) const
// *********************************************
{
return _screenHeight - (_screenDy + (ScreenUnit)(GetValue(y) * _scale));
}
ScreenUnit View::GetScreenSize(const Unit& size) const
// ***************************************************
{
return (ScreenUnit)(GetValue(size) * _scale);
}
ScreenPoint View::GetScreenPoint(const Point& point) const
// *******************************************************
{
return Point(GetScreenX(point.GetX()), GetScreenY(point.GetY()));
}
ScreenBox View::GetScreenBox(const Box& box) const
// ***********************************************
{
return Box(GetScreenX(box.GetXMin()),
GetScreenY(box.GetYMin()),
GetScreenX(box.GetXMax()),
GetScreenY(box.GetYMax()));
}
Box View::GetClientArea() const
// ****************************
{
Box area(-1, -1, 1, 1);
Cell* cell = GetCell();
if (cell) {
Box boundingBox = cell->GetBoundingBox();
if (!boundingBox.IsEmpty()) area = boundingBox;
}
GetTransformation().ApplyOn(area);
return area;
}
Box View::GetVisibleArea() const
// *****************************
{
return Box(GetX(0), GetY(0), GetX(_screenWidth), GetY(_screenHeight));
}
Command* View::GetCommand(unsigned button) const
// *********************************************
{
CommandMap::const_iterator it = _commandMap.find(button);
return (it != _commandMap.end()) ? (*it).second : NULL;
}
BasicLayers View::GetVisibleBasicLayers() const
// ********************************************
{
Technology* technology = GetDataBase()->GetTechnology();
return (technology) ? technology->GetBasicLayers(_visibleBasicLayersMask) : BasicLayers();
}
bool View::IsVisible(BasicLayer* basicLayer) const
// ***********************************************
{
if (!basicLayer)
throw Error("Can't evaluate if is visible : null basic layer");
return (basicLayer->GetMask() & _visibleBasicLayersMask);
}
bool View::IsSelected(Go* go) const
// ********************************
{
if (!go)
throw Error("Can't evaluate if is selected : null go");
Occurrence occurrence = go;
return IsSelected(occurrence);
}
bool View::IsSelected(const Occurrence& occurrence) const
// ****************************************************
{
for_each_selector(selector, GetSelectors()) {
if (selector->GetOccurrence() == occurrence) return true;
end_for;
}
return false;
}
void View::SetCell(Cell* newCell)
// ******************************
{
Cell* oldCell = GetCell();
if (newCell != oldCell) {
UnselectAll();
for_each_command(command, GetCommands()) command->UninstallFrom(this); end_for;
_SetCell(newCell);
_SetTransformation(Transformation());
if (_hasBeenExposed) FitToContent();
_backCenter = _center;
_backScale = _scale;
}
}
void View::SetTransformation(const Transformation& newTransformation)
// ******************************************************************
{
Transformation oldTransformation = GetTransformation();
if (newTransformation != oldTransformation) {
_SetTransformation(newTransformation);
if (GetCell()) FitToContent();
_backCenter = _center;
_backScale = _scale;
}
}
void View::ShowGrid()
// ******************
{
if (!_gridIsVisible) {
_gridIsVisible = true;
if (GridIsDrawable()) Invalidate();
}
}
void View::HideGrid()
// ******************
{
if (_gridIsVisible) {
_gridIsVisible = false;
if (GridIsDrawable()) Invalidate();
}
}
void View::SetGridDisplayThreshold(const ScreenUnit& threshold)
// ************************************************************
{
if (threshold < 3)
throw Error("Can't set grid display threshold : too small value");
if (threshold != _gridDisplayThreshold) {
_gridDisplayThreshold = threshold;
Invalidate();
}
}
void View::SetVisibleBasicLayersMask(const Layer::Mask& visibleBasicLayersMask)
// ****************************************************************************
{
if (_visibleBasicLayersMask != visibleBasicLayersMask) {
_visibleBasicLayersMask = visibleBasicLayersMask;
Invalidate();
}
}
void View::ShowPhantoms()
// **********************
{
if (!_phantomsAreVisible) {
_phantomsAreVisible = true;
Invalidate();
}
}
void View::HidePhantoms()
// **********************
{
if (_phantomsAreVisible) {
_phantomsAreVisible = false;
Invalidate();
}
}
void View::ShowBoundaries()
// ************************
{
if (!_boundariesAreVisible) {
_boundariesAreVisible = true;
Invalidate();
}
}
void View::HideBoundaries()
// ************************
{
if (_boundariesAreVisible) {
_boundariesAreVisible = false;
Invalidate();
}
}
void View::ShowCutPoints()
// ***********************
{
if (!_cutPointsAreVisible) {
_cutPointsAreVisible = true;
Invalidate();
}
}
void View::HideCutPoints()
// ***********************
{
if (_cutPointsAreVisible) {
_cutPointsAreVisible = false;
Invalidate();
}
}
void View::ShowRubbers()
// *********************
{
if (!_rubbersAreVisible) {
_rubbersAreVisible = true;
Invalidate();
}
}
void View::HideRubbers()
// *********************
{
if (_rubbersAreVisible) {
_rubbersAreVisible = false;
Invalidate();
}
}
void View::ShowMarkers()
// *********************
{
if (!_markersAreVisible) {
_markersAreVisible = true;
Invalidate();
}
}
void View::HideMarkers()
// *********************
{
if (_markersAreVisible) {
_markersAreVisible = false;
Invalidate();
}
}
void View::ShowSelection()
// ***********************
{
if (!_selectionIsVisible) {
_selectionIsVisible = true;
if (HasSomethingSelected()) Invalidate();
}
}
void View::HideSelection()
// ***********************
{
if (_selectionIsVisible) {
_selectionIsVisible = false;
if (HasSomethingSelected()) Invalidate();
}
}
void View::ShowDisplaySlots()
// **************************
{
if (!_displaySlotsAreVisible) {
_displaySlotsAreVisible = true;
Invalidate();
}
}
void View::HideDisplaySlots()
// **************************
{
if (_displaySlotsAreVisible) {
_displaySlotsAreVisible = false;
Invalidate();
}
}
void View::ShowVisualMaps()
// **************************
{
if (!_visualMapsAreVisible) {
_visualMapsAreVisible = true;
Invalidate();
}
}
void View::HideVisualMaps()
// **************************
{
if (_visualMapsAreVisible) {
_visualMapsAreVisible = false;
Invalidate();
}
}
void View::Show(BasicLayer* basicLayer)
// ************************************
{
if (!basicLayer)
throw Error("Can't show basic layer : null basic layer");
if (!IsVisible(basicLayer)) {
_visibleBasicLayersMask |= basicLayer->GetMask();
Invalidate();
}
}
void View::Hide(BasicLayer* basicLayer)
// ************************************
{
if (!basicLayer)
throw Error("Can't hide basic layer : null basic layer");
if (IsVisible(basicLayer)) {
_visibleBasicLayersMask &= ~basicLayer->GetMask();
Invalidate();
}
}
void View::ShowAllLayers()
// ***********************
{
SetVisibleBasicLayersMask(~0);
}
void View::HideAllLayers()
// ***********************
{
SetVisibleBasicLayersMask(0);
}
void View::Select(Go* go)
// **********************
{
if (!go)
throw Error("Can't select go : null go");
Occurrence occurrence = go;
Select(occurrence);
}
void View::Unselect(Go* go)
// ************************
{
if (!go)
throw Error("Can't unselect go : null go");
Occurrence occurrence = go;
Unselect(occurrence);
}
void View::Select(Occurrence& occurrence)
// ************************************
{
if (!occurrence.IsValid())
throw Error("Can't select occurrence : invalid occurrence");
if (occurrence.GetOwnerCell() != GetCell())
throw Error("Can't select occurrence : incompatible occurrence");
Selector* selector = (Selector*)occurrence.GetProperty(Selector::GetPropertyName());
if (!selector)
selector = Selector::_Create(occurrence);
else
if (!is_a<Selector*>(selector))
throw Error("Abnormal property named " + GetString(Selector::GetPropertyName()));
selector->_AttachTo(this);
Invalidate(GetTransformation().GetBox(occurrence.GetBoundingBox()));
}
void View::Unselect(Occurrence& occurrence)
// **************************************
{
if (!occurrence.IsValid())
throw Error("Can't unselect occurrence : invalid occurrence");
if (occurrence.GetOwnerCell() != GetCell())
throw Error("Can't unselect occurrence : incompatible occurrence");
Selector* selector = (Selector*)occurrence.GetProperty(Selector::GetPropertyName());
if (selector) {
if (!is_a<Selector*>(selector))
throw Error("Abnormal property named " + GetString(Selector::GetPropertyName()));
selector->_DetachFrom(this);
Invalidate(GetTransformation().GetBox(occurrence.GetBoundingBox()));
}
}
void View::UnselectAll()
// *********************
{
Box boundingBox;
for_each_selector(selector, GetSelectors()) {
boundingBox.Merge(selector->GetOccurrence().GetBoundingBox());
selector->_DetachFrom(this);
end_for;
}
if (!boundingBox.IsEmpty())
Invalidate(GetTransformation().GetBox(boundingBox));
}
void View::Invalidate(const ScreenUnit& screenXo, const ScreenUnit& screenYo, const ScreenUnit& screenXe, const ScreenUnit& screenYe)
// ****************************************************************************************************
{
if (_drawingArea && _drawingArea->window) {
ScreenBox screenBox = Box(0, 0, _screenWidth, _screenHeight).Inflate(1);
ScreenBox updateBox = Box(screenXo, screenYo, screenXe, screenYe).Inflate(1);
_screenUpdateArea.Merge(screenBox.GetIntersection(updateBox));
}
}
void View::Invalidate()
// ********************
{
if (_drawingArea && _drawingArea->window)
_screenUpdateArea = ScreenBox(0, 0, _screenWidth, _screenHeight);
}
void View::Invalidate(const Box& area)
// ***********************************
{
if (!area.IsEmpty())
Invalidate(GetScreenX(area.GetXMin()),
GetScreenY(area.GetYMin()),
GetScreenX(area.GetXMax()),
GetScreenY(area.GetYMax()));
}
bool View::Update(bool useDoubleBuffering)
// ***************************************
{
if (_screenUpdateArea.IsEmpty()) return false;
if (!_drawingArea) return false;
GdkWindow* window = _drawingArea->window;
if (!window) return false;
_HideSpot();
for_each_command(command, GetCommands()) {
if (!DRAG_VIEW || (DRAG_VIEW == this))
DrawGhost(command);
end_for;
}
_drawable = window;
_drawGC = _foregroundGC;
_fillGC = _foregroundGC;
_clipBox = Box(GetX(-2), GetY(_screenHeight + 2), GetX(_screenWidth + 2), GetY(-2));
if (IN_AUTO_SCROLL || useDoubleBuffering || _doubleBufferingIsEnabled)
_drawable = GetPixmap(_screenWidth, _screenHeight);
_screenUpdateArea.Inflate(5);
static GdkCursor* sprayCanCursor = gdk_cursor_new(GDK_SPRAYCAN);
gdk_window_set_cursor(window, sprayCanCursor);
_Repaint(GetBox(_screenUpdateArea));
static GdkCursor* leftPtrCursor = gdk_cursor_new(GDK_LEFT_PTR);
gdk_window_set_cursor(window, leftPtrCursor);
if (_drawable != window) {
if (IN_AUTO_SCROLL) _screenUpdateArea = Box(0, 0, _screenWidth, _screenHeight);
gdk_window_copy_area
(window,
_foregroundGC,
_screenUpdateArea.GetXMin(), _screenUpdateArea.GetYMin(),
_drawable,
_screenUpdateArea.GetXMin(), _screenUpdateArea.GetYMin(),
_screenUpdateArea.GetWidth(), _screenUpdateArea.GetHeight());
}
_fillGC = _foregroundGC;
_drawGC = _foregroundGC;
_drawable = window;
_screenUpdateArea = ScreenBox();
for_each_command(command, GetCommands()) {
if (!DRAG_VIEW || (DRAG_VIEW == this))
DrawGhost(command);
end_for;
}
_ShowSpot();
return true;
}
void View::Refresh(bool useDoubleBuffering)
// ****************************************
{
Invalidate();
Update(useDoubleBuffering);
}
void View::CheckForDisplayInterruption()
// *************************************
{
if (_DisplayHasBeenAborted()) throw Interruption("Display");
}
void View::VerticalScroll(const Unit& dy)
// **************************************
{
Reframe(Point(_center).Translate(0, -dy));
}
void View::HorizontalScroll(const Unit& dx)
// ****************************************
{
Reframe(Point(_center).Translate(-dx, 0));
}
void View::Scroll(const Unit& dx, const Unit& dy)
// **********************************************
{
Reframe(Point(_center).Translate(-dx, -dy));
}
void View::Reframe(const Point& center)
// ************************************
{
Reframe(center, _scale);
}
void View::Reframe(const Point& center, double scale)
// **************************************************
{
if ((0 < scale) && ((center != _center) || (scale != _scale))) {
_backCenter = _center;
_backScale = _scale;
_center = center;
_scale = scale;
_screenDx = -(int)((GetValue(_center.GetX()) - (_screenWidth / (_scale * 2))) * _scale);
_screenDy = -(int)((GetValue(_center.GetY()) - (_screenHeight / (_scale * 2))) * _scale);
Invalidate();
}
}
void View::Reframe(const Box& area)
// ********************************
{
if (!area.IsEmpty() && !area.IsFlat())
Reframe(
area.GetCenter(),
min(_screenWidth / GetValue(area.GetWidth()), _screenHeight / GetValue(area.GetHeight())));
}
void View::ReframeBack()
// *********************
{
// _backCenter is mofified inside the Reframe function
// so we should give a copy to have a good behaviour
Reframe(Point(_backCenter), _backScale);
}
void View::FitToContent()
// **********************
{
Box area = GetClientArea();
Point center = _center;
double scale = _scale;
Reframe(area);
area.Inflate(GetSize(10));
Reframe(area);
_backCenter = center;
_backScale = scale;
_hasBeenExposed = true;
}
void View::DrawGhost(Command* command)
// ***********************************
{
if (command) {
GdkGC* oldDrawGC = _drawGC;
GdkGC* oldFillGC = _fillGC;
_drawGC = _ghostGC;
_fillGC = _ghostGC;
command->_OnDrawGhost(this);
_drawGC = oldDrawGC;
_fillGC = oldFillGC;
}
}
void View::DrawPoint(const Unit& x, const Unit& y, const ScreenUnit& screenSize)
// *****************************************************************************
{
if (!_drawable) return;
if (x < _clipBox.GetXMin()) return;
else if (_clipBox.GetXMax() < x) return;
if (y < _clipBox.GetYMin()) return;
else if (_clipBox.GetYMax() < y) return;
ScreenUnit screenX = GetScreenX(x);
ScreenUnit screenY = GetScreenY(y);
static gint ANGLE = 360 * 64;
gdk_draw_arc(_drawable,
_drawGC,
true,
screenX - screenSize,
screenY - screenSize,
(screenSize * 2),
(screenSize * 2),
0,
ANGLE);
}
void View::DrawPoint(const Point& position, const ScreenUnit& screenSize)
// **********************************************************************
{
DrawPoint(position.GetX(), position.GetY(), screenSize);
}
void View::DrawLine(const Unit& xo, const Unit& yo, const Unit& xe, const Unit& ye)
// ********************************************************************************
{
if (!_drawable) return;
Unit cXo = xo;
Unit cYo = yo;
Unit cXe = xe;
Unit cYe = ye;
if (_ClipLine(cXo, cYo, cXe, cYe)) {
gdk_draw_line(_drawable,
_drawGC,
GetScreenX(cXo),
GetScreenY(cYo),
GetScreenX(cXe),
GetScreenY(cYe));
}
}
void View::DrawLine(const Point& origin, const Point& extremity)
// *************************************************************
{
DrawLine(origin.GetX(), origin.GetY(), extremity.GetX(), extremity.GetY());
}
void View::DrawLines(const vector<Point>& points, unsigned size)
// *************************************************************
{
// PROVISOIREMENT : doit faire le clipping
if (!_drawable || !size) return;
if (SIZE < size) {
if (POINTS) delete[] POINTS;
SIZE = size;
POINTS = new GdkPoint[SIZE];
}
for (unsigned i = 0; i < size; i++) {
POINTS[i].x = GetScreenX(points[i].GetX());
POINTS[i].y = GetScreenY(points[i].GetY());
}
gdk_draw_lines(_drawable, _drawGC, POINTS, size);
}
void View::DrawPolygon(const vector<Point>& points, unsigned size)
// ***************************************************************
{
// PROVISOIREMENT : doit faire le clipping
if (!_drawable || !size) return;
if (SIZE < size) {
if (POINTS) delete[] POINTS;
SIZE = size;
POINTS = new GdkPoint[SIZE];
}
for (unsigned i = 0; i < size; i++) {
POINTS[i].x = GetScreenX(points[i].GetX());
POINTS[i].y = GetScreenY(points[i].GetY());
}
gdk_draw_polygon(_drawable, _drawGC, false, POINTS, size);
}
void View::DrawRectangle(const Unit& xo, const Unit& yo, const Unit& xe, const Unit& ye)
// *************************************************************************************
{
DrawRectangle(Box(xo, yo, xe, ye));
}
void View::DrawRectangle(const Point& origin, const Point& extremity)
// ******************************************************************
{
DrawRectangle(Box(origin, extremity));
}
void View::DrawRectangle(const Box& box)
// *************************************
{
if (!_drawable) return;
Box cBox = box;
if (_ClipBox(cBox)) {
Box screenBox = GetScreenBox(cBox);
gdk_draw_rectangle(_drawable,
_drawGC,
false,
screenBox.GetXMin(),
screenBox.GetYMin(),
screenBox.GetWidth(),
screenBox.GetHeight());
}
}
void View::DrawCircle(const Unit& x, const Unit& y, const Unit& radius)
// ********************************************************************
{
if (!_drawable) return;
ScreenUnit screenX = GetScreenX(x);
ScreenUnit screenY = GetScreenY(y);
ScreenUnit screenRadius = GetScreenSize(radius);
static gint ANGLE = 360 * 64;
gdk_draw_arc(_drawable,
_drawGC,
false,
screenX - screenRadius,
screenY - screenRadius,
(screenRadius * 2),
(screenRadius * 2),
0,
ANGLE);
}
void View::DrawCircle(const Point& center, const Unit& radius)
// ***********************************************************
{
DrawCircle(center.GetX(), center.GetY(), radius);
}
void View::DrawString(const string& text, const Unit& x, const Unit& y)
// ********************************************************************
{
if (!_drawable) return;
Unit X = x;
Unit Y = y;
GdkFont * police = gdk_font_load ( "-*-lucidatypewriter-bold-*-*-*-*-120-*-*-*-*-iso8859-1" );
gint textWidth = gdk_string_width ( police, text.c_str() );
gint textHeight = gdk_string_height ( police, text.c_str() );
gdk_draw_string ( _drawable,
police,
_drawGC,
GetScreenX( X ) + 2,
GetScreenY( Y ) + 2,
text.c_str()
);
gdk_draw_rectangle ( _drawable,
_drawGC,
false,
GetScreenX( X ),
GetScreenY( Y ) - textHeight,
textWidth + 4,
textHeight + 4
);
}
void View::FillPolygon(const vector<Point>& points, unsigned size, bool solid)
// ***************************************************************************
{
// PROVISOIREMENT : doit faire le clipping
if (!_drawable || !size) return;
if (SIZE < size) {
if (POINTS) delete[] POINTS;
SIZE = size;
POINTS = new GdkPoint[SIZE];
}
for (unsigned i = 0; i < size; i++) {
POINTS[i].x = GetScreenX(points[i].GetX());
POINTS[i].y = GetScreenY(points[i].GetY());
}
gdk_draw_polygon(_drawable, ((solid) ? _drawGC : _fillGC), true, POINTS, size);
}
void View::FillRectangle(const Unit& xo, const Unit& yo, const Unit& xe, const Unit& ye, bool solid)
// *************************************************************************************************
{
FillRectangle(Box(xo, yo, xe, ye), solid);
}
void View::FillRectangle(const Point& origin, const Point& extremity, bool solid)
// *****************************************************************************
{
FillRectangle(Box(origin, extremity), solid);
}
void View::FillRectangle(const Box& box, bool solid)
// *************************************************
{
if (!_drawable) return;
Box cBox = box;
if (_ClipBox(cBox)) {
Box screenBox = GetScreenBox(cBox);
gdk_draw_rectangle(_drawable,
(solid) ? _drawGC : _fillGC,
true,
screenBox.GetXMin(),
screenBox.GetYMin(),
screenBox.GetWidth() + 1,
screenBox.GetHeight() + 1);
}
}
void View::FillCircle(const Unit& x, const Unit& y, const Unit& radius, bool solid)
// ********************************************************************************
{
if (!_drawable) return;
ScreenUnit screenX = GetScreenX(x);
ScreenUnit screenY = GetScreenY(y);
ScreenUnit screenRadius = GetScreenSize(radius);
static gint ANGLE = 360 * 64;
gdk_draw_arc(_drawable,
(solid) ? _drawGC : _fillGC,
true,
screenX - screenRadius,
screenY - screenRadius,
(screenRadius * 2),
(screenRadius * 2),
0,
ANGLE);
}
void View::FillCircle(const Point& center, const Unit& radius, bool solid)
// ***********************************************************************
{
FillCircle(center.GetX(), center.GetY(), radius, solid);
}
void View::_PostCreate()
// *********************
{
_frame = gtk_table_new(1, 1, false);
gtk_container_set_border_width(GTK_CONTAINER(_frame), 2);
gtk_signal_connect(GTK_OBJECT(_frame), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &_frame);
_drawingArea = gtk_drawing_area_new();
gtk_table_attach
(GTK_TABLE(_frame), _drawingArea, 0, 1, 0, 1, GTK_FILL_EXPAND, GTK_FILL_EXPAND, 0, 0);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &_drawingArea);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "expose_event", GTK_SIGNAL_FUNC(OnExpose), this);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "configure_event", GTK_SIGNAL_FUNC(OnConfigure), this);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "enter_notify_event", GTK_SIGNAL_FUNC(OnEnterNotify), this);
gtk_widget_add_events(GTK_WIDGET(_drawingArea), GDK_ENTER_NOTIFY_MASK);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "motion_notify_event", GTK_SIGNAL_FUNC(OnMotionNotify), this);
gtk_widget_add_events
(GTK_WIDGET(_drawingArea), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "leave_notify_event", GTK_SIGNAL_FUNC(OnLeaveNotify), this);
gtk_widget_add_events(GTK_WIDGET(_drawingArea), GDK_LEAVE_NOTIFY_MASK);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "button_press_event", GTK_SIGNAL_FUNC(OnButtonPress), this);
gtk_widget_add_events(GTK_WIDGET(_drawingArea), GDK_BUTTON_PRESS_MASK);
gtk_signal_connect
(GTK_OBJECT(_drawingArea), "button_release_event", GTK_SIGNAL_FUNC(OnButtonRelease), this);
gtk_widget_add_events(GTK_WIDGET(_drawingArea), GDK_BUTTON_RELEASE_MASK);
_backgroundGC = gtk_gc_new(&_backgroundColor);
_foregroundGC = gtk_gc_new(&_foregroundColor);
_phantomGC = gtk_gc_new(&_phantomColor);
_boundaryGC = gtk_gc_new(&_boundaryColor);
_rubberGC = gtk_gc_new(&_rubberColor);
_markerGC = gtk_gc_new(&_markerColor);
gdk_gc_set_line_attributes (_markerGC, 1, GDK_LINE_SOLID, GDK_CAP_PROJECTING, GDK_JOIN_MITER);
_selectionDrawGC = gtk_gc_new(&_selectionDrawColor);
_selectionFillGC = gtk_gc_new(&_selectionFillColor, "AA55AA55AA55AA55");
_gridGC = gtk_gc_new(&_gridColor);
_spotGC = gtk_gc_new(&_spotColor);
gdk_gc_set_function(_spotGC, GDK_XOR);
_ghostGC = gtk_gc_new(&_ghostColor);
gdk_gc_set_function(_ghostGC, GDK_XOR);
_drawGC = _foregroundGC;
_fillGC = _foregroundGC;
Inherit::_PostCreate();
}
void View::_PreDelete()
// ********************
{
Inherit::_PreDelete();
for_each_selector(selector, GetSelectors()) selector->_DetachFrom(this); end_for;
for_each_command(command, GetCommands()) command->UninstallFrom(this); end_for;
gdk_gc_destroy(_backgroundGC);
gdk_gc_destroy(_foregroundGC);
gdk_gc_destroy(_phantomGC);
gdk_gc_destroy(_boundaryGC);
gdk_gc_destroy(_rubberGC);
gdk_gc_destroy(_markerGC);
gdk_gc_destroy(_selectionDrawGC);
gdk_gc_destroy(_selectionFillGC);
gdk_gc_destroy(_gridGC);
gdk_gc_destroy(_spotGC);
gdk_gc_destroy(_ghostGC);
if (_frame) gtk_widget_destroy(_frame);
Cell* cell = GetCell();
if (cell) cell->_GetViewSet()._Remove(this);
}
string View::_GetString() const
// ****************************
{
string s = Inherit::_GetString();
Cell* cell = GetCell();
if (cell) s.insert(s.length() - 1, " " + GetString(cell->GetName()));
return s;
}
Record* View::_GetRecord() const
// ***********************
{
Record* record = Inherit::_GetRecord();
if (record) {
record->Add(GetSlot("Cell", GetCell()));
record->Add(GetSlot("Transformation",GetTransformation()));
record->Add(GetSlot("Center", &_center));
record->Add(GetSlot("Scale", &_scale));
record->Add(GetSlot("ScreenWidth", &_screenWidth));
record->Add(GetSlot("ScreenHeight", &_screenHeight));
record->Add(GetSlot("Commands", &_commandMap));
record->Add(GetSlot("GridIsVisible", &_gridIsVisible));
record->Add(GetSlot("GridDisplayThreshold", &_gridDisplayThreshold));
record->Add(GetSlot("AutoScrollIsEnabled", &_autoScrollIsEnabled));
record->Add(GetSlot("DoubleBufferingIsEnabled", &_doubleBufferingIsEnabled));
record->Add(GetSlot("PhantomsAreVisible", &_phantomsAreVisible));
record->Add(GetSlot("BoundariesAreVisible", &_boundariesAreVisible));
record->Add(GetSlot("CutPointsAreVisible", &_cutPointsAreVisible));
record->Add(GetSlot("RubbersAreVisible", &_rubbersAreVisible));
record->Add(GetSlot("MarkersAreVisible", &_markersAreVisible));
record->Add(GetSlot("SelectionIsVisible", &_selectionIsVisible));
record->Add(GetSlot("DisplaySlotsAreVisible", &_displaySlotsAreVisible));
record->Add(GetSlot("VisualMapsAreVisible", &_visualMapsAreVisible));
record->Add(GetSlot("VisibleBasicLayersMask", &_visibleBasicLayersMask));
record->Add(GetSlot("Selection", &_selectorSet));
record->Add(GetSlot("RubberDisplayType", &_rubberDisplayType));
}
return record;
}
bool View::_DisplayHasBeenAborted()
// ********************************
{
bool aborted = false;
if (gdk_events_pending()) {
GdkEvent* event = gdk_event_get();
if (event) {
if (event->any.window == _drawingArea->window) {
if ((event->type == GDK_CONFIGURE) ||
(event->type == GDK_BUTTON_PRESS) ||
(event->type == GDK_2BUTTON_PRESS) ||
(event->type == GDK_3BUTTON_PRESS) ||
(event->type == GDK_KEY_PRESS))
aborted = true;
}
if (!aborted) aborted = _DisplayHasBeenAborted();
gdk_event_put(event);
gdk_event_free(event);
}
}
return aborted;
}
void View::_PreRepaint()
// *********************
{
}
void View::_PostRepaint()
// **********************
{
}
void View::_DrawDisplaySlot(DisplaySlot* displaySlot, const Box& area, const Box& updateArea, const Transformation& transformation)
// ********************************************************************************************************************************
{
GdkRectangle clipRectangle;
clipRectangle.x = GetScreenX(area.GetXMin());
clipRectangle.y = GetScreenY(area.GetYMax());
clipRectangle.width = GetScreenX(area.GetXMax()) - clipRectangle.x;
clipRectangle.height = GetScreenY(area.GetYMin()) - clipRectangle.y;
if (displaySlot->IsVisible()) {
_drawGC = displaySlot->_GetDrawGC();
_fillGC = displaySlot->_GetFillGC();
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
displaySlot->_Draw(this, updateArea, transformation);
gdk_flush();
}
}
void View::_Repaint(const Box& area)
// *********************************
{
GdkRectangle clipRectangle;
clipRectangle.x = GetScreenX(area.GetXMin());
clipRectangle.y = GetScreenY(area.GetYMax());
clipRectangle.width = GetScreenX(area.GetXMax()) - clipRectangle.x;
clipRectangle.height = GetScreenY(area.GetYMin()) - clipRectangle.y;
Box updateArea = GetTransformation().GetInvert().GetBox(area);
_drawGC = _backgroundGC;
_fillGC = _backgroundGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
FillRectangle(area, true);
_PreRepaint();
Cell* cell = GetCell();
if (cell) {
if (_phantomsAreVisible) {
_drawGC = _phantomGC;
_fillGC = _phantomGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
cell->_DrawPhantoms(this, updateArea, GetTransformation());
gdk_flush();
}
if (_boundariesAreVisible) {
_drawGC = _boundaryGC;
_fillGC = _boundaryGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
cell->_DrawBoundaries(this, updateArea, GetTransformation());
gdk_flush();
}
_drawGC = _foregroundGC;
_fillGC = _foregroundGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
DataBase* dataBase = GetDataBase();
Technology* technology = dataBase->GetTechnology();
for_each_composite_layer(compositeLayer, technology->GetCompositeLayers()) {
compositeLayer->_UpdateSymbolicBasicLayer(_visibleBasicLayersMask);
end_for;
}
try {
for_each_basic_layer(basicLayer, GetVisibleBasicLayers()) {
CheckForDisplayInterruption();
if (basicLayer->GetDisplayThreshold() < _scale) {
_drawGC = basicLayer->_GetDrawGC();
_fillGC = basicLayer->_GetFillGC();
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
cell->_DrawContent(this, basicLayer, updateArea, GetTransformation());
gdk_flush();
_drawGC = _foregroundGC;
_fillGC = _foregroundGC;
}
end_for;
}
}
catch (Interruption& interruption) {
}
for_each_composite_layer(compositeLayer, technology->GetCompositeLayers()) {
compositeLayer->_UpdateSymbolicBasicLayer(~0);
end_for;
}
if (_rubbersAreVisible) {
_drawGC = _rubberGC;
_fillGC = _rubberGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
cell->_DrawRubbers(this, updateArea, GetTransformation());
gdk_flush();
}
if (_markersAreVisible) {
_drawGC = _markerGC;
_fillGC = _markerGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
cell->_DrawMarkers(this, updateArea, GetTransformation());
gdk_flush();
}
if (_displaySlotsAreVisible) {
cell->_DrawDisplaySlots(this, area, updateArea, GetTransformation());
}
if (_visualMapsAreVisible) {
for_each_visual_map(visualMap, GetVisualMaps(cell)) {
if (visualMap->IsVisible()) {
#if 0
_drawGC = visualMap->_GetGC();
_fillGC = visualMap->_GetGC();
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
#endif
visualMap->_Draw(this, updateArea, GetTransformation());
gdk_flush();
}
end_for;
}
}
bool cutPointsAreVisible = _cutPointsAreVisible;
_cutPointsAreVisible = true;
if (_selectionIsVisible) {
_drawGC = _selectionDrawGC;
_fillGC = _selectionFillGC;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
for_each_selector(selector, GetSelectors()) {
Occurrence occurrence = selector->GetOccurrence();
Entity* entity = occurrence.GetEntity();
Transformation transformation = occurrence.GetPath().GetTransformation();
GetTransformation().ApplyOn(transformation);
if (is_a<Go*>(entity))
((Go*)entity)->_Highlight(this, updateArea, transformation);
end_for;
}
gdk_flush();
}
_cutPointsAreVisible = cutPointsAreVisible;
}
if (GridIsVisible() && GridIsDrawable()) {
Unit xmin = GetOnGridUnit(GetX(0));
Unit ymin = GetOnGridUnit(GetY(_screenHeight));
Unit xmax = GetOnGridUnit(GetX(_screenWidth));
Unit ymax = GetOnGridUnit(GetY(0));
for (Unit xi = xmin; xi <= xmax; xi += GetGridStep()) {
bool bx = IsOnGrid(xi, 10);
for (Unit yi = ymin; yi <= ymax; yi += GetGridStep()) {
bool by = IsOnGrid(yi, 10);
ScreenUnit screenX = GetScreenX(xi);
ScreenUnit screenY = GetScreenY(yi);
if (!bx || !by)
gdk_draw_point(_drawable, _gridGC, screenX, screenY);
else {
gdk_draw_line(_drawable, _gridGC, screenX - 2, screenY, screenX + 2, screenY);
gdk_draw_line(_drawable, _gridGC, screenX, screenY - 2, screenX, screenY + 2);
}
}
}
}
_PostRepaint();
clipRectangle.x = 0;
clipRectangle.y = 0;
clipRectangle.width = _screenWidth;
clipRectangle.height = _screenHeight;
gdk_gc_set_clip_rectangle(_drawGC, &clipRectangle);
gdk_gc_set_clip_rectangle(_fillGC, &clipRectangle);
}
void View::_DrawSpot()
// *******************
{
if (!_drawingArea || !_drawingArea->window) return;
if (_spotIsDrawable) {
ScreenUnit screenX = GetScreenX(_spotPosition.GetX());
ScreenUnit screenY = GetScreenY(_spotPosition.GetY());
if (((-3 <= screenX) && (screenX <= (_screenWidth + 3))) &&
((-3 <= screenY) && (screenY <= (_screenHeight + 3))))
gdk_draw_rectangle(_drawable, _spotGC, false, screenX - 3, screenY - 3, 6, 6);
_spotIsVisible = !_spotIsVisible;
}
}
void View::_ShowSpot()
// *******************
{
if (!_spotIsVisible) _DrawSpot();
}
void View::_HideSpot()
// *******************
{
if (_spotIsVisible) _DrawSpot();
}
int View::_GetClipCode(const Unit& x, const Unit& y) const
// *******************************************************
{
int code = 0;
if (x < _clipBox.GetXMin()) code = 1;
else if (_clipBox.GetXMax() < x) code = 2;
if (y < _clipBox.GetYMin()) code |= 4;
else if (_clipBox.GetYMax() < y) code |= 8;
return code;
}
bool View::_ClipLine(Unit& xo, Unit& yo, Unit& xe, Unit& ye) const
// ***************************************************************
{
int cco = _GetClipCode(xo, yo);
int cce = _GetClipCode(xe, ye);
if (!(cco | cce)) return true;
int c = cco & cce;
if ((c & 1) || (c & 2) || (c & 4) || (c & 8)) return false;
if (cco & 1) {
yo += GetUnit((GetValue(ye - yo) * GetValue(_clipBox.GetXMin() - xo)) / GetValue(xe - xo));
xo = _clipBox.GetXMin();
return _ClipLine(xo, yo, xe, ye);
}
if (cco & 2) {
yo += GetUnit((GetValue(ye - yo) * GetValue(_clipBox.GetXMax() - xo)) / GetValue(xe - xo));
xo = _clipBox.GetXMax();
return _ClipLine(xo, yo, xe, ye);
}
if (cce & 1) {
ye += GetUnit((GetValue(yo - ye) * GetValue(_clipBox.GetXMin() - xe)) / GetValue(xo - xe));
xe = _clipBox.GetXMin();
return _ClipLine(xo, yo, xe, ye);
}
if (cce & 2) {
ye += GetUnit((GetValue(yo - ye) * GetValue(_clipBox.GetXMax() - xe)) / GetValue(xo - xe));
xe = _clipBox.GetXMax();
return _ClipLine(xo, yo, xe, ye);
}
if (cco & 4) {
xo += GetUnit((GetValue(xe - xo) * GetValue(_clipBox.GetYMin() - yo)) / GetValue(ye - yo));
yo = _clipBox.GetYMin();
return _ClipLine(xo, yo, xe, ye);
}
if (cco & 8) {
xo += GetUnit((GetValue(xe - xo) * GetValue(_clipBox.GetYMax() - yo)) / GetValue(ye - yo));
yo = _clipBox.GetYMax();
return _ClipLine(xo, yo, xe, ye);
}
if (cce & 4) {
xe += GetUnit((GetValue(xo - xe) * GetValue(_clipBox.GetYMin() - ye)) / GetValue(yo - ye));
ye = _clipBox.GetYMin();
return _ClipLine(xo, yo, xe, ye);
}
if (cce & 8) {
xe += GetUnit((GetValue(xo - xe) * GetValue(_clipBox.GetYMax() - ye)) / GetValue(yo - ye));
ye = _clipBox.GetYMax();
return _ClipLine(xo, yo, xe, ye);
}
return true;
}
bool View::_ClipBox(Box& box) const
// ********************************
{
box = box.GetIntersection(_clipBox);
return !box.IsEmpty();
}
void View::_OnExpose(const ScreenUnit& screenX, const ScreenUnit& screenY, const ScreenUnit& screenWidth, const ScreenUnit& screenHeight, bool update)
// ****************************************************************************************************
{
if (!_drawingArea) return;
if (!_hasBeenExposed) {
GdkWindow* window = _drawingArea->window;
GdkColormap* colormap = gdk_window_get_colormap(window);
GdkColor color;
color.red = 50 * 255;
color.green = 50 * 255;
color.blue = 50 * 255;
gdk_color_alloc(colormap, &color);
gdk_window_set_background(window, &color);
FitToContent();
_backCenter = _center;
_backScale = _scale;
}
Invalidate(screenX, screenY, screenX + screenWidth, screenY + screenHeight);
if (update) Update();
}
void View::_OnResize(const ScreenUnit& screenWidth, const ScreenUnit& screenHeight)
// ********************************************************************************
{
_screenWidth = screenWidth;
_screenHeight = screenHeight;
if (_drawingArea && _drawingArea->window) {
Point backCenter = _backCenter;
double backScale = _backScale;
double scale = _scale;
_scale = 0; // to force reframe
Reframe(_center, scale);
// to restore good values altered by the hack
_backCenter = backCenter;
_backScale = backScale;
}
}
void View::_OnMouseEnter(const Point& position)
// ********************************************
{
for_each_command(command, GetCommands()) {
command->_OnMouseEnter(this, position);
end_for;
}
_spotIsDrawable = true;
_spotPosition = position;
_ShowSpot();
}
void View::_OnMouseMove(const Point& position, unsigned state)
// ***********************************************************
{
_HideSpot();
for_each_command(command, GetCommands()) {
command->_OnMouseMove(this, position, state);
end_for;
}
_spotPosition = position;
_ShowSpot();
}
void View::_OnMouseLeave(const Point& position)
// ********************************************
{
_HideSpot();
_spotIsDrawable = false;
for_each_command(command, GetCommands()) {
command->_OnMouseLeave(this, position);
end_for;
}
}
void View::_OnButtonPress(unsigned button, const Point& position, unsigned state)
// ******************************************************************************
{
Command* command = GetCommand(button);
if (command) {
_HideSpot();
command->_OnButtonPress(this, position, state);
_ShowSpot();
}
}
void View::_OnButtonRelease(unsigned button, const Point& position, unsigned state)
// ********************************************************************************
{
Command* command = GetCommand(button);
if (command) {
_HideSpot();
command->_OnButtonRelease(this, position, state);
_ShowSpot();
}
}
void View::SetDefaultColor (const string& name, unsigned short red, unsigned short green, unsigned short blue)
// ***********************************************************************************************************
{
GdkColor* color = NULL;
if (name == "background" ) { color = &_backgroundColor; }
else if (name == "foreground" ) { color = &_foregroundColor; }
else if (name == "rubber" ) { color = &_rubberColor; }
else if (name == "phantom" ) { color = &_phantomColor; }
else if (name == "boundary" ) { color = &_boundaryColor; }
else if (name == "marker" ) { color = &_markerColor; }
else if (name == "selectionDraw") { color = &_selectionDrawColor; }
else if (name == "selectionFill") { color = &_selectionFillColor; }
else if (name == "grid" ) { color = &_gridColor; }
else if (name == "spot" ) { color = &_spotColor; }
else if (name == "ghost" ) { color = &_ghostColor; }
else {
throw Error ("Invalid View color name : " + name);
}
color->red = red * 255;
color->green = green * 255;
color->blue = blue * 255;
}
void View::SetColor (const string& name, unsigned short red, unsigned short green, unsigned short blue)
// ****************************************************************************************************
{
GdkColor* color = gdk_color_new(red, green, blue);
GdkGC* gc;
if (name == "background" ) { gc = _backgroundGC; }
else if (name == "foreground" ) { gc = _foregroundGC; }
else if (name == "rubber" ) { gc = _rubberGC; }
else if (name == "phantom" ) { gc = _phantomGC; }
else if (name == "boundary" ) { gc = _boundaryGC; }
else if (name == "marker" ) { gc = _markerGC; }
else if (name == "selectionDraw") { gc = _selectionDrawGC; }
else if (name == "selectionFill") { gc = _selectionFillGC; }
else if (name == "grid" ) { gc = _gridGC; }
else if (name == "spot" ) { gc = _spotGC; }
else if (name == "ghost" ) { gc = _ghostGC; }
else {
throw Error ("Invalid View color name : " + name);
}
gdk_gc_set_foreground(gc, color);
}
void View::SetRubberDisplayType(const RubberDisplayType& rubberdisplaytype)
// ************************************************************************
{
_rubberDisplayType = rubberdisplaytype;
}
void View::SetTextDisplayState(const bool& isTextVisible)
// ************************************************************************
{
_isTextVisible = isTextVisible;
}
// ****************************************************************************************************
// View::RubberDisplayType implementation
// ****************************************************************************************************
View::RubberDisplayType::RubberDisplayType(const Type& type)
// *********************************************************
: _type(type)
{
}
View::RubberDisplayType::RubberDisplayType(const RubberDisplayType& rubberdisplaytype)
// ***********************************************************************************
: _type(rubberdisplaytype._type)
{
}
View::RubberDisplayType& View::RubberDisplayType::operator=(const RubberDisplayType& rubberdisplaytype)
// ****************************************************************************************************
{
_type = rubberdisplaytype._type;
return *this;
}
string View::RubberDisplayType::_GetString() const
// ***********************************************
{
switch (_type) {
case GEOMETRIC : return "GEOMETRIC";
case BARYCENTRIC : return "BARYCENTRIC";
case STEINER: return "STEINER";
}
return "ABNORMAL";
}
Record* View::RubberDisplayType::_GetRecord() const
// ******************************************
{
Record* record = new Record(GetString(this));
record->Add(GetSlot("Type", ((unsigned int*)((void*)&_type))));
return record;
}
} // End of Hurricane namespace.
// ****************************************************************************************************
// Copyright (c) BULL S.A. 2000-2004, All Rights Reserved
// ****************************************************************************************************