From 25de8ef96d58e4e2958303e91988903368fbf11e Mon Sep 17 00:00:00 2001 From: Christophe Alexandre Date: Fri, 4 Jan 2008 16:16:31 +0000 Subject: [PATCH] reorganization --- hurricane/src/CMakeLists.txt | 2 +- .../src/{figures => editor}/CMakeLists.txt | 0 .../src/{figures => editor}/CellFigure.cpp | 0 .../src/{figures => editor}/CellFigure.h | 0 .../src/{figures => editor}/CellScene.cpp | 0 hurricane/src/{figures => editor}/CellScene.h | 0 .../src/{figures => editor}/GoFigure.cpp | 0 hurricane/src/{figures => editor}/GoFigure.h | 0 .../{figures => editor}/InstanceFigure.cpp | 0 .../src/{figures => editor}/InstanceFigure.h | 0 .../src/{figures => editor}/SegmentFigure.cpp | 0 .../src/{figures => editor}/SegmentFigure.h | 0 .../src/{figures => editor}/SliceFigure.cpp | 0 .../src/{figures => editor}/SliceFigure.h | 0 hurricane/src/{figures => editor}/Utils.h | 0 hurricane/src/viewer/CMakeLists.txt | 12 + hurricane/src/viewer/Cell.cpp | 860 ++++++++ hurricane/src/viewer/CellWidget.cpp | 73 + hurricane/src/viewer/CellWidget.h | 34 + hurricane/src/viewer/View.cpp | 1811 +++++++++++++++++ 20 files changed, 2791 insertions(+), 1 deletion(-) rename hurricane/src/{figures => editor}/CMakeLists.txt (100%) rename hurricane/src/{figures => editor}/CellFigure.cpp (100%) rename hurricane/src/{figures => editor}/CellFigure.h (100%) rename hurricane/src/{figures => editor}/CellScene.cpp (100%) rename hurricane/src/{figures => editor}/CellScene.h (100%) rename hurricane/src/{figures => editor}/GoFigure.cpp (100%) rename hurricane/src/{figures => editor}/GoFigure.h (100%) rename hurricane/src/{figures => editor}/InstanceFigure.cpp (100%) rename hurricane/src/{figures => editor}/InstanceFigure.h (100%) rename hurricane/src/{figures => editor}/SegmentFigure.cpp (100%) rename hurricane/src/{figures => editor}/SegmentFigure.h (100%) rename hurricane/src/{figures => editor}/SliceFigure.cpp (100%) rename hurricane/src/{figures => editor}/SliceFigure.h (100%) rename hurricane/src/{figures => editor}/Utils.h (100%) create mode 100644 hurricane/src/viewer/CMakeLists.txt create mode 100644 hurricane/src/viewer/Cell.cpp create mode 100644 hurricane/src/viewer/CellWidget.cpp create mode 100644 hurricane/src/viewer/CellWidget.h create mode 100644 hurricane/src/viewer/View.cpp diff --git a/hurricane/src/CMakeLists.txt b/hurricane/src/CMakeLists.txt index 3962e260..4ec93fc7 100644 --- a/hurricane/src/CMakeLists.txt +++ b/hurricane/src/CMakeLists.txt @@ -10,7 +10,7 @@ find_package(FLEX REQUIRED) add_subdirectory(hurricane) add_subdirectory(analogic) -add_subdirectory(figures) +add_subdirectory(graphical) set(DEST_DIR "$ENV{DESTDIR}") configure_file(${HURRICANE_SOURCE_DIR}/hurricane.pc.cmake hurricane.pc @ONLY) diff --git a/hurricane/src/figures/CMakeLists.txt b/hurricane/src/editor/CMakeLists.txt similarity index 100% rename from hurricane/src/figures/CMakeLists.txt rename to hurricane/src/editor/CMakeLists.txt diff --git a/hurricane/src/figures/CellFigure.cpp b/hurricane/src/editor/CellFigure.cpp similarity index 100% rename from hurricane/src/figures/CellFigure.cpp rename to hurricane/src/editor/CellFigure.cpp diff --git a/hurricane/src/figures/CellFigure.h b/hurricane/src/editor/CellFigure.h similarity index 100% rename from hurricane/src/figures/CellFigure.h rename to hurricane/src/editor/CellFigure.h diff --git a/hurricane/src/figures/CellScene.cpp b/hurricane/src/editor/CellScene.cpp similarity index 100% rename from hurricane/src/figures/CellScene.cpp rename to hurricane/src/editor/CellScene.cpp diff --git a/hurricane/src/figures/CellScene.h b/hurricane/src/editor/CellScene.h similarity index 100% rename from hurricane/src/figures/CellScene.h rename to hurricane/src/editor/CellScene.h diff --git a/hurricane/src/figures/GoFigure.cpp b/hurricane/src/editor/GoFigure.cpp similarity index 100% rename from hurricane/src/figures/GoFigure.cpp rename to hurricane/src/editor/GoFigure.cpp diff --git a/hurricane/src/figures/GoFigure.h b/hurricane/src/editor/GoFigure.h similarity index 100% rename from hurricane/src/figures/GoFigure.h rename to hurricane/src/editor/GoFigure.h diff --git a/hurricane/src/figures/InstanceFigure.cpp b/hurricane/src/editor/InstanceFigure.cpp similarity index 100% rename from hurricane/src/figures/InstanceFigure.cpp rename to hurricane/src/editor/InstanceFigure.cpp diff --git a/hurricane/src/figures/InstanceFigure.h b/hurricane/src/editor/InstanceFigure.h similarity index 100% rename from hurricane/src/figures/InstanceFigure.h rename to hurricane/src/editor/InstanceFigure.h diff --git a/hurricane/src/figures/SegmentFigure.cpp b/hurricane/src/editor/SegmentFigure.cpp similarity index 100% rename from hurricane/src/figures/SegmentFigure.cpp rename to hurricane/src/editor/SegmentFigure.cpp diff --git a/hurricane/src/figures/SegmentFigure.h b/hurricane/src/editor/SegmentFigure.h similarity index 100% rename from hurricane/src/figures/SegmentFigure.h rename to hurricane/src/editor/SegmentFigure.h diff --git a/hurricane/src/figures/SliceFigure.cpp b/hurricane/src/editor/SliceFigure.cpp similarity index 100% rename from hurricane/src/figures/SliceFigure.cpp rename to hurricane/src/editor/SliceFigure.cpp diff --git a/hurricane/src/figures/SliceFigure.h b/hurricane/src/editor/SliceFigure.h similarity index 100% rename from hurricane/src/figures/SliceFigure.h rename to hurricane/src/editor/SliceFigure.h diff --git a/hurricane/src/figures/Utils.h b/hurricane/src/editor/Utils.h similarity index 100% rename from hurricane/src/figures/Utils.h rename to hurricane/src/editor/Utils.h diff --git a/hurricane/src/viewer/CMakeLists.txt b/hurricane/src/viewer/CMakeLists.txt new file mode 100644 index 00000000..354222dc --- /dev/null +++ b/hurricane/src/viewer/CMakeLists.txt @@ -0,0 +1,12 @@ +include(${QT_USE_FILE}) + +include_directories(${HURRICANE_SOURCE_DIR}/hurricane) + +set(includes CellWidget.h) +set(cpps CellWidget.cpp) + +add_library(hurricanefigs SHARED ${cpps}) +target_link_libraries(hurricanefigs ${QT_LIBRARIES} hurricane) + +install(FILES ${includes} DESTINATION /include/hurricane) +install(TARGETS hurricanefigs DESTINATION /lib) diff --git a/hurricane/src/viewer/Cell.cpp b/hurricane/src/viewer/Cell.cpp new file mode 100644 index 00000000..f93ea795 --- /dev/null +++ b/hurricane/src/viewer/Cell.cpp @@ -0,0 +1,860 @@ +// **************************************************************************************************** +// File: Cell.cpp +// Authors: R. Escassut +// Copyright (c) BULL S.A. 2000-2004, All Rights Reserved +// **************************************************************************************************** + +#include "Cell.h" +#include "DataBase.h" +#include "Library.h" +#include "Instance.h" +#include "Net.h" +#include "Pin.h" +#include "RoutingPad.h" +#include "Layer.h" +#include "Slice.h" +#include "Rubber.h" +#include "Marker.h" +#include "Symbol.h" +#include "Primitive.h" +#include "MapView.h" +#include "DisplaySlot.h" +#include "Component.h" +#include "UpdateSession.h" +#include "Error.h" + +namespace Hurricane { + +// **************************************************************************************************** +// Cell implementation +// **************************************************************************************************** + +Cell::Cell(Library* library, const Name& name) +// ******************************************* +: Inherit(), + _library(library), + _name(name), + _instanceMap(), + _quadTree(), + _slaveInstanceSet(), + _netMap(), + _sliceMap(), + _markerSet(), + _viewSet(), + _abutmentBox(), + _boundingBox(), + _isTerminal(true), + _isPad(false), + _symbol(NULL), + _nextOfLibraryCellMap(NULL), + _nextOfSymbolCellSet(NULL), + _slaveEntityMap() +{ + if (!_library) + throw Error("Can't create " + _TName("Cell") + " : null library"); + + if (name.IsEmpty()) + throw Error("Can't create " + _TName("Cell") + " : empty name"); + + if (_library->GetCell(_name)) + throw Error("Can't create " + _TName("Cell") + " : already exists"); +} + +Cell* Cell::Create(Library* library, const Name& name) +// *************************************************** +{ + Cell* cell = new Cell(library, name); + + cell->_PostCreate(); + + return cell; +} + +Box Cell::GetBoundingBox() const +// ***************************** +{ + if (_boundingBox.IsEmpty()) { + Box& boundingBox = (Box&)_boundingBox; + boundingBox = _abutmentBox; + boundingBox.Merge(_quadTree.GetBoundingBox()); + for_each_slice(slice, GetSlices()) { + boundingBox.Merge(slice->GetBoundingBox()); + end_for; + } + } + + return _boundingBox; +} + +bool Cell::IsLeaf() const +// ********************** +{ + return _instanceMap.IsEmpty(); +} + +bool Cell::IsCalledBy(Cell* cell) const +// ************************************ +{ + for_each_instance(instance, cell->GetInstances()) { + Cell* masterCell = instance->GetMasterCell(); + if (masterCell == this) return true; + if (IsCalledBy(masterCell)) return true; + end_for; + } + return false; +} + +void Cell::SetName(const Name& name) +// ********************************* +{ + if (name != _name) { + if (name.IsEmpty()) + throw Error("Can't change " + _TName("Cell") + " name : empty name"); + + if (_library->GetCell(name)) + throw Error("Can't change " + _TName("Cell") + " name : already exists"); + + _library->_GetCellMap()._Remove(this); + _name = name; + _library->_GetCellMap()._Insert(this); + } +} + +void Cell::SetAbutmentBox(const Box& abutmentBox) +// ********************************************** +{ + if (abutmentBox != _abutmentBox) { + if (!_abutmentBox.IsEmpty() && + (abutmentBox.IsEmpty() || !abutmentBox.Contains(_abutmentBox))) + _Unfit(_abutmentBox); + _abutmentBox = abutmentBox; + _Fit(_abutmentBox); + } +} + +void Cell::SetSymbol(Symbol* symbol) +// ********************************* +{ + if (symbol != _symbol) { + OpenUpdateSession(); + if (_symbol) { + _Unfit(_symbol->GetBoundingBox()); + for_each_net(net, GetExternalNets()) { + net->SetPosition(Point(0, 0)); + end_for; + } + _symbol->_GetCellSet()._Remove(this); + } + _symbol = symbol; + if (_symbol) { + _symbol->_GetCellSet()._Insert(this); + for_each_net(net, GetExternalNets()) { + Port* port = _symbol->GetPort(net->GetName()); + if (port) net->SetPosition(port->GetPosition()); + end_for; + } + _Fit(_symbol->GetBoundingBox()); + } + CloseUpdateSession(); + } +} + +void Cell::FlattenNets(bool buildRings) +// ************************************ +{ + OpenUpdateSession (); + + for_each_occurrence ( occurrence, GetHyperNetRootNetOccurrences() ) { + HyperNet hyperNet ( occurrence ); + if ( !occurrence.GetPath().IsEmpty() ) { + DeepNet* deepNet = DeepNet::Create ( hyperNet ); + if (deepNet) deepNet->_CreateRoutingPads ( buildRings ); + } else { + RoutingPad* previousRP = NULL; + RoutingPad* currentRP = NULL; + Net* net = static_cast(occurrence.GetEntity()); + + for_each_component ( component, net->GetComponents() ) { + Plug* primaryPlug = dynamic_cast( component ); + if ( primaryPlug ) { + if ( !primaryPlug->GetBodyHook()->GetSlaveHooks().IsEmpty() ) { + cerr << "[ERROR] " << primaryPlug << "\n" + << " has attached components, not managed yet." << endl; + } else { + primaryPlug->GetBodyHook()->Detach (); + } + } + end_for + } + + for_each_occurrence ( plugOccurrence, hyperNet.GetLeafPlugOccurrences() ) { + currentRP = CreateRoutingPad ( net, plugOccurrence ); + currentRP->Materialize (); + if ( buildRings ) { + if ( previousRP ) { + currentRP->GetBodyHook()->Attach ( previousRP->GetBodyHook() ); + } + Plug* plug = static_cast( plugOccurrence.GetEntity() ); + if ( plugOccurrence.GetPath().IsEmpty() ) { + plug->GetBodyHook()->Attach ( currentRP->GetBodyHook() ); + plug->GetBodyHook()->Detach (); + } + previousRP = currentRP; + } + + end_for + } + + for_each_component ( component, net->GetComponents() ) { + Pin* pin = dynamic_cast( component ); + if ( pin ) { + currentRP = CreateRoutingPad ( pin ); + if ( buildRings ) { + if ( previousRP ) { + currentRP->GetBodyHook()->Attach ( previousRP->GetBodyHook() ); + } + pin->GetBodyHook()->Attach ( currentRP->GetBodyHook() ); + pin->GetBodyHook()->Detach (); + } + previousRP = currentRP; + } + + end_for + } + } + end_for + } + + CloseUpdateSession (); +} + +void Cell::Materialize() +// ********************* +{ + for_each_instance(instance, GetInstances()) instance->Materialize(); end_for; + for_each_net(net, GetNets()) net->Materialize(); end_for; + for_each_marker(marker, GetMarkers()) marker->Materialize(); end_for; +} + +void Cell::Unmaterialize() +// *********************** +{ + for_each_instance(instance, GetInstances()) instance->Unmaterialize(); end_for; + for_each_net(net, GetNets()) net->Unmaterialize(); end_for; + for_each_marker(marker, GetMarkers()) marker->Unmaterialize(); end_for; +} + +void Cell::_PostCreate() +// ********************* +{ + _library->_GetCellMap()._Insert(this); + + Inherit::_PostCreate(); +} + +void Cell::_PreDelete() +// ******************** +{ + Inherit::_PreDelete(); + + while(_slaveEntityMap.size()) { + _slaveEntityMap.begin()->second->Delete(); + } + + if (_symbol) SetSymbol(NULL); + + for_each_view(view, GetViews()) view->SetCell(NULL); end_for; + for_each_marker(marker, GetMarkers()) marker->Delete(); end_for; + for_each_instance(slaveInstance, GetSlaveInstances()) slaveInstance->Delete(); end_for; + for_each_instance(instance, GetInstances()) instance->Delete(); end_for; + for_each_net(net, GetNets()) net->Delete(); end_for; + for_each_slice(slice, GetSlices()) slice->_Delete(); end_for; + + _library->_GetCellMap()._Remove(this); +} + +string Cell::_GetString() const +// **************************** +{ + string s = Inherit::_GetString(); + s.insert(s.length() - 1, " " + GetString(_name)); + return s; +} + +Record* Cell::_GetRecord() const +// *********************** +{ + Record* record = Inherit::_GetRecord(); + if (record) { + record->Add(GetSlot("Library", _library)); + record->Add(GetSlot("Name", &_name)); + record->Add(GetSlot("Instances", &_instanceMap)); + record->Add(GetSlot("QuadTree", &_quadTree)); + record->Add(GetSlot("SlaveInstances", &_slaveInstanceSet)); + record->Add(GetSlot("Nets", &_netMap)); + record->Add(GetSlot("Pins", &_pinMap)); + record->Add(GetSlot("Slices", &_sliceMap)); + record->Add(GetSlot("Markers", &_markerSet)); + record->Add(GetSlot("Views", &_viewSet)); + record->Add(GetSlot("AbutmentBox", &_abutmentBox)); + record->Add(GetSlot("BoundingBox", &_boundingBox)); + record->Add(GetSlot("IsTerminal", &_isTerminal)); + record->Add(GetSlot("IsFlattenLeaf", &_isFlattenLeaf)); + //record->Add(GetSlot("Symbol", _symbol)); + } + return record; +} + +void Cell::_Fit(const Box& box) +// **************************** +{ + if (box.IsEmpty()) return; + if (_boundingBox.IsEmpty()) return; + if (_boundingBox.Contains(box)) return; + _boundingBox.Merge(box); + for_each_instance(instance, GetSlaveInstances()) { + instance->GetCell()->_Fit(instance->GetTransformation().GetBox(box)); + end_for; + } +} + +void Cell::_Unfit(const Box& box) +// ****************************** +{ + if (box.IsEmpty()) return; + if (_boundingBox.IsEmpty()) return; + if (!_boundingBox.IsConstrainedBy(box)) return; + _boundingBox.MakeEmpty(); + for_each_instance(instance, GetSlaveInstances()) { + instance->GetCell()->_Unfit(instance->GetTransformation().GetBox(box)); + end_for; + } +} + +void Cell::_AddSlaveEntity(Entity* entity, Entity* slaveEntity) +// ************************************************************************ +{ + assert(entity->GetCell() == this); + + _slaveEntityMap.insert(pair(entity,slaveEntity)); +} + +void Cell::_RemoveSlaveEntity(Entity* entity, Entity* slaveEntity) +// *************************************************************************** +{ + assert(entity->GetCell() == this); + + pair + bounds = _slaveEntityMap.equal_range(entity); + multimap::iterator it = bounds.first; + for(; it != bounds.second ; it++ ) { + if (it->second == slaveEntity) { + _slaveEntityMap.erase(it); + break; + } + } +} + +void Cell::_GetSlaveEntities(SlaveEntityMap::iterator& begin, SlaveEntityMap::iterator& end) +// ********************************************************************************************************* +{ + begin = _slaveEntityMap.begin(); + end = _slaveEntityMap.end(); +} + +void Cell::_GetSlaveEntities(Entity* entity, SlaveEntityMap::iterator& begin, SlaveEntityMap::iterator& end) +// ********************************************************************************************************* +{ + begin = _slaveEntityMap.lower_bound(entity); + end = _slaveEntityMap.upper_bound(entity); +} + +bool Cell::_IsDrawable(View* view) const +// ************************************* +{ + if (view->GetCell() == this) return true; + + if (is_a(view)) return true; + + return (1 < (double)view->GetScreenSize(_boundingBox.GetHeight())); +// return (100 < ((double)view->GetScreenSize(_boundingBox.GetWidth()) * +// (double)view->GetScreenSize(_boundingBox.GetHeight()))); +} + +bool Cell::_ContentIsDrawable(View* view) const +// ******************************************** +{ + if (IsTerminal()) return false; + + if (view->GetCell() == this) return true; + + if (is_a(view)) return false; + + return (40 < (double)view->GetScreenSize(_boundingBox.GetHeight())); +// return (400 < ((double)view->GetScreenSize(_boundingBox.GetWidth()) * +// (double)view->GetScreenSize(_boundingBox.GetHeight()))); +} + +void Cell::_DrawPhantoms(View* view, const Box& updateArea, const Transformation& transformation) +// ********************************************************************************************** +{ + if (_IsDrawable(view)) { // To avoid irregular display of instances phantoms + if (!_ContentIsDrawable(view)) + view->FillRectangle(transformation.GetBox(GetAbutmentBox())); + else { + for_each_instance(instance, GetInstancesUnder(updateArea)) { + instance->_DrawPhantoms(view, updateArea, transformation); + end_for; + } + } + } +} + +void Cell::_DrawBoundaries(View* view, const Box& updateArea, const Transformation& transformation) +// ************************************************************************************************ +{ + if (_IsDrawable(view)) { // To avoid irregular display of instances phantoms + view->DrawRectangle(transformation.GetBox(GetAbutmentBox())); + if (_ContentIsDrawable(view)) { + for_each_instance(instance, GetInstancesUnder(updateArea)) { + instance->_DrawBoundaries(view, updateArea, transformation); + end_for; + } + } + } +} + +void Cell::_DrawContent(View* view, BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) +// **************************************************************************************************** +{ + if (_IsDrawable(view)) { + if (_ContentIsDrawable(view)) { + view->CheckForDisplayInterruption(); + for_each_instance(instance, GetInstancesUnder(updateArea)) { + instance->_Draw(view, basicLayer, updateArea, transformation); + end_for; + } + for_each_slice(slice, GetSlices()) { + slice->_Draw(view, basicLayer, updateArea, transformation); + end_for; + } + } + } +} + +void Cell::_DrawRubbers(View* view, const Box& updateArea, const Transformation& transformation) +// ********************************************************************************************* +{ + if (_IsDrawable(view)) { + if (_ContentIsDrawable(view)) { + for_each_instance(instance, GetInstancesUnder(updateArea)) { + instance->_DrawRubbers(view, updateArea, transformation); + end_for; + } + for_each_rubber(rubber, GetRubbersUnder(updateArea)) { + rubber->_Draw(view, NULL, updateArea, transformation); + end_for; + } + } + } +} + +void Cell::_DrawMarkers(View* view, const Box& updateArea, const Transformation& transformation) +// ********************************************************************************************* +{ + if (_IsDrawable(view)) { + if (_ContentIsDrawable(view)) { + for_each_instance(instance, GetInstancesUnder(updateArea)) { + instance->_DrawMarkers(view, updateArea, transformation); + end_for; + } + for_each_marker(marker, GetMarkersUnder(updateArea)) { + marker->_Draw(view, NULL, updateArea, transformation); + end_for; + } + } + } +} + +void Cell::_DrawDisplaySlots(View* view, const Box& area, const Box& updateArea, const Transformation& transformation) +// ******************************************************************************************************************** +{ + if (_IsDrawable(view)) { + if (_ContentIsDrawable(view)) { + for_each_instance(instance, GetInstancesUnder(updateArea)) { + instance->_DrawDisplaySlots(view, area, updateArea, transformation); + end_for; + } + for_each_display_slot(displaySlot, GetDisplaySlots(this)) { + view->_DrawDisplaySlot(displaySlot, area, updateArea, transformation); + end_for; + } + } + } +} + +void Cell::_SaveHeaderTo(OutputFile& outputFile) +// ********************************************* +{ + outputFile.Register(this); + + Inherit::_SaveHeaderTo(outputFile); + + outputFile << " " << outputFile.GetId(GetLibrary()); + outputFile << " " << GetName(); + outputFile << " " << GetValueString(GetAbutmentBox().GetXMin()); + outputFile << " " << GetValueString(GetAbutmentBox().GetYMin()); + outputFile << " " << GetValueString(GetAbutmentBox().GetXMax()); + outputFile << " " << GetValueString(GetAbutmentBox().GetYMax()); + outputFile << " " << ((IsTerminal()) ? '1' : '0'); +} + +void Cell::_SaveContentTo(OutputFile& outputFile) +// ********************************************** +{ + Inherit::_SaveContentTo(outputFile); + + for_each_instance(instance, GetInstances()) { + instance->_SaveTo(outputFile); + end_for; + } + + for_each_net(net, GetNets()) { + net->_SaveTo(outputFile); + end_for; + } +} + +void Cell::_Realize(Hurricane::Builder* builder, InputFile& inputFile) +// ******************************************************************* +{ + assert(is_a(builder)); + + Cell::Builder* cellBuilder = (Cell::Builder*)builder; + + SetAbutmentBox(cellBuilder->GetAbutmentBox()); + SetTerminal(cellBuilder->IsTerminal()); + + // PROVISOIREMENT + string s = GetString(GetName()); + Library* library = GetLibrary(); + while (library) { + s = GetString(library->GetName()) + "/" + s; + library = library->GetLibrary(); + } + cout << " Loading cell " << s << endl; + // PROVISOIREMENT + + inputFile.Register(this); + + Go::DisableAutoMaterialization(); + + OpenUpdateSession(); + + Inherit::_Realize(builder, inputFile); +} + +void Cell::_Finalize(InputFile& inputFile) +// *************************************** +{ + CloseUpdateSession(); + + Go::EnableAutoMaterialization(); + + Materialize(); + + Inherit::_Finalize(inputFile); +} + + + +// **************************************************************************************************** +// Cell::InstanceMap implementation +// **************************************************************************************************** + +Cell::InstanceMap::InstanceMap() +// ***************************** +: Inherit() +{ +} + +Name Cell::InstanceMap::_GetKey(Instance* instance) const +// ****************************************************** +{ + return instance->GetName(); +} + +unsigned Cell::InstanceMap::_GetHashValue(Name name) const +// ******************************************************* +{ + return ( (unsigned int)( (unsigned long)name._GetSharedName() ) ) / 8; +} + +Instance* Cell::InstanceMap::_GetNextElement(Instance* instance) const +// ******************************************************************* +{ + return instance->_GetNextOfCellInstanceMap(); +} + +void Cell::InstanceMap::_SetNextElement(Instance* instance, Instance* nextInstance) const +// ************************************************************************************** +{ + instance->_SetNextOfCellInstanceMap(nextInstance); +} + + + +// **************************************************************************************************** +// Cell::SlaveInstanceSet implementation +// **************************************************************************************************** + +Cell::SlaveInstanceSet::SlaveInstanceSet() +// *************************************** +: Inherit() +{ +} + +unsigned Cell::SlaveInstanceSet::_GetHashValue(Instance* slaveInstance) const +// ************************************************************************** +{ + return ( (unsigned int)( (unsigned long)slaveInstance ) ) / 8; +} + +Instance* Cell::SlaveInstanceSet::_GetNextElement(Instance* slaveInstance) const +// ***************************************************************************** +{ + return slaveInstance->_GetNextOfCellSlaveInstanceSet(); +} + +void Cell::SlaveInstanceSet::_SetNextElement(Instance* slaveInstance, Instance* nextSlaveInstance) const +// **************************************************************************************************** +{ + slaveInstance->_SetNextOfCellSlaveInstanceSet(nextSlaveInstance); +} + + + +// **************************************************************************************************** +// Cell::NetMap implementation +// **************************************************************************************************** + +Cell::NetMap::NetMap() +// ******************* +: Inherit() +{ +} + +Name Cell::NetMap::_GetKey(Net* net) const +// *************************************** +{ + return net->GetName(); +} + +unsigned Cell::NetMap::_GetHashValue(Name name) const +// ************************************************** +{ + return ( (unsigned int)( (unsigned long)name._GetSharedName() ) ) / 8; +} + +Net* Cell::NetMap::_GetNextElement(Net* net) const +// *********************************************** +{ + return net->_GetNextOfCellNetMap(); +} + +void Cell::NetMap::_SetNextElement(Net* net, Net* nextNet) const +// ************************************************************* +{ + net->_SetNextOfCellNetMap(nextNet); +} + + +// **************************************************************************************************** +// Cell::PinMap implementation +// **************************************************************************************************** + +Cell::PinMap::PinMap() +// ******************* +: Inherit() +{ +} + +Name Cell::PinMap::_GetKey(Pin* pin) const +// *************************************** +{ + return pin->GetName(); +} + +unsigned Cell::PinMap::_GetHashValue(Name name) const +// ************************************************** +{ + return ( (unsigned int)( (unsigned long)name._GetSharedName() ) ) / 8; +} + +Pin* Cell::PinMap::_GetNextElement(Pin* pin) const +// *********************************************** +{ + return pin->_GetNextOfCellPinMap(); +} + +void Cell::PinMap::_SetNextElement(Pin* pin, Pin* nextPin) const +// ************************************************************* +{ + pin->_SetNextOfCellPinMap(nextPin); +} + + +// **************************************************************************************************** +// Cell::SliceMap implementation +// **************************************************************************************************** + +Cell::SliceMap::SliceMap() +// *********************** +: Inherit() +{ +} + +const Layer* Cell::SliceMap::_GetKey(Slice* slice) const +// ***************************************************** +{ + return slice->GetLayer(); +} + +unsigned Cell::SliceMap::_GetHashValue(const Layer* layer) const +// ************************************************************* +{ + return ( (unsigned int)( (unsigned long)layer ) ) / 8; +} + +Slice* Cell::SliceMap::_GetNextElement(Slice* slice) const +// ******************************************************* +{ + return slice->_GetNextOfCellSliceMap(); +} + +void Cell::SliceMap::_SetNextElement(Slice* slice, Slice* nextSlice) const +// *********************************************************************** +{ + slice->_SetNextOfCellSliceMap(nextSlice); +}; + + + +// **************************************************************************************************** +// Cell::MarkerSet implementation +// **************************************************************************************************** + +Cell::MarkerSet::MarkerSet() +// ************************* +: Inherit() +{ +} + +unsigned Cell::MarkerSet::_GetHashValue(Marker* marker) const +// ********************************************************** +{ + return ( (unsigned int)( (unsigned long)marker ) ) / 8; +} + +Marker* Cell::MarkerSet::_GetNextElement(Marker* marker) const +// *********************************************************** +{ + return marker->_GetNextOfCellMarkerSet(); +} + +void Cell::MarkerSet::_SetNextElement(Marker* marker, Marker* nextMarker) const +// **************************************************************************** +{ + marker->_SetNextOfCellMarkerSet(nextMarker); +} + + + +// **************************************************************************************************** +// Cell::ViewSet implementation +// **************************************************************************************************** + +Cell::ViewSet::ViewSet() +// ********************* +: Inherit() +{ +} + +unsigned Cell::ViewSet::_GetHashValue(View* view) const +// **************************************************** +{ + return ( (unsigned int)( (unsigned long)view ) ) / 8; +} + +View* Cell::ViewSet::_GetNextElement(View* view) const +// *************************************************** +{ + return view->_GetNextOfCellViewSet(); +} + +void Cell::ViewSet::_SetNextElement(View* view, View* nextView) const +// ****************************************************************** +{ + view->_SetNextOfCellViewSet(nextView); +} + + + +// **************************************************************************************************** +// Cell::Builder declaration +// **************************************************************************************************** + +Cell::Builder::Builder(const string& token) +// **************************************** +: Inherit(token), + _library(NULL), + _name(), + _xMin(0), + _yMin(0), + _xMax(0), + _yMax(0), + _isTerminal(0) +{ +} + +void Cell::Builder::Scan(InputFile& inputFile, char*& arguments) +// ************************************************************* +{ + DBo* owner = inputFile.GetOwner(); + + if (!is_a(owner)) + throw Error("Can't create Cell : bad owner"); + + Inherit::Scan(inputFile, arguments); + + unsigned libraryId; + unsigned n; + + int r = sscanf(arguments, "%u%s%lf%lf%lf%lf%u%n", &libraryId, _name, + &_xMin, &_yMin, &_xMax, &_yMax, &_isTerminal, &n); + + if (r != 7) + throw Error("Can't create Cell : syntax error"); + + arguments = &arguments[n]; + + DBo* dbo = inputFile.GetDBo(libraryId); + if (!dbo || !is_a(dbo)) + throw Error("Can't create Cell : bad library"); + + _library = (Library*)dbo; +} + +DBo* Cell::Builder::CreateDBo() +// **************************** +{ + return Cell::Create(GetLibrary(), GetName()); +} + +Cell::Builder CELL_BUILDER("C"); + +} // End of Hurricane namespace. + +// **************************************************************************************************** +// Copyright (c) BULL S.A. 2000-2004, All Rights Reserved +// **************************************************************************************************** diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp new file mode 100644 index 00000000..bcbeb770 --- /dev/null +++ b/hurricane/src/viewer/CellWidget.cpp @@ -0,0 +1,73 @@ +#include + +#include +#include + +#include "DataBase.h" +#include "Technology.h" +#include "Box.h" +using namespace H; + +#include "CellWidget.h" + +namespace { + +Technology* getTechnology() { + DataBase* database = GetDataBase(); + if (database) { + return database->GetTechnology(); + } + return NULL; +} + +CellWidget::CellWidget(Cell* c, QWidget* parent) + : QAbstractScrollArea(parent), + cell(c) { +} + +void CellWidget::paintEvent(QPaintEvent* event) { + //invalidate(event->rect()); + redraw(); +} + +void CellWidget::redraw() { + drawPhantoms(cell); + drawBoundaries(cell); + for_each_layer(layer, getTechnology()->GetLayers()) { + drawCell(cell, layer); + end_for; + } +} + +void CellWidget::drawCell(const Cell* cell, const Layer* layer) const { +} + +void CellWidget::drawPhantoms(const Cell* cell) const { +} + +void CellWidget::drawBoundaries(const Cell* cell) const { +} + +void CellWidget::drawRectangle(const H::Box& box) { + if (painter) { + H::Box ibox = box.getIntersection(clipBox); + if (!ibox.isEmpty()) { + int x = getScreenX(ibox.getXMin()); + int y = getScreenY(ibox.getYMax()); + int w = getScreenX(ibox.getXMax()) - x + 1; + int h = getScreenY(ibox.getYMin()) - y + 1; + + painter->drawRect(x, y, w, h); + } + } +} + +int CellWidget::getScreenX(const Unit& x) const { + return screenDx + (int)rint(GetValue(x) * scale); +} + +int CellWidget::getScreenY(const Unit& y) const { + return height() - (int)rint(screenDy + (GetValue(y) * scale)); +} + +} diff --git a/hurricane/src/viewer/CellWidget.h b/hurricane/src/viewer/CellWidget.h new file mode 100644 index 00000000..9e9f637f --- /dev/null +++ b/hurricane/src/viewer/CellWidget.h @@ -0,0 +1,34 @@ +#ifndef __CELL_WIDGET_H +#define __CELL_WIDGET_H + +#include + +#include "Box.h" +#include "Cell.h" +using namespace H; + + +class CellWidget : public QAbstractScrollArea { + public: + CellWidget(Cell* cell, QWidget* parent=0); + void redraw(); + protected: + void paintEvent(QPaintEvent* event); + private: + Cell* cell; + QPainter* painter; + H::Box clipBox; + double scale; + int screenDx; + int screenDy; + + void drawCell(const Cell* cell, const Layer* layer) const; + void drawPhantoms(const Cell* cell) const; + void drawBoundaries(const Cell* cell) const; + void drawRectangle(const H::Box& box); + int getScreenX(const Unit& x) const; + int getScreenY(const Unit& y) const; +}; + + +#endif /* __CELL_WIDGET_H */ diff --git a/hurricane/src/viewer/View.cpp b/hurricane/src/viewer/View.cpp new file mode 100644 index 00000000..1bfd319f --- /dev/null +++ b/hurricane/src/viewer/View.cpp @@ -0,0 +1,1811 @@ +// **************************************************************************************************** +// 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)) + 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)) + 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& 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& 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& 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(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 +// ****************************************************************************************************