From 8544dc5116cb5aa838eed5330507f95b3220582f Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 3 Apr 2008 15:13:57 +0000 Subject: [PATCH] Old viewer by xtof. To be deleted sometime. --- hurricane/src/viewer.xtof/CMakeLists.txt | 15 + hurricane/src/viewer.xtof/Cell.cpp | 860 ++++++ hurricane/src/viewer.xtof/CellViewer.cpp | 93 + hurricane/src/viewer.xtof/CellViewer.h | 39 + hurricane/src/viewer.xtof/CellWidget.cpp | 2765 ++++++++++++++++++++ hurricane/src/viewer.xtof/CellWidget.h | 1641 ++++++++++++ hurricane/src/viewer.xtof/LayersWidget.cpp | 45 + hurricane/src/viewer.xtof/LayersWidget.h | 19 + hurricane/src/viewer.xtof/View.cpp | 1811 +++++++++++++ 9 files changed, 7288 insertions(+) create mode 100644 hurricane/src/viewer.xtof/CMakeLists.txt create mode 100644 hurricane/src/viewer.xtof/Cell.cpp create mode 100644 hurricane/src/viewer.xtof/CellViewer.cpp create mode 100644 hurricane/src/viewer.xtof/CellViewer.h create mode 100644 hurricane/src/viewer.xtof/CellWidget.cpp create mode 100644 hurricane/src/viewer.xtof/CellWidget.h create mode 100644 hurricane/src/viewer.xtof/LayersWidget.cpp create mode 100644 hurricane/src/viewer.xtof/LayersWidget.h create mode 100644 hurricane/src/viewer.xtof/View.cpp diff --git a/hurricane/src/viewer.xtof/CMakeLists.txt b/hurricane/src/viewer.xtof/CMakeLists.txt new file mode 100644 index 00000000..021b690c --- /dev/null +++ b/hurricane/src/viewer.xtof/CMakeLists.txt @@ -0,0 +1,15 @@ +include(${QT_USE_FILE}) + +include_directories(${HURRICANE_SOURCE_DIR}/src/hurricane) + +set(includes CellWidget.h LayersWidget.h CellViewer.h) +set(exports CellViewer.h) +set(cpps CellWidget.cpp LayersWidget.cpp CellViewer.cpp) + +QT4_WRAP_CPP(MOC_SRCS ${includes}) + +add_library(hurricaneviewer SHARED ${cpps} ${MOC_SRCS}) +target_link_libraries(hurricaneviewer ${QT_LIBRARIES} hurricane) + +install(FILES ${exports} DESTINATION /include/hurricane) +install(TARGETS hurricaneviewer DESTINATION /lib) diff --git a/hurricane/src/viewer.xtof/Cell.cpp b/hurricane/src/viewer.xtof/Cell.cpp new file mode 100644 index 00000000..f93ea795 --- /dev/null +++ b/hurricane/src/viewer.xtof/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.xtof/CellViewer.cpp b/hurricane/src/viewer.xtof/CellViewer.cpp new file mode 100644 index 00000000..2da1e23b --- /dev/null +++ b/hurricane/src/viewer.xtof/CellViewer.cpp @@ -0,0 +1,93 @@ +#include + +#include "CellWidget.h" +#include "LayersWidget.h" + +#include "CellViewer.h" + +CellViewer::CellViewer(Cell* cell) + : QMainWindow() +{ + cellWidget = new CellWidget(cell); + setCentralWidget(cellWidget); + + createActions(); + createMenus(); + + setWindowTitle(tr("Cell Viewer")); + resize(1000, 500); +} + +CellViewer::~CellViewer() { + delete cellWidget; + delete layersWidget; +} + +static int scrollStep = getUnit(200); + +void CellViewer::keyPressEvent(QKeyEvent *event) { + switch (event->key()) { + case Qt::Key_Left: + cellWidget->scroll(-scrollStep, 0); + break; + case Qt::Key_Right: + cellWidget->scroll(+scrollStep, 0); + break; + case Qt::Key_Down: + cellWidget->scroll(0, -scrollStep); + break; + case Qt::Key_Up: + cellWidget->scroll(0, +scrollStep); + break; + default: + QWidget::keyPressEvent(event); + } +} + +// +//void CellViewer::wheelEvent(QWheelEvent *event) { +// int numDegrees = event->delta() / 8; +// double numSteps = numDegrees / 15.0f; +// zoom(pow(ZoomInFactor, numSteps)); +//} + +void CellViewer::zoomIn() { + cellWidget->reframe(cellWidget->getScale() * 1.2); + cellWidget->update(); +} + +void CellViewer::zoomOut() { + cellWidget->reframe(cellWidget->getScale() / 1.2); + cellWidget->update(); +} + +void CellViewer::fitToWindow() { + cellWidget->fitToContent(); + cellWidget->update(); +} + +void CellViewer::createActions() { + zoomInAct = new QAction(tr("Zoom &In (25%)"), this); + zoomInAct->setShortcut(tr("Ctrl++")); + zoomInAct->setEnabled(true); + connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomIn())); + + zoomOutAct = new QAction(tr("Zoom &Out (25%)"), this); + zoomOutAct->setShortcut(tr("Ctrl+-")); + zoomOutAct->setEnabled(true); + connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOut())); + + fitToWindowAct = new QAction(tr("Fit &To &Window"), this); + fitToWindowAct->setShortcut(tr("f")); + fitToWindowAct->setEnabled(true); + connect(fitToWindowAct, SIGNAL(triggered()), this, SLOT(fitToWindow())); +} + +void CellViewer::createMenus() { + viewMenu = new QMenu(tr("&View"), this); + viewMenu->addAction(zoomInAct); + viewMenu->addAction(zoomOutAct); + viewMenu->addAction(fitToWindowAct); + + menuBar()->addMenu(viewMenu); +} diff --git a/hurricane/src/viewer.xtof/CellViewer.h b/hurricane/src/viewer.xtof/CellViewer.h new file mode 100644 index 00000000..cd304103 --- /dev/null +++ b/hurricane/src/viewer.xtof/CellViewer.h @@ -0,0 +1,39 @@ +#ifndef __CELL_VIEWER_H +#define __CELL_VIEWER_H + +#include "Cell.h" +using namespace Hurricane; + +#include + +class CellWidget; +class LayersWidget; + +class CellViewer : public QMainWindow { + Q_OBJECT + + public: + CellViewer(Cell* cell); + ~CellViewer(); + private: + CellWidget* cellWidget; + LayersWidget* layersWidget; + + QAction *zoomInAct; + QAction *zoomOutAct; + QAction *fitToWindowAct; + QMenu *viewMenu; + + void createActions(); + void createMenus(); + + private slots: + void zoomIn(); + void zoomOut(); + void fitToWindow(); + protected: + void keyPressEvent(QKeyEvent *event); + +}; + +#endif diff --git a/hurricane/src/viewer.xtof/CellWidget.cpp b/hurricane/src/viewer.xtof/CellWidget.cpp new file mode 100644 index 00000000..f46ab916 --- /dev/null +++ b/hurricane/src/viewer.xtof/CellWidget.cpp @@ -0,0 +1,2765 @@ +// ************************************************************************************************* +// ************************************************************************************************* +// File: CellWidget.cpp +// ************************************************************************************************* +// ************************************************************************************************* + +#include "CellWidget.h" + +#include "Cell.h" +#include "Boxes.h" +//#include "Command.h" +#include "DataBase.h" +#include "Exception.h" +#include "Layer.h" +#include "Record.h" +//#include "Selector.h" +#include "Slice.h" +#include "Slot.h" +#include "Technology.h" +#include "Transformation.h" +using namespace Hurricane; + +#include +#include +#include + +#include +#include + +//OPEN_MY_NAMESPACE + +namespace { + +QBrush getBrush(const string &pattern, int redValue, int greenValue, int blueValue) { + if (pattern == "FFFFFFFFFFFFFFFF") { + return QBrush(QColor(redValue, greenValue, blueValue)); + } else { + uchar bits[8]; + for (int i = 0; i < 8; i++) { + int high = pattern[i * 2]; + if (('0' <= high) && (high <= '9')) { + high = high - '0'; + } else { + if (('a' <= high) && (high <= 'f')) { + high = 10 + high - 'a'; + } else { + if (('A' <= high) && (high <= 'F')) { + high = 10 + high - 'A'; + } else { + high = '0'; + } + } + } + int low = pattern[(i * 2) + 1]; + if (('0' <= low) && (low <= '9')) { + low = low - '0'; + } else { + if (('a' <= low) && (low <= 'f')) { + low = 10 + low - 'a'; + } else { + if (('A' <= low) && (low <= 'F')) { + low = 10 + low - 'A'; + } else { + low = '0'; + } + } + } + bits[i] = (uchar)((high * 16) + low); + } + + return QBrush(QColor(redValue, greenValue, blueValue), QBitmap::fromData(QSize(8,8), bits, QImage::Format_Mono)); + } +} + +static QColor backgroundColor = QColor( 50, 50, 50 ); +static QColor foregroundColor = QColor( 255, 255, 255 ); +static QColor rubberColor = QColor( 192, 0, 192 ); +static QColor phantomColor = QColor( 139, 134, 130 ); +static QColor boundaryColor = QColor( 208, 199, 192 ); +static QColor markerColor = QColor( 80, 250, 80 ); +static QColor selectionDrawColor = QColor( 255, 255, 255 ); +static QColor selectionFillColor = QColor( 255, 255, 255 ); +static QColor gridColor = QColor( 255, 255, 255 ); +static QColor spotColor = QColor( 255, 255, 255 ); +static QColor ghostColor = QColor( 255, 255, 255 ); + +static QPen boundariesPen = QPen(boundaryColor); +static QBrush boundariesBrush = QBrush(boundaryColor); +static QPen phantomsPen = QPen(phantomColor); +static QBrush phantomsBrush = QBrush(phantomColor); +static QBrush defaultBrush = QBrush(); +static QPen defaultPen = QPen(); + +} + + +Cell* +CellWidget::getCell() const { + return _cell; +} + +// ************************************************************************************************* +// getLabel() +// ************************************************************************************************* + +///static +///Label +///getLabel(const QColor& color) +///{ +/// return getLabel(color.red()) + ":" + getLabel(color.green()) + ":" + getLabel(color.blue()); +///} +/// + + +// ************************************************************************************************* +// CellWidget::_sPoints +// ************************************************************************************************* + +//QPointArray CellWidget::_sPoints; + + + +// ************************************************************************************************* +// CellWidget::CellWidget() +// ************************************************************************************************* + +CellWidget::CellWidget(Cell* cell, + QWidget* parent, + const char* name) +: Inherit(parent), + _cell(cell), + _center(0, 0), + _scale(1), + _screenDx(0), + _screenDy(0), + _brushDx(0), + _brushDy(0), + _alreadyExposed(false), + _invalidRegion(), + _clipBox(), + _clipX(), + _clipY(), + _painter(NULL), + _backgroundColor(20, 20, 20), + _foregroundColor(255, 255, 255), + _doubleBuffering(false), + _automaticScrolling(false), + _visibleLayerMask(~0), + //_commandMap(), + //_startedCommand(NULL), + _gridOrigin(), + _gridXStep(getUnit(1)), + _gridYStep(getUnit(1)), + _gridIsVisible(true), + _gridAxesAreVisible(false), + _gridDisplayThreshold(8), + _gridColor(QColor(155, 155, 155)), + _snapGrid(true), + _drawSnapPoint(false), + _snapPoint(), + _displayDepth(1), + _displaySize(2), + //_selectorSet(), + _selectionLimit(100000), + _selectionColor(255, 255, 255), + _selectionIsVisible(true), + //_highlightorSet(), + _highlightionLimit(10000), + _highlightionIsVisible(true), + //_trackBox(NULL), + _peekList(), + _basicLayersBrush(), + _basicLayersPen() +{ + setFocusPolicy(Qt::StrongFocus); // to accepts focus by tabbing and clicking + setMouseTracking(true); // to have move events even a mouse button isn't pressed + + DataBase* database = getDataBase(); + if (database) { + Technology* technology = database->getTechnology(); + if (technology) { + for_each_basic_layer(basiclayer, technology->getBasicLayers()) { + _basicLayersBrush[basiclayer] = + ::getBrush(basiclayer->getFillPattern(), + basiclayer->getRedValue(), + basiclayer->getGreenValue(), + basiclayer->getBlueValue()); + _basicLayersPen[basiclayer] = + QPen(QColor(basiclayer->getRedValue(), basiclayer->getGreenValue(), basiclayer->getBlueValue())); + end_for; + } + } + } +} + + + +// ************************************************************************************************* +// CellWidget::~CellWidget() +// ************************************************************************************************* + +CellWidget::~CellWidget() +{ + clearPeeks(); + //clearHighlightion(); + //clearSelection(); + + //forEachCommand(command, getCommands()) { + // command->uninstallFrom(this); + // endFor; + //} + + //if (_trackBox) { + // _trackBox->_setCellWidget(NULL); + //} +} + + + +// ************************************************************************************************* +// CellWidget::getLabel() +// CellWidget::getRecord() +// CellWidget::getSlot() +// ************************************************************************************************* + +//Label +//CellWidget::getLabel() const +//{ +// Label label = Label::create(getTypeName(*this)); +// +// View* view = getView(); +// if (view) { +// label.add(" ", view); +// } +// +// return label; +//} +// +//Record* +//CellWidget::getRecord() const +//{ +// Record* record = new Record(this); +// +// if (record) { +// record->addHeader("Widget"); +// +// record->addHeader("CellWidget"); +// +// record->addSlot("View", getView()); +// record->addSlot("Center", getCenter()); +// record->addSlot("Scale", getScale()); +// record->addSlot("BackgroundColor", My::getLabel(getBackgroundColor())); +// record->addSlot("ForegroundColor", My::getLabel(getForegroundColor())); +// record->addSlot("DoubleBuffering", doubleBuffering()); +// record->addSlot("AutomaticScrolling", automaticScrolling()); +// record->addSlot("VisibleLayers", getVisibleLayers()); +// record->addSlot("Commands", getCommands()); +// record->addSlot("GridOrigin", getGridOrigin()); +// record->addSlot("GridXStep", getValueString(getGridXStep())); +// record->addSlot("GridYStep", getValueString(getGridYStep())); +// record->addSlot("GridDisplayThreshold", getGridDisplayThreshold()); +// record->addSlot("GridIsVisible", gridIsVisible()); +// record->addSlot("GridAxesAreVisible", gridAxesAreVisible()); +// record->addSlot("GridIsDrawable", gridIsDrawable()); +// record->addSlot("GridColor", My::getLabel(getGridColor())); +// record->addSlot("SnapGrid", snapGrid()); +// record->addSlot("DisplayDepth", getDisplayDepth()); +// record->addSlot("DisplaySize", getDisplaySize()); +// record->addSlot("SelectionIsVisible", selectionIsVisible()); +// record->addSlot("Selection", getSelection()); +// record->addSlot("SelectionBox", getSelectionBox()); +// unsigned limit = getSelectionLimit(); +// if (limit) { +// record->addSlot("SelectionLimit", limit); +// } +// else { +// record->addSlot("SelectionLimit", "NONE"); +// } +// record->addSlot("SelectionColor", My::getLabel(getSelectionColor())); +// record->addSlot("HighlightionIsVisible", highlightionIsVisible()); +// record->addSlot("Highlightion", getHighlightion()); +// record->addSlot("HighlightionBox", getHighlightionBox()); +// record->addSlot("TrackBox", getTrackBox()); +// } +// +// return record; +//} +// +//Slot* +//CellWidget::getSlot(const string& name) const +//{ +// return new StandardSlot(name, this); +//} +// + + +// ************************************************************************************************* +// CellWidget::getCenter() +// CellWidget::getScale() +// ************************************************************************************************* + +const Point& +CellWidget::getCenter() const +{ + return _center; +} + +double +CellWidget::getScale() const +{ + return _scale; +} + + + +// ************************************************************************************************* +// CellWidget::getX() +// CellWidget::getY() +// CellWidget::getSize() +// CellWidget::getPoint() +// CellWidget::getBox() +// ************************************************************************************************* + +Unit +CellWidget::getX(int screenX) const +{ + return getUnit((screenX - _screenDx) / _scale); +} + +Unit +CellWidget::getY(int screenY) const +{ + return getUnit(((height() - screenY) - _screenDy) / _scale); +} + +Unit +CellWidget::getSize(int screenSize) const +{ + return getUnit(screenSize / _scale); +} + +Point +CellWidget::getPoint(const QPoint& screenPoint) const +{ + return Point(getX(screenPoint.x()), getY(screenPoint.y())); +} + +Box +CellWidget::getBox(const QRect& screenRect) const +{ + if (screenRect.isEmpty()) { + return Box(); + } + + return Box(getX(screenRect.left()), + getY(screenRect.bottom()), + getX(screenRect.right()), + getY(screenRect.top())); +} + + + +// ************************************************************************************************* +// CellWidget::getScreenX() +// CellWidget::getScreenY() +// CellWidget::getScreenSize() +// CellWidget::getScreenPoint() +// CellWidget::getScreenBox() +// ************************************************************************************************* + +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)); +} + +int +CellWidget::getScreenSize(const Unit& size) const +{ + return (int)rint(getValue(size) * _scale); +} + +QPoint +CellWidget::getScreenPoint(const Point& point) const +{ + return QPoint(getScreenX(point.getX()), getScreenY(point.getY())); +} + +QRect +CellWidget::getScreenRect(const Box& box) const +{ + if (box.isEmpty()) { + return QRect(); + } + + int screenX1 = getScreenX(box.getXMin()); + int screenY1 = getScreenY(box.getYMin()); + int screenX2 = getScreenX(box.getXMax()); + int screenY2 = getScreenY(box.getYMax()); + + return QRect(QPoint(min(screenX1, screenX2), min(screenY1, screenY2)), + QPoint(max(screenX1, screenX2), max(screenY1, screenY2))); +} + + + +// ************************************************************************************************* +// CellWidget::getSnapPoint() +// ************************************************************************************************* + +Point +CellWidget::getSnapPoint(const Point& point) const +{ + return (_snapGrid) ? getGridPoint(point) : point; +} + +Point +CellWidget::getSnapPoint(int screenX, + int screenY) const +{ + return getSnapPoint(Point(getX(screenX), getY(screenY))); +} + + + +// ************************************************************************************************* +// CellWidget::getVisibleLayers() +// ************************************************************************************************* + +BasicLayers +CellWidget::getVisibleLayers() const +{ + DataBase* database = getDataBase(); + if (database) { + Technology* technology = database->getTechnology(); + if (technology) { + return technology->getBasicLayers(_visibleLayerMask); + } + } + return NULL; +} + + + +// ************************************************************************************************* +// CellWidget::getCommand() +// CellWidget::getCommands() +// ************************************************************************************************* + +//Command* +//CellWidget::getCommand(int button) const +//{ +// CommandMap::const_iterator i = _commandMap.find(button); +// +// return (i != _commandMap.end()) ? (*i).second : NULL; +//} +// +//Commands +//CellWidget::getCommands() const +//{ +// return _commandMap; +//} +// + + +// ************************************************************************************************* +// CellWidget::getGridX() +// CellWidget::getGridY() +// CellWidget::getGridPoint() +// ************************************************************************************************* + +Unit +CellWidget::getGridX(const Unit& x, + int sign) const +{ + if (!((-1 <= sign) && (sign <= 1))) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + Unit cx = x; + Unit xo = _gridOrigin.getX(); + + if (cx != xo) { + cx -= xo; + switch (sign) { + case -1 : { + if (0 < cx) { + return ((cx / _gridXStep) * _gridXStep) + xo; + } + else { + if (cx < 0) { + return (((cx / _gridXStep) - 1) * _gridXStep) + xo; + } + } + return cx + xo; + } + case 0 : { + Unit x1 = (cx / _gridXStep) * _gridXStep; + Unit x2 = ((x1 < cx) ? (x1 + _gridXStep) : (x1 - _gridXStep)); + return ((labs(x1 - cx) <= labs(x2 - cx)) ? x1 : x2) + xo; + } + case 1 : { + if (0 < cx) { + return (((cx / _gridXStep) + 1) * _gridXStep) + xo; + } + else { + if (cx < 0) { + return ((cx / _gridXStep) * _gridXStep) + xo; + } + } + return cx + xo; + } + } + } + + return cx; +} + +Unit +CellWidget::getGridY(const Unit& y, + int sign) const +{ + if (!((-1 <= sign) && (sign <= 1))) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + Unit cy = y; + Unit yo = _gridOrigin.getY(); + + if (cy != yo) { + cy -= yo; + switch (sign) { + case -1 : { + if (0 < cy) { + return ((cy / _gridYStep) * _gridYStep) + yo; + } + else { + if (cy < 0) { + return (((cy / _gridYStep) - 1) * _gridYStep) + yo; + } + } + return cy + yo; + } + case 0 : { + Unit y1 = (cy / _gridYStep) * _gridYStep; + Unit y2 = ((y1 < cy) ? (y1 + _gridYStep) : (y1 - _gridYStep)); + return ((labs(y1 - cy) <= labs(y2 - cy)) ? y1 : y2) + yo; + } + case 1 : { + if (0 < cy) { + return (((cy / _gridYStep) + 1) * _gridYStep) + yo; + } + else { + if (cy < 0) { + return ((cy / _gridYStep) * _gridYStep) + yo; + } + } + return cy + yo; + } + } + } + + return cy; +} + +Point +CellWidget::getGridPoint(const Point& point, + int xSign, + int ySign) const +{ + return Point(getGridX(point.getX(), xSign), getGridY(point.getY(), ySign)); +} + + + +// ************************************************************************************************* +// CellWidget::getWorld() +// ************************************************************************************************* + +//Box +//CellWidget::getWorld() const +//{ +// Box world = Box(getX(0), getY(0), getX(width()), getY(height())); +// +// View* view = getView(); +// +// if (view) { +// world.merge(view->getBoundingBox()); +// } +// +// return world; +//} + + + +// ************************************************************************************************* +// CellWidget::getSelectors() +// CellWidget::getSelection() +// CellWidget::getSelectionBox() +// CellWidget::getHighlightors() +// CellWidget::getHighlightion() +// CellWidget::getHighlightionBox() +// ************************************************************************************************* + +//Selectors +//CellWidget::getSelectors() const +//{ +// return _selectorSet; +//} + +//Occurrences +//CellWidget::getSelection() const +//{ +// return getSelectors().getAssociates(getOccurrence()); +//} + +//Box +//CellWidget::getSelectionBox() const +//{ +// Box selectionBox; +// +// forEachOccurrence(occurrence, getSelection()) { +// selectionBox.merge(occurrence.getBoundingBox()); +// endFor; +// } +// +// return selectionBox; +//} +// +//Highlightors +//CellWidget::getHighlightors() const +//{ +// return _highlightorSet; +//} +// +//Occurrences +//CellWidget::getHighlightion() const +//{ +// return getHighlightors().getAssociates(getOccurrence()); +//} +// +//Box +//CellWidget::getHighlightionBox() const +//{ +// Box highlightionBox; +// +// forEachOccurrence(occurrence, getHighlightion()) { +// highlightionBox.merge(occurrence.getBoundingBox()); +// endFor; +// } +// +// return highlightionBox; +//} +// + + +// ************************************************************************************************* +// CellWidget::getFont() +// CellWidget::getPen() +// CellWidget::getBrush() +// CellWidget::getBrushOrigin() +// ************************************************************************************************* + +const QFont& +CellWidget::getFont() +{ + return (_painter) ? _painter->font() : QPainter(this).font(); +} + +const QPen& +CellWidget::getPen() +{ + return (_painter) ? _painter->pen() : QPainter(this).pen(); +} + + +const QPen& +CellWidget::getPen(const BasicLayer* basiclayer) { + map::const_iterator pmit = _basicLayersPen.find(basiclayer); + if (pmit != _basicLayersPen.end()) { + return pmit->second; + } + return defaultPen; +} + +const QBrush& +CellWidget::getBrush() +{ + return (_painter) ? _painter->brush() : QPainter(this).brush(); +} + +const QBrush& +CellWidget::getBrush(BasicLayer* basiclayer) { + map::const_iterator bmit = _basicLayersBrush.find(basiclayer); + if (bmit != _basicLayersBrush.end()) { + return bmit->second; + } + return defaultBrush; +} + +const QPoint +CellWidget::getBrushOrigin() +{ + return (_painter) ? _painter->brushOrigin() : QPainter(this).brushOrigin(); +} + + + +// ************************************************************************************************* +// CellWidget::hasRecord() +// ************************************************************************************************* + +bool +CellWidget::hasRecord() const +{ + return true; +} + + + +// ************************************************************************************************* +// CellWidget::setTrackBox() +// ************************************************************************************************* + +//void +//CellWidget::setTrackBox(TrackBox* trackBox) +//{ +// if (trackBox != _trackBox) { +// if (_trackBox) { +// _trackBox->_setCellWidget(NULL); +// } +// _trackBox = trackBox; +// if (_trackBox) { +// _trackBox->_setCellWidget(this); +// } +// } +//} +// + + +// ************************************************************************************************* +// CellWidget::allowAutomaticScrolling() +// ************************************************************************************************* + +bool +CellWidget::allowAutomaticScrolling() const +{ + return true; +} + + + +// ************************************************************************************************* +// CellWidget::isVisible() +// CellWidget::isDrawable() +// ************************************************************************************************* + +bool +CellWidget::isVisible(BasicLayer* layer) const +{ + if (!layer) { + //throw Error(NULL_LAYER, __FILE__, __LINE__); + } + + return (_visibleLayerMask & layer->getMask()); +} + +bool +CellWidget::isDrawable(BasicLayer* layer) const +{ + if (!layer) { + //throw Error(NULL_LAYER, __FILE__, __LINE__); + } + + return (layer->getDisplayThreshold() <= _scale); +} + + + +// ************************************************************************************************* +// CellWidget::isOnGridX() +// CellWidget::isOnGridY() +// CellWidget::isOnGridPoint() +// ************************************************************************************************* + +bool +CellWidget::isOnGridX(const Unit& x, + unsigned n) const +{ + if (!n) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + Unit delta = labs(x - _gridOrigin.getX()); + + if (delta < 0) { + delta = -delta; + } + + Unit step = _gridXStep * n; + + return (delta == ((delta / step) * step)); +} + +bool +CellWidget::isOnGridY(const Unit& y, + unsigned n) const +{ + if (!n) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + Unit delta = labs(y - _gridOrigin.getY()); + + if (delta < 0) { + delta = -delta; + } + + Unit step = _gridYStep * n; + + return (delta == ((delta / step) * step)); +} + +bool +CellWidget::isOnGridPoint(const Point& point, + unsigned xN, + unsigned yN) const +{ + return isOnGridX(point.getX(), xN) && isOnGridY(point.getX(), yN); +} + + + +// ************************************************************************************************* +// CellWidget::isSelected() +// CellWidget::isSelectable() +// CellWidget::isHighlighted() +// CellWidget::isHighlightable() +// ************************************************************************************************* + +//bool +//CellWidget::isSelected(const Occurrence& occurrence) const +//{ +// Selector* selector = +// dynamic_cast(occurrence.getProperty(Selector::getPropertyName())); +// +// return (selector) ? selector->_contains((CellWidget*)this) : false; +//} +// +//bool +//CellWidget::isSelectable(const Occurrence& occurrence) const +//{ +// return occurrence.isSelectable() && (occurrence.getView() == getView()); +//} +// +//bool +//CellWidget::isHighlighted(const Occurrence& occurrence) const +//{ +// Highlightor* highlightor = +// dynamic_cast(occurrence.getProperty(Highlightor::getPropertyName())); +// +// return (highlightor) ? highlightor->_contains((CellWidget*)this) : false; +//} +// +//bool +//CellWidget::isHighlightable(const Occurrence& occurrence) const +//{ +// return occurrence.isHighlightable() && (occurrence.getView() == getView()); +//} + + + +// ************************************************************************************************* +// CellWidget::setBackgroundColor() +// CellWidget::setForegroundColor() +// ************************************************************************************************* + +void +CellWidget::setBackgroundColor(const QColor& color) +{ + if (color != _backgroundColor) { + _backgroundColor = color; + invalidate(); + } +} + +void +CellWidget::setForegroundColor(const QColor& color) +{ + if (color != _foregroundColor) { + _foregroundColor = color; + invalidate(); + } +} + + + +// ************************************************************************************************* +// CellWidget::setVisible() +// ************************************************************************************************* + +void +CellWidget::setVisible(BasicLayer* layer, + bool visible) +{ + if (isVisible(layer) != visible) { + if (visible) { + _visibleLayerMask |= layer->getMask(); + } + else { + _visibleLayerMask &= ~layer->getMask(); + } + + onSetVisible(layer, visible); + + Cell* cell = getCell(); + + //if (view && !view->getSlices(layer).isEmpty() && isDrawable(layer)) { + // invalidate(); + //} + + if (cell && !cell->getSlices(layer->getMask()).IsEmpty() && isDrawable(layer)) { + invalidate(); + } + } +} + + + +// ************************************************************************************************* +// CellWidget::setGridOrigin() +// CellWidget::setGridXStep() +// CellWidget::setGridYStep() +// CellWidget::setGridStep() +// CellWidget::setGridSteps() +// CellWidget::setGridDisplayThreshold() +// CellWidget::setGridColor() +// ************************************************************************************************* + +void +CellWidget::setGridOrigin(const Point& origin) +{ + if (origin != _gridOrigin) { + bool gridIsDrawn = gridIsVisible() && gridIsDrawable(); + + _gridOrigin = origin; + + if (gridIsDrawn || (gridIsVisible() && gridIsDrawable())) { + invalidate(); + } + } +} + +void +CellWidget::setGridXStep(const Unit& step) +{ + if (!step) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + if (step != _gridXStep) { + bool gridIsDrawn = gridIsVisible() && gridIsDrawable(); + + _gridXStep = step; + + if (gridIsDrawn || (gridIsVisible() && gridIsDrawable())) { + invalidate(); + } + } +} + +void +CellWidget::setGridYStep(const Unit& step) +{ + if (!step) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + if (step != _gridYStep) { + bool gridIsDrawn = gridIsVisible() && gridIsDrawable(); + + _gridYStep = step; + + if (gridIsDrawn || (gridIsVisible() && gridIsDrawable())) { + invalidate(); + } + } +} + +void +CellWidget::setGridStep(const Unit& step) +{ + if (!step) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + if ((step != _gridXStep) || (step != _gridYStep)) { + bool gridIsDrawn = gridIsVisible() && gridIsDrawable(); + + _gridXStep = step; + _gridYStep = step; + + if (gridIsDrawn || (gridIsVisible() && gridIsDrawable())) { + invalidate(); + } + } +} + +void +CellWidget::setGridSteps(const Unit& xStep, + const Unit& yStep) +{ + if (!xStep || !yStep) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + if ((xStep != _gridXStep) || (yStep != _gridYStep)) { + bool gridIsDrawn = gridIsVisible() && gridIsDrawable(); + + _gridXStep = xStep; + _gridYStep = yStep; + + if (gridIsDrawn || (gridIsVisible() && gridIsDrawable())) { + invalidate(); + } + } +} + +void +CellWidget::setGridDisplayThreshold(unsigned threshold) +{ + if (threshold < 3) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + _gridDisplayThreshold = threshold; + + invalidate(); +} + +void +CellWidget::setGridColor(const QColor& color) +{ + if (_gridColor != color) { + _gridColor = color; + if (gridIsVisible() && gridIsDrawable()) { + invalidate(); + } + } +} + + + +// ************************************************************************************************* +// CellWidget::setGridVisible() +// CellWidget::setGridAxesVisible() +// CellWidget::setSnapGrid() +// ************************************************************************************************* + +void +CellWidget::setGridVisible(bool visible) +{ + if (_gridIsVisible != visible) { + _gridIsVisible = visible; + if (gridIsDrawable()) { + invalidate(); + } + } +} + +void +CellWidget::setGridAxesVisible(bool visible) +{ + if (_gridAxesAreVisible != visible) { + _gridAxesAreVisible = visible; + if (gridIsDrawable()) { + invalidate(); + } + } +} + +void +CellWidget::setSnapGrid(bool enable) +{ + if (_snapGrid != enable) { + if (_snapGrid && _drawSnapPoint) { + drawSnapPoint(); + _drawSnapPoint = false; + } + _snapGrid = enable; + if (_snapGrid && !_drawSnapPoint) { + _drawSnapPoint = true; + drawSnapPoint(); + } + } +} + + + +// ************************************************************************************************* +// CellWidget::setDisplayDepth() +// CellWidget::setDisplayDepth() +// ************************************************************************************************* + +void +CellWidget::setDisplayDepth(unsigned displayDepth) +{ + if (displayDepth != _displayDepth) { + _displayDepth = displayDepth; + invalidate(); + } +} + +void +CellWidget::setDisplaySize(unsigned displaySize) +{ + if (displaySize != _displaySize) { + _displaySize = displaySize; + } +} + + + +// ************************************************************************************************* +// CellWidget::setFont() +// CellWidget::setPen() +// CellWidget::setBrush() +// CellWidget::setBrushOrigin() +// ************************************************************************************************* + +void +CellWidget::setFont(const QFont& font) +{ + if (_painter) { + _painter->setFont(font); + } +} + +void +CellWidget::setPen(const QPen& pen, + double brightness) +{ + if (!((0.1 <= brightness) && (brightness <= 1.0))) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + if (_painter) { + if (pen == Qt::NoPen) { + _painter->setPen(pen); + } + else { + QPen correctedPen = pen; + + if (brightness < 1) { + QColor bgColor = getBackgroundColor(); + int r = bgColor.red(); + int g = bgColor.green(); + int b = bgColor.blue(); + + QColor color = pen.color(); + r = r + (int)((color.red() - r) * brightness); + g = g + (int)((color.green() - g) * brightness); + b = b + (int)((color.blue() - b) * brightness); + + correctedPen = QPen(QColor(r, g, b)); + } + + _painter->setPen(correctedPen); + } + } +} + +void +CellWidget::setBrush(const QBrush& brush, + double brightness) +{ + if (!((0.1 <= brightness) && (brightness <= 1.0))) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + if (_painter) { + if (brush == Qt::NoBrush) { + _painter->setBrush(brush); + } + else { + QBrush correctedBrush = brush; + + if (brightness < 1) { + QColor bgColor = getBackgroundColor(); + int r = bgColor.red(); + int g = bgColor.green(); + int b = bgColor.blue(); + + QColor color = brush.color(); + r = r + (int)((color.red() - r) * brightness); + g = g + (int)((color.green() - g) * brightness); + b = b + (int)((color.blue() - b) * brightness); + + correctedBrush = QBrush(QColor(r, g, b), brush.style()); + } + + _painter->setBrush(correctedBrush); + } + } +} + +void +CellWidget::setBrushOrigin(const QPoint& origin) +{ + if (_painter) { + _painter->setBrushOrigin(_brushDx + origin.x(), _brushDy + origin.y()); + } +} + + + +// ************************************************************************************************* +// CellWidget::setSelectionColor() +// CellWidget::setSelectionVisible() +// CellWidget::setHighlightionVisible() +// ************************************************************************************************* + +//void +//CellWidget::setSelectionColor(const QColor& color) +//{ +// if (color != _selectionColor) { +// _selectionColor = color; +// if (selectionIsVisible()) { +// invalidate(getSelectionBox()); +// } +// } +//} +// +//void +//CellWidget::setSelectionVisible(bool visible) +//{ +// if (_selectionIsVisible != visible) { +// _selectionIsVisible = visible; +// invalidate(getSelectionBox()); +// } +//} +// +//void +//CellWidget::setHighlightionVisible(bool visible) +//{ +// if (_highlightionIsVisible != visible) { +// _highlightionIsVisible = visible; +// invalidate(getHighlightionBox()); +// } +//} +// + + +// ************************************************************************************************* +// CellWidget::setAutomaticScrolling() +// ************************************************************************************************* + +void +CellWidget::setAutomaticScrolling(bool enable) +{ + if (!allowAutomaticScrolling()) { + //throw Error(INVALID_REQUEST, __FILE__, __LINE__); + } + + _automaticScrolling = enable; +} + + + +// ************************************************************************************************* +// CellWidget::showAllLayers() +// CellWidget::hideAllLayers() +// ************************************************************************************************* + +void +CellWidget::showAllLayers() +{ + DataBase* database = getDataBase(); + if (database) { + Technology* technology = database->getTechnology(); + if (technology) { + for_each_basic_layer(layer, technology->getBasicLayers()) { + setVisible(layer, true); + end_for; + } + } + } +} + +void +CellWidget::hideAllLayers() +{ + DataBase* database = getDataBase(); + if (database) { + Technology* technology = database->getTechnology(); + if (technology) { + for_each_basic_layer(layer, technology->getBasicLayers()) { + setVisible(layer, false); + end_for; + } + } + } +} + + + +// ************************************************************************************************* +// CellWidget::select() +// CellWidget::unselect() +// CellWidget::clearSelection() +// ************************************************************************************************* + +//bool +//CellWidget::select(const Occurrence& occurrence) +//{ +// if (!isSelectable(occurrence)) { +// throw Error(INVALID_REQUEST, __FILE__, __LINE__); +// } +// +// if (_selectionLimit && (_selectionLimit <= getSelectors().getCount())) { +// return false; +// } +// +// Property* property = occurrence.getProperty(Selector::getPropertyName()); +// +// Selector* selector = NULL; +// +// if (!property) { +// selector = new Selector(occurrence); +// } +// else { +// if (!dynamic_cast(property)) { +// throw Error(BAD_PROPERTY_TYPE, __FILE__, __LINE__); +// } +// selector = (Selector*)property; +// } +// +// selector->_attachTo(this); +// +// invalidate(occurrence.getBoundingBox()); +// +// return true; +//} + +//void +//CellWidget::unselect(const Occurrence& occurrence) +//{ +// if (!isSelectable(occurrence)) { +// throw Error(INVALID_REQUEST, __FILE__, __LINE__); +// } +// +// Property* property = occurrence.getProperty(Selector::getPropertyName()); +// +// if (property) { +// if (!dynamic_cast(property)) { +// throw Error(BAD_PROPERTY_TYPE, __FILE__, __LINE__); +// } +// +// ((Selector*)property)->_detachFrom(this); +// +// invalidate(occurrence.getBoundingBox()); +// } +//} +// +//void +//CellWidget::clearSelection() +//{ +// Occurrences selection = getSelection(); +// +// bool _cumulativeMode = false; // HOOPS !!! +// if (_cumulativeMode) { +// invalidate(getSelectionBox()); +// } +// +// while (!selection.isEmpty()) { +// unselect(selection.getFirst()); +// } +//} +// +// +// +//// ************************************************************************************************* +//// CellWidget::highlight() +//// CellWidget::unhighlight() +//// CellWidget::clearHighlightion() +//// ************************************************************************************************* +// +//bool +//CellWidget::highlight(const Occurrence& occurrence) +//{ +// if (!isHighlightable(occurrence)) { +// throw Error(INVALID_REQUEST, __FILE__, __LINE__); +// } +// +// unsigned count = getHighlightors().getCount(); +// +// if (_highlightionLimit && (_highlightionLimit <= count)) { +// return false; +// } +// +// Property* property = occurrence.getProperty(Highlightor::getPropertyName()); +// +// Highlightor* highlightor = NULL; +// +// if (!property) { +// highlightor = new Highlightor(occurrence); +// } +// else { +// if (!dynamic_cast(property)) { +// throw Error(BAD_PROPERTY_TYPE, __FILE__, __LINE__); +// } +// highlightor = (Highlightor*)property; +// } +// +// highlightor->_attachTo(this); +// +// if (!count) { +// invalidate(); +// } +// else { +// invalidate(occurrence.getBoundingBox()); +// } +// +// return true; +//} +// +//void +//CellWidget::unhighlight(const Occurrence& occurrence) +//{ +// if (!isHighlightable(occurrence)) { +// throw Error(INVALID_REQUEST, __FILE__, __LINE__); +// } +// +// Property* property = occurrence.getProperty(Highlightor::getPropertyName()); +// +// if (property) { +// if (!dynamic_cast(property)) { +// throw Error(BAD_PROPERTY_TYPE, __FILE__, __LINE__); +// } +// +// ((Highlightor*)property)->_detachFrom(this); +// +// if (getHighlightors().isEmpty()) { +// invalidate(); +// } +// else { +// invalidate(occurrence.getBoundingBox()); +// } +// } +//} +// +//void +//CellWidget::clearHighlightion() +//{ +// Occurrences highlightion = getHighlightion(); +// +// bool _cumulativeMode = false; // HOOPS !!! +// if (_cumulativeMode) { +// invalidate(getHighlightionBox()); +// } +// +// while (!highlightion.isEmpty()) { +// unhighlight(highlightion.getFirst()); +// } +//} +// +// + +// ************************************************************************************************* +// CellWidget::clearPeeks() +// CellWidget::addPeek() +// ************************************************************************************************* + +void +CellWidget::clearPeeks() +{ + for (list::iterator plit = _peekList.begin(); + plit != _peekList.end(); + ++plit) { + invalidate(*plit); + } +// for_each_box(peek, getCollection(_peekList)) { +// invalidate(peek); +// end_for; +// } +// + _peekList.clear(); +} + +void +CellWidget::addPeek(const Box& peek) +{ + if (!peek.isEmpty()) { + invalidate(peek); + _peekList.push_back(peek); + } +} + + + +// ************************************************************************************************* +// CellWidget::invalidate() +// ************************************************************************************************* + +void +CellWidget::invalidate() +{ + _invalidRegion = QRegion(rect()); +} + +void +CellWidget::invalidate(const QRect& screenRect) +{ + QRect visibleScreenRect = screenRect.intersect(rect()); + + if (!visibleScreenRect.isEmpty()) { + bool _cumulativeMode = false; // HOOPS !!! + if (!_cumulativeMode) { + _invalidRegion = _invalidRegion.unite(QRegion(visibleScreenRect)); + } + else { + _invalidRegion = QRegion(_invalidRegion.boundingRect().unite(visibleScreenRect)); + } + } +} + +void +CellWidget::invalidate(const Box& box) +{ + if (!box.isEmpty()) { + int safetyMargin = 2; // 2 pixel + invalidate(getScreenRect(box.getInflated(getSize(safetyMargin)))); + } +} + +void +CellWidget::fitToContent(unsigned screenMargin) { + Box area(getX(0), getY(0), getX(width()), getY(height())); + if (_cell) { + area = _cell->getBoundingBox(); + } + + reframe(area); + area.inflate(screenMargin); + reframe(area); +} + + + + +// ************************************************************************************************* +// CellWidget::reframe() +// ************************************************************************************************* + +void +CellWidget::reframe() +{ + reframe(_center, _scale); +} + +void +CellWidget::reframe(double scale) +{ + reframe(_center, scale); +} + +void +CellWidget::reframe(const Point& center) +{ + reframe(center, _scale); +} + +void +CellWidget::reframe(const Point& center, + double scale) +{ + if (0 < scale) { + _center = center; + _scale = scale; + _screenDx = -(int)rint((getValue(_center.getX()) - (width() / (_scale*2))) * _scale); + _screenDy = -(int)rint((getValue(_center.getY()) - (height() / (_scale*2))) * _scale); + _brushDx = 0; + _brushDy = 0; + invalidate(); + } +} + +void +CellWidget::reframe(const Box& box) +{ + if (!box.isEmpty()) { + Point center = box.getCenter(); + + double scale = min((double)width() / getValue(box.getWidth()), + (double)height() / getValue(box.getHeight())); + + reframe(center, scale); + } +} + + + +// ************************************************************************************************* +// CellWidget::scroll() +// ************************************************************************************************* + +void +CellWidget::scroll(const Unit& dx, + const Unit& dy) +{ + if ((getSize(width()) < labs(dx)) || (getSize(height()) < labs(dy))) { + reframe(getCenter().getTranslated(-dx, -dy)); + redraw(); + } else { + int sdx = getScreenSize(dx); + int sdy = getScreenSize(dy); + + if (sdx || sdy) { + QCursor oldCursor = cursor(); + setCursor(Qt::WaitCursor); + + if (_snapGrid) { + drawSnapPoint(); + } + + //forEachCommand(command, getCommands()) { + // _callDrawOf(command); + // endFor; + //} + + _screenDx += sdx; + _screenDy += sdy; + + _brushDx += sdx; + _brushDy -= sdy; + + _center = getPoint(QPoint(width() / 2, height() / 2)); + + int w = width(); + int h = height(); + + if (0 < sdx) { + if (0 < sdy) { + //bitBlt(this, sdx, 0, this, 0, sdy, w - sdx, h - sdy); + invalidate(QRect(-1, -1, sdx + 1, h + 1)); + //_redraw(); + invalidate(QRect(sdx - 1, h - sdy - 1, w + 1, h + 1)); + //_redraw(); + update(); + } else { + //bitBlt(this, sdx, -sdy, this, 0, 0, w - sdx, h + sdy, CopyROP); + invalidate(QRect(-1, -1, sdx + 1, h + 1)); + //_redraw(); + invalidate(QRect(sdx - 1, -1, w + 1, -sdy + 1)); + //_redraw(); + update(); + } + } + else { + if (0 < sdy) { + //bitBlt(this, 0, 0, this, -sdx, sdy, w + sdx, h - sdy, CopyROP); + invalidate(QRect(w + sdx - 1, -1, w + 1, h + 1)); + // _redraw(); + invalidate(QRect(-1, h - sdy - 1, w + sdx + 1, h + 1)); + //_redraw(); + update(); + } + else { + //bitBlt(this, 0, -sdy, this, -sdx, 0, w + sdx, h + sdy); + invalidate(QRect(w + sdx - 1, -1, w + 1, h + 1)); + //_redraw(); + invalidate(QRect(-1, -1, w + sdx + 1, -sdy + 1)); + //_redraw(); + update(); + } + } + + //forEachCommand(command, reverse(getCommands())) { + // _callDrawOf(command); + // endFor; + //} + + if (_snapGrid) { + drawSnapPoint(); + } + + setCursor(oldCursor); + } + } +} + + + +// ************************************************************************************************* +// CellWidget::redraw() +// ************************************************************************************************* + +void +CellWidget::redraw() +{ + if (!_invalidRegion.isEmpty()) { + QCursor oldCursor = cursor(); + setCursor(Qt::WaitCursor); + + if (_snapGrid) { + drawSnapPoint(); + } + + //forEachCommand(command, getCommands()) { + // _callDrawOf(command); + // endFor; + //} + + if (!_alreadyExposed) { + fitToContent(); + _alreadyExposed = true; + } + + _redraw(); + + //forEachCommand(command, reverse(getCommands())) { + // _callDrawOf(command); + // endFor; + //} + + if (_snapGrid) { + drawSnapPoint(); + } + + setCursor(oldCursor); + + _invalidRegion = QRegion(); + } +} + + + +// ************************************************************************************************* +// CellWidget::abortStartedCommand() +// ************************************************************************************************* + +//void +//CellWidget::abortStartedCommand() +//{ +// if (_startedCommand) { +// _startedCommand->abortOn(this); +// } +// +// if (_trackBox) { +// _trackBox->stop(_snapPoint); +// } +//} + + + +// ************************************************************************************************* +// CellWidget::preRedraw() +// CellWidget::postRedraw() +// ************************************************************************************************* + +void +CellWidget::preRedraw(const Box& area) +{ +} + +void +CellWidget::postRedraw(const Box& area) +{ +} + + +void CellWidget::drawContent(const Cell* cell, const BasicLayer* basicLayer, const Hurricane::Box& updateArea, const Transformation& transformation) const { + for_each_instance(instance, cell->getInstancesUnder(updateArea)) { + drawContent(instance, basicLayer, updateArea, transformation); + end_for; + } + + for_each_slice(slice, cell->getSlices()) { + drawSlice(slice, basicLayer, updateArea, transformation); + end_for; + } +} + + +void CellWidget::drawContent(const Instance* instance, const BasicLayer* basicLayer, const Hurricane::Box& updateArea, const Transformation& transformation) const { + Box masterArea = updateArea; + Transformation masterTransformation = instance->getTransformation(); + instance->getTransformation().getInvert().applyOn(masterArea); + transformation.applyOn(masterTransformation); + drawContent(instance->getMasterCell(), basicLayer, masterArea, masterTransformation); +} + + +void CellWidget::drawSlice(const Slice* slice, const BasicLayer* basicLayer, const Hurricane::Box& updateArea, const Transformation& transformation) const { + if (slice->getLayer()->contains(basicLayer)) { + if (slice->getBoundingBox().intersect(updateArea)) { + //if ((basicLayer == _layer->_getSymbolicBasicLayer()) || (3 < view->getScale())) + for_each_go(go, slice->getGosUnder(updateArea)) { + drawGo(go, basicLayer, updateArea, transformation); + end_for; + } + } + } +} + +void CellWidget::drawGo(const Go* go, const BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) const { + const Segment* segment = dynamic_cast(go); + if (segment) { + drawSegment(segment, basicLayer, updateArea, transformation); + return; + } + const Contact* contact = dynamic_cast(go); + if (contact) { + drawContact(contact, basicLayer, updateArea, transformation); + return; + } +} + +void CellWidget::drawSegment(const Segment* segment, const BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) const { + if (1 < getScreenSize(segment->getWidth())) { + drawRectangle(transformation.getBox(segment->getBoundingBox(basicLayer))); + } else { + drawLine(transformation.getPoint(segment->getSourcePosition()), + transformation.getPoint(segment->getTargetPosition())); + } +} + +void CellWidget::drawContact(const Contact* contact, const BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) const { + drawRectangle(transformation.getBox(contact->getBoundingBox(basicLayer))); +} + +void CellWidget::drawPhantoms(const Cell* cell, const Hurricane::Box& updateArea, const Transformation& transformation) const { + for_each_instance(instance, cell->getInstancesUnder(updateArea)) { + drawPhantoms(instance, updateArea, transformation); + end_for; + } +} + +void CellWidget::drawPhantoms(const Instance* instance, const Hurricane::Box& updateArea, const Transformation& transformation) const { + Hurricane::Box masterArea = updateArea; + Transformation masterTransformation = instance->getTransformation(); + instance->getTransformation().getInvert().applyOn(masterArea); + transformation.applyOn(masterTransformation); + drawPhantoms(instance->getMasterCell(), masterArea, masterTransformation); +} + +void CellWidget::drawBoundaries(const Cell* cell, const Hurricane::Box& updateArea, const Transformation& transformation) const { + drawRectangle(transformation.getBox(cell->getAbutmentBox())); + for_each_instance(instance, cell->getInstances()) { + drawBoundaries(instance, updateArea, transformation); + end_for; + } +} + +void CellWidget::drawBoundaries(const Instance* instance, const Hurricane::Box& updateArea, const Transformation& transformation) const { + Hurricane::Box masterArea = updateArea; + Transformation masterTransformation = instance->getTransformation(); + instance->getTransformation().getInvert().applyOn(masterArea); + transformation.applyOn(masterTransformation); + drawBoundaries(instance->getMasterCell(), masterArea, masterTransformation); +} + + + +// ************************************************************************************************* +// CellWidget::drawLine() +// CellWidget::drawPolyline() +// CellWidget::drawRectangle() +// CellWidget::drawPolygon() +// CellWidget::drawText() +// ************************************************************************************************* + +void +CellWidget::drawLine(const Unit& xo, + const Unit& yo, + const Unit& xe, + const Unit& ye) const +{ + if (_painter) { + double dxo = getValue(xo); + double dyo = getValue(yo); + int co = getClipCode(dxo, dyo); + double dxe = getValue(xe); + double dye = getValue(ye); + int ce = getClipCode(dxe, dye); + if (clipLine(dxo, dyo, co, dxe, dye, ce)) { + int ixo = getScreenX(getUnit(dxo)); + int iyo = getScreenY(getUnit(dyo)); + int ixe = getScreenX(getUnit(dxe)); + int iye = getScreenY(getUnit(dye)); + _painter->save(); + if (_painter->pen() == Qt::NoPen) { + _painter->setPen(_painter->brush().color()); + } + _painter->drawLine(ixo, iyo, ixe, iye); + //_painter->moveTo(ixo, iyo); + //_painter->lineTo(ixe, iye); + _painter->restore(); + } + } +} + +//void +//CellWidget::drawPolyline(const Points& points) +//{ +// if (_painter) { +// unsigned sCount; +// +// if (clipLines(points, _sPoints, sCount, false)) { +// _painter->save(); +// if (_painter->pen() == NoPen) { +// _painter->setPen(_painter->brush().color()); +// } +// _painter->drawPolyline(_sPoints, 0, sCount); +// _painter->restore(); +// } +// } +//} + +void +CellWidget::drawRectangle(const Box& box) const +{ + if (_painter) { + 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); + } + } +} + +//void +//CellWidget::drawPolygon(const Points& points) +//{ +// if (_painter) { +// unsigned sCount; +// +// if (clipLines(points, _sPoints, sCount, true)) { +// _painter->drawPolygon(_sPoints, true, 0, sCount); +// } +// } +//} + +//void +//CellWidget::drawText(const Box& frame, +// const string& text, +// const Direction& direction) +//{ +// if (_painter && !frame.isEmpty()) { +// int x = getScreenX(frame.getXMin()); +// int y = getScreenY(frame.getYMax()); +// int w = getScreenX(frame.getXMax()) - x + 1; +// int h = getScreenY(frame.getYMin()) - y + 1; +// switch (direction) { +// case NORTH: { +// int ow = w; +// w = h; +// h = ow; +// int ox = x; +// x = - (y + w); +// y = ox; +// break; +// } +// /* +// case WEST: { +// x = - (x + w); +// y = - (y + h); +// break; +// } +// */ +// case SOUTH: { +// int ow = w; +// w = h; +// h = ow; +// int ox = x; +// x = y; +// y = - (ox + h); +// break; +// } +// } +// QFontMetrics metrics(_painter->font()); +// if ((metrics.width(text) <= w) && (metrics.height() <= h)) { +// _painter->save(); +// switch (direction) { +// case NORTH: _painter->rotate(-90); break; +// /* +// case WEST: _painter->rotate(180); break; +// */ +// case SOUTH: _painter->rotate(90); break; +// } +// if (_painter->pen() == NoPen) { +// _painter->setPen(_painter->brush().color()); +// } +// _painter->drawText(x, y, w, h, Qt::AlignCenter, text); +// _painter->restore(); +// } +// } +//} +// + + +// ************************************************************************************************* +// CellWidget::drawSnapPoint() +// ************************************************************************************************* + +void +CellWidget::drawSnapPoint() +{ + if (_drawSnapPoint) { + int sx = getScreenX(_snapPoint.getX()); + int sy = getScreenY(_snapPoint.getY()); + + if (((-3 <= sx) && (sx <= (width() + 3))) && + ((-3 <= sy) && (sy <= (height() + 3)))) { + QPainter painter(this); + painter.setPen(getForegroundColor()); + painter.setBrush(Qt::NoBrush); + //painter.setRasterOp(Qt::XorROP); + painter.drawRect(sx - 3, sy - 3, 7, 7); + } + } +} + + + +// ************************************************************************************************* +// CellWidget::resizeEvent() +// CellWidget::enterEvent() +// CellWidget::leaveEvent() +// CellWidget::mousePressEvent() +// CellWidget::mouseMoveEvent() +// CellWidget::mouseReleaseEvent() +// CellWidget::focusInEvent() +// CellWidget::focusOutEvent() +// CellWidget::paintEvent() +// ************************************************************************************************* + +void +CellWidget::resizeEvent(QResizeEvent* event) +{ + reframe(); +} + +//void +//CellWidget::enterEvent(QEvent* event) +//{ +// if (getView()) { +// forEachCommand(command, getCommands()) { +// command->onArm(this); +// endFor; +// } +// } +// +// if (_snapGrid) { +// _drawSnapPoint = true; +// drawSnapPoint(); +// } +//} +// +//void +//CellWidget::leaveEvent(QEvent* event) +//{ +// if (_snapGrid) { +// drawSnapPoint(); +// _drawSnapPoint = false; +// } +// +// if (getView()) { +// forEachCommand(command, getCommands()) { +// command->onDisarm(this); +// endFor; +// } +// } +//} + +//void +//CellWidget::mousePressEvent(QMouseEvent* event) +//{ +// if (!_startedCommand) { +// Point position = getSnapPoint(event->x(), event->y()); +// if (getView()) { +// _startedCommand = getCommand(event->button()); +// +// if (_startedCommand) { +// _startedCommand->onStart(this, position, event->state()); +// } +// } +// if (_trackBox) { +// _trackBox->start(position); +// } +// } +//} +// +//void +//CellWidget::mouseMoveEvent(QMouseEvent* event) +//{ +// if (_startedCommand && automaticScrolling() && _startedCommand->automaticScrolling()) { +// int sx = event->x(); +// int sy = event->y(); +// Unit dx = 0; +// if (sx < 0) { +// dx = getUnit(width() / 40); +// } +// else { +// if (width() < sx) { +// dx = - getUnit(width() / 40); +// } +// } +// Unit dy = 0; +// if (sy < 0) { +// dy = - getUnit(height() / 40); +// } +// else { +// if (height() < sy) { +// dy = getUnit(height() / 40); +// } +// } +// if (dx || dy) { +// scroll(dx, dy); +// } +// } +// +// Point position = getSnapPoint(event->x(), event->y()); +// +// if (position != _snapPoint) { +// if (_snapGrid) { +// drawSnapPoint(); +// } +// _snapPoint = position; +// if (_snapGrid) { +// drawSnapPoint(); +// } +// if (getView()) { +// forEachCommand(command, getCommands()) { +// command->onTrack(this, position); +// endFor; +// } +// +// if (_startedCommand) { +// _startedCommand->onUpdate(this, position, event->state()); +// } +// } +// if (_trackBox) { +// _trackBox->update(position); +// } +// } +//} +// +//void +//CellWidget::mouseReleaseEvent(QMouseEvent* event) +//{ +// if (_startedCommand && (_startedCommand->getButton() == event->button())) { +// Point position = getSnapPoint(event->x(), event->y()); +// if (getView()) { +// _startedCommand->onStop(this, position); +// _startedCommand = NULL; +// } +// if (_trackBox) { +// _trackBox->stop(position); +// } +// } +//} +// +//void +//CellWidget::focusInEvent(QFocusEvent* event) +//{ +// // overriden to avoid repaint when the widget gains the focus +//} +// +//void +//CellWidget::focusOutEvent(QFocusEvent* event) +//{ +// // overriden to avoid repaint when the widget loose the focus +//} + +void +CellWidget::paintEvent(QPaintEvent* event) +{ + invalidate(event->rect()); + + redraw(); +} + + + +// ************************************************************************************************* +// CellWidget::onSetVisible() +// ************************************************************************************************* + +void +CellWidget::onSetVisible(Layer* layer, + bool visible) +{ +} + + + +// ************************************************************************************************* +// CellWidget:getClipCode() +// ************************************************************************************************* + +int +CellWidget::getClipCode(double x, + double y) const +{ + if (x < _clipX[0]) { + if (y < _clipY[0]) { + return 28; + } + if (_clipY[3] < y) { + return 22; + } + return 4; + } + + if (_clipX[3] < x) { + if (y < _clipY[0]) { + return 25; + } + if (_clipY[3] < y) { + return 19; + } + return 1; + } + + if (y < _clipY[0]) { + return 8; + } + + if (_clipY[3] < y) { + return 2; + } + + return 0; +} + + + +// ************************************************************************************************* +// CellWidget::clipLine() +// CellWidget::clipLines() +// ************************************************************************************************* + +bool +CellWidget::clipLine(double& xo, + double& yo, + int co, + double& xe, + double& ye, + int ce, + int u) const +{ + if (co & ce & -17) { + return false; + } + + if (!co & !ce) { + return true; + } + + if (co & 1) { + yo += ((ye - yo) / (xe - xo)) * (_clipX[3] - xo); + xo = _clipX[3]; + co = getClipCode(xo, yo); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (co & 2) { + xo += ((xe - xo) / (ye - yo)) * (_clipY[3] - yo); + yo = _clipY[3]; + co = getClipCode(xo, yo); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (co & 4) { + yo += ((ye - yo) / (xe - xo)) * (_clipX[0] - xo); + xo = _clipX[0]; + co = getClipCode(xo, yo); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (co & 8) { + xo += ((xe - xo) / (ye - yo)) * (_clipY[0] - yo); + yo = _clipY[0]; + co = getClipCode(xo, yo); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (ce & 1) { + ye -= ((ye - yo) / (xe - xo)) * (xe - _clipX[3]); + xe = _clipX[3]; + ce = getClipCode(xe, ye); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (ce & 2) { + xe -= ((xe - xo) / (ye - yo)) * (ye - _clipY[3]); + ye = _clipY[3]; + ce = getClipCode(xe, ye); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (ce & 4) { + ye -= ((ye - yo) / (xe - xo)) * (xe - _clipX[0]); + xe = _clipX[0]; + ce = getClipCode(xe, ye); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + if (ce & 8) { + xe -= ((xe - xo) / (ye - yo)) * (ye - _clipY[0]); + ye = _clipY[0]; + ce = getClipCode(xe, ye); + return clipLine(xo, yo, co, xe, ye, ce, u + 1); + } + + return true; +} + +//bool +//CellWidget::clipLines(const Points& points, +// QPointArray& sPoints, +// unsigned& sCount, +// bool closed) const +//{ +// sCount = 0; +// +// if (points.isEmpty()) { +// return false; +// } +// +// int co, ce; +// double xo, yo, xe, ye; +// bool firstPoint = true; +// +// forEachPoint(point, points) { +// xe = getValue(point.getX()); +// ye = getValue(point.getY()); +// ce = getClipCode(xe, ye); +// if (firstPoint) { +// if (!ce) { +// int sx = getScreenX(getUnit(xe)); +// int sy = getScreenY(getUnit(ye)); +// sPoints.putPoints(sCount++, 1, sx, sy); +// } +// firstPoint = false; +// } +// else { +// static int tcc[] = {0,-3,-6,1,3,0,1,0,6,1,0,0,1,0,0,0}; +// static int cra[] = {-1,-1,-1,3,-1,-1,2,-1,-1,1,-1,-1,0,-1,-1,-1}; +// +// double xco = xo; +// double yco = yo; +// double xce = xe; +// double yce = ye; +// if (clipLine(xco, yco, co, xce, yce, ce)) { +// if (co) { +// int sx = getScreenX(getUnit(xco)); +// int sy = getScreenY(getUnit(yco)); +// sPoints.putPoints(sCount++, 1, sx, sy); +// } +// int sx = getScreenX(getUnit(xce)); +// int sy = getScreenY(getUnit(yce)); +// sPoints.putPoints(sCount++, 1, sx, sy); +// } +// else { +// if (ce & 16) { +// if (!(co & ce & ~16)) { +// int c; +// if (!(co & 16)) { +// c = ce + tcc[co]; +// } +// else { +// bool done = false; +// double xto = xo; +// double yto = yo; +// double xte = xe; +// double yte = ye; +// while (!done) { +// double x = (xto + xte) / 2; +// double y = (yto + yte) / 2; +// c = getClipCode(x, y); +// if (!(c & 16)) { +// if (c & ce) { +// c = ce + tcc[co & ~16]; +// } +// else { +// c = co + tcc[ce & ~16]; +// } +// done = true; +// } +// else { +// if (c == ce) { +// xte = x; +// yte = y; +// } +// else { +// if (c != co) { +// done = true; +// } +// else { +// xto = x; +// yto = y; +// } +// } +// } +// } +// } +// int sx = getScreenX(getUnit(_clipX[cra[c&~16]])); +// int sy = getScreenY(getUnit(_clipY[cra[c&~16]])); +// sPoints.putPoints(sCount++, 1, sx, sy); +// } +// } +// else { +// if (co & 16) { +// if (!(co & ce)) ce = co + tcc[ce]; +// } +// else { +// ce |= co; +// if (tcc[ce] == 1) ce |= 16; +// } +// } +// } +// if (ce & 16) { +// int sx = getScreenX(getUnit(_clipX[cra[ce&~16]])); +// int sy = getScreenY(getUnit(_clipY[cra[ce&~16]])); +// sPoints.putPoints(sCount++, 1, sx, sy); +// } +// } +// xo = xe; +// yo = ye; +// co = ce; +// endFor; +// } +// +// if (closed && sCount) { +// sPoints.putPoints(sCount++, 1, sPoints[0].x(), sPoints[0].y()); +// } +// +// return sCount; +//} +// + + +// ************************************************************************************************* +// CellWidget::_setStartedCommand() +// CellWidget::_setClipBox() +// ************************************************************************************************* + +//void +//CellWidget::_setStartedCommand(Command* command) +//{ +// _startedCommand = command; +//} + +void +CellWidget::_setClipBox(const Box& area) +{ + _clipBox = Box(area).inflate(getSize(2)); + + _clipX[0] = getValue(_clipBox.getXMin()); + _clipX[1] = getValue(_clipBox.getXMax()); + _clipX[2] = getValue(_clipBox.getXMin()); + _clipX[3] = getValue(_clipBox.getXMax()); + _clipY[0] = getValue(_clipBox.getYMin()); + _clipY[1] = getValue(_clipBox.getYMin()); + _clipY[2] = getValue(_clipBox.getYMax()); + _clipY[3] = getValue(_clipBox.getYMax()); +} + + + +// ************************************************************************************************* +// CellWidget::_redraw() +// ************************************************************************************************* + +void +CellWidget::_redraw() +{ + if (!_invalidRegion.isEmpty()) { + QRect invalidRect = _invalidRegion.boundingRect(); + + if (_doubleBuffering) { + _invalidRegion = invalidRect; + } + + Box area = getBox(invalidRect).inflate(getSize(1)); + + _setClipBox(area); + + QPaintDevice* device = this; + + if (_doubleBuffering) { + //device = _getPixmap(); + } + + QPainter painter(device); + QPainter* oldPainter = _painter; + _painter = &painter; + + QRegion deepRegion; + for (list::iterator plit = _peekList.begin(); + plit != _peekList.end(); + ++plit) { + deepRegion = deepRegion.unite(QRegion(getScreenRect(*plit))); + } +// forEachBox(peek, _peekList) { +// deepRegion = deepRegion.unite(QRegion(getScreenRect(peek))); +// endFor; +// } + deepRegion = deepRegion.intersect(_invalidRegion); + Box deepArea = getBox(deepRegion.boundingRect()); + + _painter->setClipRegion(_invalidRegion); + + _painter->fillRect(invalidRect, QBrush(getBackgroundColor())); + + preRedraw(area); + + QRegion region = _invalidRegion.subtract(deepRegion); + + Cell* cell = getCell(); + if (cell) { + + + _painter->save(); + + + double brightness = 1.0; + //if (highlightionIsVisible() && !getHighlightion().isEmpty()) { + // brightness = 0.4; + //} + + setPen(boundariesPen, brightness); + setBrush(boundariesBrush, brightness); + //drawBoundaries(cell, area, Transformation()); + + + for_each_basic_layer(layer, getVisibleLayers()) { + if (isDrawable(layer)) { + //setFont(getFont(layer)); + //setPen(layer->getPen(), brightness); + setPen(getPen(layer), brightness); + //setBrush(layer->getBrush(), brightness); + setBrush(getBrush(layer), brightness); + //setBrushOrigin(layer->getBrushOrigin()); + if (deepRegion.isEmpty()) { + drawContent(cell, layer, area, Transformation()); + // view->_draw(this, layer, area, Transformation()); + } else { + _painter->setClipRegion(region); + drawContent(cell, layer, area, Transformation()); + //view->_draw(this, layer, area, Transformation()); + _painter->setClipRegion(deepRegion); + unsigned displayDepth = _displayDepth; + _displayDepth = (unsigned)-1; + //view->_draw(this, layer, deepArea, Transformation()); + drawContent(cell, layer, deepArea, Transformation()); + _displayDepth = displayDepth; + _painter->setClipRegion(_invalidRegion); + } + //_painter->flush(); + } + end_for; + } +// if (highlightionIsVisible() && !getHighlightion().isEmpty()) { +// Technology* technology = getDatabase()->getTechnology(); +// if (technology) { +// forEachLayer(layer, technology->getLayers()) { +// if (isDrawable(layer)) { +// setFont(layer->getFont()); +// setPen(layer->getPen()); +// setBrush(layer->getBrush()); +// setBrushOrigin(layer->getBrushOrigin()); +// forEachOccurrence(occurrence, getHighlightion()) { +// Figure* figure = dynamic_cast(occurrence.getEntity()); +// if (figure && +// figure->isMaterialized() && +// (figure->getLayerMask() & layer->getMask())) { +// Box boundingBox = occurrence.getBoundingBox(); +// if (boundingBox.overlaps(area)) { +// Transformation transformation = +// occurrence.getPath().getTransformation(); +// Box correctedArea = +// transformation.getInverted().getBox(area); +// figure->_draw(this, layer, correctedArea, transformation); +// } +// } +// endFor; +// } +// _painter->flush(); +// } +// endFor; +// } +// } +// } +// if (selectionIsVisible()) { +// QColor selectionColor = getSelectionColor(); +// setPen(selectionColor); +// setBrush(QBrush(selectionColor, Dense4Pattern)); +// setBrushOrigin(QPoint(0, 0)); +// forEachOccurrence(occurrence, getSelection()) { +// Figure* figure = dynamic_cast(occurrence.getEntity()); +// if (figure) { +// Box boundingBox = occurrence.getBoundingBox(); +// if (boundingBox.overlaps(area)) { +// figure->_highlight(this, occurrence.getPath().getTransformation()); +// } +// } +// endFor; +// } +// } + _painter->restore(); + if (gridIsVisible() && gridIsDrawable()) { + Unit xMin = getGridX(getX(0)); + Unit yMin = getGridY(getY(height())); + Unit xMax = getGridX(getX(width())); + Unit yMax = getGridY(getY(0)); + setPen(getGridColor()); + for (Unit x = xMin; x <= xMax; x += _gridXStep) { + int sx = getScreenX(x); + if (_gridAxesAreVisible && (x == getGridOrigin().getX())) { + //_painter->moveTo(sx, 0); + //_painter->lineTo(sx, height()); + _painter->drawLine(sx, 0, sx, height()); + } + for (Unit y = yMin; y <= yMax; y += _gridYStep) { + int sy = getScreenY(y); + if (_gridAxesAreVisible && (y == getGridOrigin().getY())) { + //_painter->moveTo(0, sy); + //_painter->lineTo(width(), sy); + _painter->drawLine(0, sy, width(), sy); + } + if (!(isOnGridX(x, 10) && isOnGridY(y, 10))) { + _painter->drawPoint(sx, sy); + } + else { + //_painter->moveTo(sx - 2, sy); + //_painter->lineTo(sx + 2, sy); + _painter->drawLine(sx - 2, sy, sx + 2, sy); + //_painter->moveTo(sx, sy - 2); + //_painter->lineTo(sx, sy + 2); + _painter->drawLine(sx, sy - 2, sx, sy + 2); + } + } + } + } + } + + postRedraw(area); + + if (device != this) { + int x = invalidRect.x(); + int y = invalidRect.y(); + int w = invalidRect.width(); + int h = invalidRect.height(); + //bitBlt(this, x, y, device, x, y, w, h, CopyROP, true); + } + + _setClipBox(getBox(rect())); + + _painter = oldPainter; + + _invalidRegion = QRegion(); + } +} + + + +// ************************************************************************************************* +// CellWidget::_callDrawOf() +// ************************************************************************************************* + +//void +//CellWidget::_callDrawOf(Command* command) +//{ +// assert(command); +// assert(command->isInstalledOn(this)); +// +// if (getView()) { +// QPainter painter(this); +// +// _painter = &painter; +// +// _painter->setRasterOp(XorROP); +// _painter->setPen(getForegroundColor()); +// _painter->setBrush(NoBrush); +// +// command->onDraw(this); +// } +//} +// + + +// ************************************************************************************************* +// CellWidget::_insertCommand() +// CellWidget::_removeCommand() +// ************************************************************************************************* + +//void +//CellWidget::_insertCommand(Command* command) +//{ +// _commandMap[command->getButton()] = command; +//} +// +//void +//CellWidget::_removeCommand(Command* command) +//{ +// _commandMap.erase(command->getButton()); +//} +// +// +// +//// ************************************************************************************************* +//// CellWidget::_insertSelector() +//// CellWidget::_removeSelector() +//// ************************************************************************************************* +// +//void +//CellWidget::_insertSelector(Selector* selector) +//{ +// _selectorSet.insert(selector); +//} +// +//void +//CellWidget::_removeSelector(Selector* selector) +//{ +// _selectorSet.erase(selector); +//} +// +// +// +//// ************************************************************************************************* +//// CellWidget::_insertHighlightor() +//// CellWidget::_removeHighlightor() +//// ************************************************************************************************* +// +//void +//CellWidget::_insertHighlightor(Highlightor* highlightor) +//{ +// _highlightorSet.insert(highlightor); +//} +// +//void +//CellWidget::_removeHighlightor(Highlightor* highlightor) +//{ +// _highlightorSet.erase(highlightor); +//} +// + + +//CLOSE_MY_NAMESPACE + +// ************************************************************************************************* +// ************************************************************************************************* diff --git a/hurricane/src/viewer.xtof/CellWidget.h b/hurricane/src/viewer.xtof/CellWidget.h new file mode 100644 index 00000000..d0d5e5e2 --- /dev/null +++ b/hurricane/src/viewer.xtof/CellWidget.h @@ -0,0 +1,1641 @@ +// ************************************************************************************************* +// ************************************************************************************************* +// File: CellWidget.h +// ************************************************************************************************* +// ************************************************************************************************* + +#ifndef H_CellWidget +#define H_CellWidget + +#include + +#include "Box.h" +//#include "Commands.h" +#include "Slice.h" +#include "Segment.h" +#include "Contact.h" +#include "Layers.h" +#include "BasicLayer.h" +#include "Occurrences.h" +#include "Points.h" +using namespace Hurricane; +//#include "Selectors.h" + +//OPEN_MY_NAMESPACE + +//class View; +//class TrackBox; + + +// ************************************************************************************************* +// CellWidget +// ************************************************************************************************* + +class /* Q_EXPORT */ CellWidget : public QWidget { + + Q_OBJECT + + public: + ~CellWidget(); + + Cell* getCell() const; + //View* getView() const ; + const Point& getCenter() const; + double getScale() const; + Unit getX(int screenX) const; + Unit getY(int screenY) const; + Unit getSize(int screenSize) const; + Point getPoint(const QPoint& screenPoint) const; + Box getBox(const QRect& screenRect) const; + int getScreenX(const Unit& x) const; + int getScreenY(const Unit& y) const; + int getScreenSize(const Unit& size) const; + QPoint getScreenPoint(const Point& point) const; + QRect getScreenRect(const Box& box) const; + Point getSnapPoint(const Point& point) const; + Point getSnapPoint(int screenX, int screenY) const; + const QColor& getBackgroundColor() const; + const QColor& getForegroundColor() const; + const Layer::Mask& getVisibleLayerMask() const; + BasicLayers getVisibleLayers() const; + //Command* getCommand(int button) const; + //Command* getStartedCommand() const; + //Commands getCommands() const; + const Point& getGridOrigin() const; + const Unit& getGridXStep() const; + const Unit& getGridYStep() const; + unsigned getGridDisplayThreshold() const; + const QColor& getGridColor() const; + Unit getGridX(const Unit& x, + int sign = 0) const; + Unit getGridY(const Unit& y, + int sign = 0) const; + Point getGridPoint(const Point& point, + int xSign = 0, + int ySign = 0) const; + unsigned getDisplayDepth() const; + unsigned getDisplaySize() const; + Occurrences getSelection() const; + Box getSelectionBox() const; + unsigned getSelectionLimit() const; + const QColor& getSelectionColor() const; + Occurrences getHighlightion() const; + Box getHighlightionBox() const; + unsigned getHighlightionLimit() const; + const QFont& getFont(); + const QPen& getPen(); + const QPen& getPen(const BasicLayer* layer); + const QBrush& getBrush(); + const QBrush& getBrush(BasicLayer* layer); + const QPoint getBrushOrigin(); + //TrackBox* getTrackBox() const; + + bool doubleBuffering() const; + bool automaticScrolling() const; + bool isVisible(BasicLayer* layer) const; + bool isDrawable(BasicLayer* layer) const; + bool gridIsVisible() const; + bool gridAxesAreVisible() const; + bool gridIsDrawable() const; + bool isOnGridX(const Unit& x, + unsigned n = 1) const; + bool isOnGridY(const Unit& y, + unsigned n = 1) const; + bool isOnGridPoint(const Point& point, + unsigned xN = 1, + unsigned yN = 1) const; + bool snapGrid() const; + bool selectionIsVisible() const; + bool isSelected(const Occurrence& occurrence) const; + bool isSelectable(const Occurrence& occurrence) const; + bool highlightionIsVisible() const; + bool isHighlighted(const Occurrence& occurrence) const; + bool isHighlightable(const Occurrence& occurrence) const; + + void setBackgroundColor(const QColor& color); + void setForegroundColor(const QColor& color); + void setDoubleBuffering(bool enable); + void setAutomaticScrolling(bool enable); + void setVisible(BasicLayer* layer, + bool visible); + void setGridOrigin(const Point& origin); + void setGridXStep(const Unit& step); + void setGridYStep(const Unit& step); + void setGridStep(const Unit& step); + void setGridSteps(const Unit& xStep, + const Unit& yStep); + void setGridDisplayThreshold(unsigned threshold); + void setGridColor(const QColor& color); + void setGridVisible(bool visible); + void setGridAxesVisible(bool visible); + void setSnapGrid(bool enable); + void setDisplayDepth(unsigned displayDepth); + void setDisplaySize(unsigned displaySize); + void setSelectionLimit(unsigned limit); + void setSelectionColor(const QColor& color); + void setSelectionVisible(bool visible); + void setHighlightionLimit(unsigned limit); + void setHighlightionVisible(bool visible); + void setFont(const QFont& font); + void setPen(const QPen& pen, + double brightness = 1.0); + void setBrush(const QBrush& brush, + double brightness = 1.0); + void setBrushOrigin(const QPoint& origin); + //void setTrackBox(TrackBox* trackBox); + + void showAllLayers(); + void hideAllLayers(); + bool select(const Occurrence& occurrence); + void unselect(const Occurrence& occurrence); + //void clearSelection(); + //bool highlight(const Occurrence& occurrence); + //void unhighlight(const Occurrence& occurrence); + //void clearHighlightion(); + void clearPeeks(); + void addPeek(const Box& box); + + void invalidate(); + void invalidate(const QRect& screenRect); + void invalidate(const Box& box); + void fitToContent(unsigned screenMargin = 5) ; + void reframe(double scale); + void reframe(const Point& center); + void reframe(const Point& center, + double scale); + void reframe(const Box& box); + void scroll(const Unit& dx, + const Unit& dy); + void redraw(); + void abortStartedCommand(); + + + void drawContent(const Cell* cell, const BasicLayer* basicLayer, const Hurricane::Box& updateArea, const Transformation& transformation) const; + void drawContent(const Instance* instance, const BasicLayer* basicLayer, const Hurricane::Box& updateArea, const Transformation& transformation) const; + void drawSlice(const Slice* slice, const BasicLayer* basicLayer, const Hurricane::Box& updateArea, const Transformation& transformation) const; + void drawPhantoms(const Cell* cell, const Box& updateArea, const Transformation& transformation) const; + void drawPhantoms(const Instance* instance, const Box& updateArea, const Transformation& transformation) const; + void drawBoundaries(const Cell* cell, const Box& updateArea, const Transformation& transformation) const; + void drawBoundaries(const Instance* instance, const Box& updateArea, const Transformation& transformation) const; + void drawGo(const Go* go, const BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) const; + void drawSegment(const Segment* segment, const BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) const; + void drawContact(const Contact* contact, const BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) const; + + void drawLine(const Unit& xo, + const Unit& yo, + const Unit& xe, + const Unit& ye) const; + void drawLine(const Point& origin, + const Point& extremity) const; + void drawPolyline(const Points& points); + + void drawRectangle(const Unit& xMin, + const Unit& yMin, + const Unit& xMax, + const Unit& yMax) const; + void drawRectangle(const Box& box) const; + void drawPolygon(const Points& points); + //void drawText(const Box& frame, + // const string& text, + // const Direction& direction); + //void drawText(const Box& frame, +// const Name& name, +// const Direction& direction); +#ifndef DOXYGEN + public: + typedef QWidget Inherit; + + //Label getLabel() const; + Record* getRecord() const; + Slot* getSlot(const string& name) const; + Box getWorld() const; + //Selectors getSelectors() const; + //Highlightors getHighlightors() const; + + bool hasRecord() const; + bool allowAutomaticScrolling() const; + + void reframe(); + + void preRedraw(const Box& area); + void postRedraw(const Box& area); + + void drawSnapPoint(); + + CellWidget(Cell* cell, + QWidget* parent = NULL, + const char* name = NULL); + + protected: + + void resizeEvent(QResizeEvent* event); + //void enterEvent(QEvent* event); + //void leaveEvent(QEvent* event); + //void mousePressEvent(QMouseEvent* event); + //void mouseMoveEvent(QMouseEvent* event); + //void mouseReleaseEvent(QMouseEvent* event); + //void focusInEvent(QFocusEvent* event); + //void focusOutEvent(QFocusEvent* event); + void paintEvent(QPaintEvent* event); + + void onSetVisible(Layer* layer, + bool visible); + + private: + CellWidget(const CellWidget& porthole); + // not implemented to forbid copy + + CellWidget& operator=(const CellWidget& porthole); + // not implemented to forbid assignment + + int getClipCode(double x, + double y) const; + bool clipLine(double& xo, + double& yo, + int co, + double& xe, + double& ye, + int ce, + int u = 0) const; +// bool clipLines(const Points& points, +// QPointArray& sPoints, +// unsigned& sCount, +// bool closed = false) const; +// +// typedef map CommandMap; +// typedef set SelectorSet; +// typedef set HighlightorSet; + typedef list PeekList; + + Cell* _cell; + Point _center; + double _scale; + int _screenDx; + int _screenDy; + int _brushDx; + int _brushDy; + bool _alreadyExposed; + QRegion _invalidRegion; + Box _clipBox; + double _clipX[4]; + double _clipY[4]; + QPainter* _painter; + QColor _backgroundColor; + QColor _foregroundColor; + bool _doubleBuffering; + bool _automaticScrolling; + Layer::Mask _visibleLayerMask; + //CommandMap _commandMap; + //Command* _startedCommand; + Point _gridOrigin; + Unit _gridXStep; + Unit _gridYStep; + bool _gridIsVisible; + bool _gridAxesAreVisible; + unsigned _gridDisplayThreshold; + QColor _gridColor; + bool _snapGrid; + bool _drawSnapPoint; + Point _snapPoint; + unsigned _displayDepth; + unsigned _displaySize; + //SelectorSet _selectorSet; + unsigned _selectionLimit; + QColor _selectionColor; + bool _selectionIsVisible; + //HighlightorSet _highlightorSet; + unsigned _highlightionLimit; + bool _highlightionIsVisible; + //static QPointArray _sPoints; + //TrackBox* _trackBox; + PeekList _peekList; + map _basicLayersBrush; + map _basicLayersPen; + + protected: + //restricted: + //QPixmap* _getPixmap() const ; + + //void _setStartedCommand(Command* command); + //void _setTrackBox(TrackBox* trackBox); + void _setClipBox(const Box& area); + + void _redraw(); + //void _callDrawOf(Command* command); + + // void _insertCommand(Command* command); + // void _removeCommand(Command* command); + // void _insertSelector(Selector* selector); + // void _removeSelector(Selector* selector); + // void _insertHighlightor(Highlightor* highlightor); + // void _removeHighlightor(Highlightor* highlightor); +#endif // DOXYGEN + +}; + + + +// ************************************************************************************************* +// getLabel() +// getRecord() +// getSlot() +// ************************************************************************************************* + +#ifndef DOXYGEN +//inline +//Label +//getLabel(const CellWidget& porthole) +//{ +// return porthole.getLabel(); +//} +// +//inline +//Label +//getLabel(const CellWidget* porthole) +//{ +// return (!porthole) ? Label("nil") : porthole->getLabel(); +//} +// +//inline +//Record* +//getRecord(const CellWidget& porthole) +//{ +// return porthole.getRecord(); +//} +// +//inline +//Record* +//getRecord(const CellWidget* porthole) +//{ +// return (!porthole) ? NULL : porthole->getRecord(); +//} +// +//inline +//Slot* +//getSlot(const string& name, +// const CellWidget& porthole) +//{ +// return porthole.getSlot(name); +//} +// +//inline +//Slot* +//getSlot(const string& name, +// const CellWidget* porthole) +//{ +// return (!porthole) ? getSlot(name, getLabel("nil")) : porthole->getSlot(name); +//} +#endif // DOXYGEN + + + +// ************************************************************************************************* +// hasRecord() +// ************************************************************************************************* + +#ifndef DOXYGEN +//inline +//bool +//hasRecord(const CellWidget& porthole) +//{ +// return porthole.hasRecord(); +//} +// +//inline +//bool +//hasRecord(const CellWidget* porthole) +//{ +// return (!porthole) ? false : porthole->hasRecord(); +//} +#endif // DOXYGEN + + + +// ************************************************************************************************* +// operator<<() +// ************************************************************************************************* + +#ifndef DOXYGEN +//inline +//ostream& +//operator<<(ostream& stream, +// const CellWidget& porthole) +//{ +// return stream << porthole.getLabel(); +//} +// +//inline +//ostream& +//operator<<(ostream& stream, +// const CellWidget* porthole) +//{ +// return (!porthole) ? (stream << "nil") : (stream << "&" << porthole->getLabel()); +//} +#endif // DOXYGEN + + + +// ************************************************************************************************* +// CellWidget::getBackgroundColor() +// CellWidget::getForegroundColor() +// CellWidget::getStartedCommand() +// CellWidget::getGridOrigin() +// CellWidget::getGridXStep() +// CellWidget::getGridYStep() +// CellWidget::getGridDisplayThreshold() +// CellWidget::getGridColor() +// CellWidget::getDisplayDepth() +// CellWidget::getDisplaySize() +// CellWidget::getSelectionColor() +// CellWidget::getSelectionLimit() +// CellWidget::getHighlightionLimit() +// CellWidget::getTrackBox() +// ************************************************************************************************* + +inline +const QColor& +CellWidget::getBackgroundColor() const +{ + return _backgroundColor; +} + +inline +const QColor& +CellWidget::getForegroundColor() const +{ + return _foregroundColor; +} + +inline +const Layer::Mask& +CellWidget::getVisibleLayerMask() const +{ + return _visibleLayerMask; +} + +// +//inline +//Command* +//CellWidget::getStartedCommand() const +//{ +// return _startedCommand; +//} + +inline +const Point& +CellWidget::getGridOrigin() const +{ + return _gridOrigin; +} + +inline +const Unit& +CellWidget::getGridXStep() const +{ + return _gridXStep; +} + +inline +const Unit& +CellWidget::getGridYStep() const +{ + return _gridYStep; +} + +inline +unsigned +CellWidget::getGridDisplayThreshold() const +{ + return _gridDisplayThreshold; +} + +inline +const QColor& +CellWidget::getGridColor() const +{ + return _gridColor; +} + +inline +unsigned +CellWidget::getDisplayDepth() const +{ + return _displayDepth; +} + +inline +unsigned +CellWidget::getDisplaySize() const +{ + return _displaySize; +} + +inline +const QColor& +CellWidget::getSelectionColor() const +{ + return _selectionColor; +} + +inline +unsigned +CellWidget::getSelectionLimit() const +{ + return _selectionLimit; +} + +inline +unsigned +CellWidget::getHighlightionLimit() const +{ + return _highlightionLimit; +} + +//inline +//TrackBox* +//CellWidget::getTrackBox() const +//{ +// return _trackBox; +//} + + + +// ************************************************************************************************* +// CellWidget::doubleBuffering() +// CellWidget::automaticScrolling() +// CellWidget::gridIsVisible() +// CellWidget::gridAxesAreVisible() +// CellWidget::gridIsDrawable() +// CellWidget::snapGrid() +// CellWidget::selectionIsVisible() +// CellWidget::highlightionIsVisible() +// ************************************************************************************************* + +inline +bool +CellWidget::doubleBuffering() const +{ + return _doubleBuffering; +} + +inline +bool +CellWidget::automaticScrolling() const +{ + return _automaticScrolling; +} + +inline +bool +CellWidget::gridIsVisible() const +{ + return _gridIsVisible; +} + +inline +bool +CellWidget::gridAxesAreVisible() const +{ + return _gridAxesAreVisible; +} + +inline +bool +CellWidget::gridIsDrawable() const +{ + return ((int)_gridDisplayThreshold < getScreenSize(min(_gridXStep, _gridYStep))); +} + +inline +bool +CellWidget::snapGrid() const +{ + return _snapGrid; +} + +inline +bool +CellWidget::selectionIsVisible() const +{ + return _selectionIsVisible; +} + +inline +bool +CellWidget::highlightionIsVisible() const +{ + return _highlightionIsVisible; +} + + + +// ************************************************************************************************* +// CellWidget::setDoubleBuffering() +// CellWidget::setSelectionLimit() +// CellWidget::setHighlightionLimit() +// ************************************************************************************************* + +inline +void +CellWidget::setDoubleBuffering(bool enable) +{ + _doubleBuffering = enable; +} + +inline +void +CellWidget::setSelectionLimit(unsigned limit) +{ + _selectionLimit = limit; +} + +inline +void +CellWidget::setHighlightionLimit(unsigned limit) +{ + _highlightionLimit = limit; +} + + + +// ************************************************************************************************* +// CellWidget::drawLine() +// CellWidget::drawRectangle() +// CellWidget::drawText() +// ************************************************************************************************* + +inline +void +CellWidget::drawLine(const Point& origin, + const Point& extremity) const +{ + drawLine(origin.getX(), origin.getY(), extremity.getX(), extremity.getY()); +} + +inline +void +CellWidget::drawRectangle(const Unit& xMin, + const Unit& yMin, + const Unit& xMax, + const Unit& yMax) const +{ + drawRectangle(Box(xMin, yMin, xMax, yMax)); +} + +//inline +//void +//CellWidget::drawText(const Box& frame, +// const Name& name, +// const Direction& direction) +//{ +// drawText(frame, name.getString(), direction); +//} + + + +// ************************************************************************************************* +// CellWidget::_setTrackBox() +// ************************************************************************************************* + +//#ifndef DOXYGEN +//inline +//void +//CellWidget::_setTrackBox(TrackBox* trackBox) +//{ +// _trackBox = trackBox; +//} +//#endif // DOXYGEN +// + + +// ************************************************************************************************* +// File documentation +// ************************************************************************************************* + +/*!\file + \brief This file contains the definition of the CellWidget class. + \paragraph Concept of CellWidget: + \nn A porthole is a Qt widget used to display a cell view. + \nn When a porthole is bound to a given cell view the content of this cell view is + displayed according to some porthole characteristics (zoom factor, grid, visible + layers, selection, highlightion, ...). + \nn The display reflects exactly the current state of the cell view (there isn't a + parallel display list). + \nn A porthole can display one and only one cell view, but a cell view can be displayed + simultaneously in multiple portholes. The fact that each porthole has its own + characteristics provides the capability to show different aspects of the same cell + view within separated portholes. + \paragraph Concept of MainCellWidget: + \nn The MainCellWidget class implements the concept of main porthole. + \nn The porthole class being an abstract class, to display a cell view you should create + a main porthole (or a specialization) and insert this widget in your graphic + interface (as all other widgets). + \nn Furthermore, you can attach to each main porthole a map porthole used to visualize + which part of the cell view is currently drawn in the main porthole and, can attach + a palette used to control the visibility of each layer and you can also two main + scroll bars. + \paragraph Concept of MapCellWidget: + \nn The MapCellWidget class implements the concept of map porthole. + \nn A map porthole is used to visualize which part of the cell view is currently + displayed by a main porthole. + \see View, MainCellWidget, MapCellWidget, Palette or Command. + \author \remye + */ + + + +// ************************************************************************************************* +// CellWidget documentation +// ************************************************************************************************* + +/*!\class CellWidget + \brief This abstract class introduces the concept of porthole + \concept A porthole is a Qt widget used to display a cell view. + \nn When a porthole is bound to a given cell view the content of this cell view is + displayed according to some porthole characteristics (zoom factor, grid, visible + layers, selection, highlightion, ...) as we will discover in the following. + \nn The display reflects exactly the current state of the cell view (there isn't a + parallel display list). + \nn A porthole can display one and only one cell view, but a cell view can be displayed + simultaneously in multiple portholes. The fact that each porthole has its own + characteristics provides the capability to show different aspects of the same cell + view within separated portholes. + \paragraph Specialization: + \nn The database provides two kind of portholes: the MainCellWidget which is used to + display the totality or some part of a cell view; and the MapCellWidget which is + associated to a main porthole to show which part of the cell view is currently + displayed in this main porthole. + \nn Note that, if you need to create a new kind of porthole you should inherit of one + of those types and not directly of the base class. + \paragraph Selection: + \nn Each porthole manages a collection of selected occurrences. The selection being + managed by portholes and not by cell views it's possible to have differents + selections for differents portholes bound to the same cell view. + \nn The selection is managed with the help of occurrence properties which is a very + secure mechanism. So, when an occurrence is no longer valid, this occurrence is + automaticaly unselected from each porthole it was selected in. + \paragraph Highlightion: + \nn Each porthole manages a collection of highlighted occurrences. The highlightion + being managed by portholes and not by cell views it's possible to have differents + highlightions for differents portholes bound to the same cell view. + \nn The highlightion is managed with the help of occurrence properties which is a very + secure mechanism. So, when an occurrence is no longer valid, this occurrence is + automaticaly unhighlighted from each porthole it was highlighted in. + \paragraph Commands: + \nn The database provides some command facilities. A command is an object which models + the behaviour to be obtained in reaction to mouse events within a porthole. + \nn Furthermore, coordinates which are manipulated by commands are cell view + coordinates and not screen coordinates (the translation being done by the porthole). + \nn %Commands are very powerfull objects which make the task more easier by managing + automaticaly important features of portholes like double buffering, automatic + scrolling, synchronization of the xor more when drawing ghost shapes... + \paragraph Palette: + \nn A palette can be used to control the visibility of the layers in a given main + porthole. + \paragraph Main scroll bars: + \nn You can also attach to each main porthole an horizontal and/or a vertical scroll + bar. + \paragraph Updates: + \nn A lot of functions provided by this class change the characteristics of the display. + \nn So, to avoid useless intermediate drawings or screen flickerings those functions + don't update the display immediately but post some invalidation regions which are + cumulated until a real request of redraw is asked. + \nn Furthermore, when a redraw is asked, something is done only when the invalidated + region isn't empty. + \paragraph Drawing: + \nn The CellWidget class provides some convenience functions to draw shapes which are + defined in cell view coordinates (and not in screen ones) according to the center, + scale and clipping region. + \nn So, no need to manage screen transformations, clipping or something like that. No + need to manage colors, pens, brushes or something else because all is controled by + the porthole which know when it is drawing a given layer or when it is drawing a + command ghost (in xor mode). + \paragraph Usage: + \nn The following piece of code illustrate the manner to build a very simple graphical + interface using a main porthole, a map porthole, two main scroll bars and a palette. + Furthermore, some commands are installed in the different portholes. The returned + editor being a widget it can be embedded in another parent widget which can add, for + example, a menu bar, a status bar or some additionnal decorations... + \code + * QWidget* getEditor(View* view) + * { + * QHBox* editor = new QHBox(); + * + * QFrame* mainFrame = new QFrame(editor); + * mainFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken); + * mainFrame->setLineWidth(2); + * mainFrame->setMinimumSize(120, 120); + * editor->setStretchFactor(mainFrame, 1); + * + * QGridLayout* mainLayout = new QGridLayout(mainFrame, 2, 2); + * mainLayout->setMargin(2); + * + * MainCellWidget* mainCellWidget = new MainCellWidget(mainFrame); + * mainLayout->addWidget(mainCellWidget, 0, 0); + * + * MainScrollBar* hScrollBar = new MainScrollBar(mainFrame); + * hScrollBar->setOrientation(Qt::Horizontal); + * mainLayout->addWidget(hScrollBar, 1, 0); + * + * MainScrollBar* vScrollBar = new MainScrollBar(mainFrame); + * vScrollBar->setOrientation(Qt::Vertical); + * mainLayout->addWidget(vScrollBar, 0, 1); + * + * QVBox* vBox = new QVBox(editor); + * editor->setStretchFactor(vBox, 0); + * vBox->setMinimumWidth(120); + * vBox->setMaximumWidth(120); + * vBox->setSpacing(5); + * + * QFrame* mapFrame = new QFrame(vBox); + * mapFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken); + * mapFrame->setLineWidth(2); + * mapFrame->setMinimumSize(120, 120); + * mapFrame->setMaximumSize(120, 120); + * + * QGridLayout* mapLayout = new QGridLayout(mapFrame, 1, 1); + * mapLayout->setMargin(2); + * + * MapCellWidget* mapCellWidget = new MapCellWidget(mapFrame); + * mapLayout->addWidget(mapCellWidget, 0, 0); + * + * Palette* palette = new Palette(vBox); + * + * mainCellWidget->setView(view); + * mainCellWidget->setMapCellWidget(mapCellWidget); + * mainCellWidget->setPalette(palette); + * mainCellWidget->setHScrollBar(hScrollBar); + * mainCellWidget->setVScrollBar(vScrollBar); + * + * mapCellWidget->hideAllLayers(); + * Layer* phantom = getDatabase()->getTechnology()->getLayer("PHANTOM"); + * if (phantom) { + * mapCellWidget->setVisible(phantom, true); + * } + * + * getZoomCommand().installOn(mainCellWidget); + * getSelectCommand().installOn(mainCellWidget); + * getPanCommand().installOn(mainCellWidget); + * + * getZoomCommand().installOn(mapCellWidget); + * getPanCommand().installOn(mapCellWidget); + * + * editor->resize(700, 500); + * editor->setMargin(5); + * editor->setSpacing(5); + * editor->show(); + * + * return editor; + * } + \endcode + \nn + \see View, MainCellWidget, MapCellWidget, MainScrollBar, Palette or Command. + \author \remye + */ + +/*!\function CellWidget::~CellWidget() + \behaviour This is the destructor. + */ + +//@{ +/*!\function View* CellWidget::getView() const + \behaviour This function returns the view displayed in this porthole. + */ + +/*!\function const Point& CellWidget::getCenter() const + \behaviour This function returns the center of this porthole. + \nn This center is in fact the point of the cell view which is located on the center of + this porthole. + \note Returns the point \c [0,0] if the porthole isn't bound to a cell view. + */ + +/*!\function double CellWidget::getScale() const + \behaviour This function returns the scale used by this porthole to display its contents. + \note Returns \c 1.0 if the porthole isn't bound to a cell view. + */ + +/*!\function Unit CellWidget::getX(int screenX) const + \behaviour This function returns the cell view abscissa corresponding to a screen abscissa. + \parameter screenX The screen abscissa for which the request is asked. + */ + +/*!\function Unit CellWidget::getY(int screenY) const + \behaviour This function returns the cell view ordinate corresponding to a screen ordinate. + \parameter screenY The screen ordinate for which the request is asked. + */ + +/*!\function Unit CellWidget::getSize(int screenSize) const + \behaviour This function returns the cell view dimension corresponding to a screen dimension. + \parameter screenSize The screen dimension for which the request is asked. + */ + +/*!\function Point CellWidget::getPoint(const QPoint& screenPoint) const + \behaviour This function returns the cell view location corresponding to a screen location. + \parameter screenPoint The screen location for which the request is asked. + */ + +/*!\function Box CellWidget::getBox(const QRect& screenRect) const + \behaviour This function returns the cell view box corresponding to a screen rectangle. + \parameter screenRect The screen rectangle for which the request is asked. + */ + +/*!\function int CellWidget::getScreenX(const Unit& x) const + \behaviour This function returns the screeen abscissa corresponding to a cell view abscissa. + \parameter x The cell view abscissa for which the request is asked. + */ + +/*!\function int CellWidget::getScreenY(const Unit& y) const + \behaviour This function returns the screeen ordinate corresponding to a cell view ordinate. + \parameter y The cell view ordinate for which the request is asked. + */ + +/*!\function int CellWidget::getScreenSize(const Unit& size) const + \behaviour This function returns the screeen dimension corresponding to a cell view dimension. + \parameter size The cell view dimension for which the request is asked. + */ + +/*!\function QPoint CellWidget::getScreenPoint(const Point& point) const + \behaviour This function returns the screeen location corresponding to a cell view location. + \parameter point The cell view location for which the request is asked. + */ + +/*!\function QRect CellWidget::getScreenRect(const Box& box) const + \behaviour This function returns the screeen rectangle corresponding to a cell view box. + \parameter box The cell view box for which the request is asked. + */ + +/*!\function Point CellWidget::getSnapPoint(const Point& point) const + \behaviour This convenience function returns the cell view location associated to a given cell + view location in respect to the snap grid status. + \nn So when snap grid is enabled the returned location correspond to the nearest grid + point of the given location else the returned location is the given location itself. + \parameter point The cell view location for which the request is asked. + */ + +/*!\function Point CellWidget::getSnapPoint(int screenX, int screenY) const + \behaviour This convenience function returns the cell view location associated to the specified + screen coordinates in respect to the snap grid status. + \nn So when snap grid is enabled the returned location correspond to the nearest grid + point of the location obtained from the specified screen coordinates else the + returned location is directly the location obtained from the specified screen + coordinates. + \parameter screenX The screen abscissa for which the request is asked. + \parameter screenY The screen ordinate for which the request is asked. + */ + +/*!\function const QColor& CellWidget::getBackgroundColor() const + \behaviour This function returns the background color of this porthole. + */ + +/*!\function const QColor& CellWidget::getForegroundColor() const + \behaviour This function returns the foreground color of this porthole. + */ + +/*!\function const LayerMask& CellWidget::getVisibleLayerMask() const + \behaviour This function returns the mask representing the visible layers of this porthole. + */ + +/*!\function Layers CellWidget::getVisibleLayers() const + \behaviour This function returns the collection of visible layers (can be empty). + \note The layers are sorted from the deepest one to the higher one. + */ + +/*!\function Command* CellWidget::getCommand(int button) const + \behaviour This function returns the command which is installed on a given button. + \parameter button The button for which we want to get the associated command. + */ + +/*!\function Command* CellWidget::getStartedCommand() const + \behaviour This function returns the command of this porthole which has started. + \note Returns \NULL when no command has started. + */ + +/*!\function Commands CellWidget::getCommands() const + \behaviour This function returns the collection of commands installed on this porthole. + */ + +/*!\function const Point& CellWidget::getGridOrigin() const + \behaviour This function returns the origin of the grid. + */ + +/*!\function const Unit& CellWidget::getGridXStep() const + \behaviour This function returns the horizontal grid step. + */ + +/*!\function const Unit& CellWidget::getGridYStep() const + \behaviour This function returns the vertical grid step. + */ + +/*!\function unsigned CellWidget::getGridDisplayThreshold() const + \behaviour This function returns the display threshold used to control the drawability of the + grid. + \nn The threshold is a minimal number of pixels allowed between two consecutives grid + points on screen. When the number of pixels is less than the threshold the grid + isn't drawn (even it is visible). + */ + +/*!\function const QColor& CellWidget::getGridColor() const + \behaviour This function returns the grid color of this porthole. + */ + +/*!\function Unit CellWidget::getGridX(const Unit& x, int sign) const + \behaviour This function returns the grid abscissa corresponding to a given cell view abscissa. + \parameter x The cell view abscissa for which the request is asked. + \parameter sign Indicates which grid position should be used. When the sign is -1 we + consider the lower grid position, when the sign is 0 we consider the + nearest position and when the sign is 1 we consider the upper grid + position (all other values are forbidden). + \exception INVALID_REQUEST This exception is thrown when the \c sign doesn't correspond to a + legal value. + */ + +/*!\function Unit CellWidget::getGridY(const Unit& y, int sign) const + \behaviour This function returns the grid ordinate corresponding to a given cell view ordinate. + \parameter y The cell view ordinate for which the request is asked. + \parameter sign Indicates which grid position should be used. When the sign is -1 we + consider the lower grid position, when the sign is 0 we consider the + nearest position and when the sign is 1 we consider the upper grid + position (all other values are forbidden). + \exception INVALID_REQUEST This exception is thrown when the \c sign doesn't correspond to a + legal value. + */ + +/*!\function Point CellWidget::getGridPoint(const Point& point, int xSign, int ySign) const + \behaviour This function returns the grid location corresponding to a given cell view location. + \parameter point The cell view location for which the request is asked. + \parameter xSign and + \parameter ySign Indicate which grid position should be used in the associated + direction. When the sign is -1 we consider the lower grid position, + when the sign is 0 we consider the nearest position and when the + sign is 1 we consider the upper grid position (all other values are + forbidden). + \exception INVALID_REQUEST This exception is thrown when the \c xSign or \c ySign doesn't + correspond to a legal value. + */ + +/*!\function unsigned CellWidget::getDisplayDepth() const + \behaviour This function returns the display depth of this porthole. + \note The display depth represent the maximal number of hierarchy levels that should be + drawn in this porthole. + */ + +/*!\function unsigned CellWidget::getDisplaySize() const + \behaviour This function returns the display size of this porthole. + \note To be drawn in a given porthole the maximal size of the bounding box of a figure + (on the screen) should be greather than the display size (defined in pixels). + */ + +/*!\function Occurrences CellWidget::getSelection() const + \behaviour This function returns the collection of occurrences selected in this porthole. + */ + +/*!\function Box CellWidget::getSelectionBox() const + \behaviour This function returns the box enclosing the selection of this porthole. + */ + +/*!\function unsigned CellWidget::getSelectionLimit() const + \behaviour This function returns the maximal number of occurrences that could be selected in + this porthole. + */ + +/*!\function const QColor& CellWidget::getSelectionColor() const + \behaviour This function returns the selection color of this porthole. + */ + +/*!\function Occurrences CellWidget::getHighlightion() const + \behaviour This function returns the collection of occurrences highlighted in this porthole. + */ + +/*!\function Box CellWidget::getHighlightionBox() const + \behaviour This function returns the box enclosing the highlightion of this porthole. + */ + +/*!\function unsigned CellWidget::getHighlightionLimit() const + \behaviour This function returns the maximal number of occurrences that could be highlighted in + this porthole. + */ + +/*!\function const QFont& CellWidget::getFont() const + \behaviour This function returns the current font of this porthole. + \note This is this font which is used by the drawing and filling functions. + */ + +/*!\function const QPen& CellWidget::getPen() const + \behaviour This function returns the current pen of this porthole. + \note This is this pen which is used by the drawing and filling functions. + */ + +/*!\function const QBrush& CellWidget::getBrush() const + \behaviour This function returns the current brush of this porthole. + \note This is this brush which is used by the drawing and filling functions. + */ + +/*!\function const QPoint& CellWidget::getBrushOrigin() const + \behaviour This function returns the current brush origin of this porthole. + \note This is this brush origin which is used by the drawing and filling functions. + */ + +/*!\function TrackBox* CellWidget::getTrackBox() const + \behaviour This function returns the track box associated to this porthole. + */ +//@} + +//@{ +/*!\function bool CellWidget::doubleBuffering() const + \behaviour This function returns \TRUE when the double buffering is enabled. + */ + +/*!\function bool CellWidget::automaticScrolling() const + \behaviour This function returns \TRUE when the automatic scrolling is enabled. + */ + +/*!\function bool CellWidget::isVisible(Layer* layer) const + \behaviour This function returns \TRUE when the specified layer is visible. + \parameter layer The layer for which the request is asked. + \note A visible layer is not systematicaly drawn. The display depends also of the layer + display threshold and the current scale. + */ + +/*!\function bool CellWidget::isDrawable(Layer* layer) const + \behaviour This function returns \TRUE when the layer can be drawn according to the layer + display threshold and the current scale. + \note A non visible layer can be drawable and a visible layer can be not drawable. So to + known if the layer should really be drawn you need to check its visibility and its + drawability. + */ + +/*!\function bool CellWidget::gridIsVisible() const + \behaviour This function returns \TRUE when the grid is visible. + \note A visible grid is not systematicaly drawn. The display depends also of the grid + display threshold and the current scale. + */ + +/*!\function bool CellWidget::gridAxesAreVisible() const + \behaviour This function returns \TRUE when the grid axes are visible. + \note Those grid axes are drawn only when this function returns \TRUE and the grid is + drawn. + */ + +/*!\function bool CellWidget::gridIsDrawable() const + \behaviour This function returns \TRUE when the grid can be drawn according to the grid + display threshold and the current scale. + \note A non visible grid can be drawable and a visible grid can be not drawable. So to + known if the grid should really be drawn you need to check its visibility and its + drawability. + */ + +/*!\function bool CellWidget::isOnGridX(const Unit& x, unsigned n) const + \behaviour This function returns \TRUE when the specified cell view abscissa is on a grid + position. + \parameter x The cell view abscissa for which the request is asked. + \parameter n This argument allows to do not take into account each grid position + but only those which are multiples of n (a null value is forbidden). + \exception INVALID_REQUEST This exception is thrown when \c n is null. + */ + +/*!\function bool CellWidget::isOnGridY(const Unit& y, unsigned n) const + \behaviour This function returns \TRUE when the specified cell view ordinate is on a grid + position. + \parameter y The cell view ordinate for which the request is asked. + \parameter n This argument allows to do not take into account each grid position + but only those which are multiples of n (a null value is forbidden). + \exception INVALID_REQUEST This exception is thrown when \c n is null. + */ + +/*!\function bool CellWidget::isOnGridPoint(const Point& point, unsigned xN, unsigned yN) const + \behaviour This function returns \TRUE when the specified cell view location is on a grid + location. + \parameter point The cell view location for which the request is asked. + \parameter xN and + \parameter yN Allow to do not take into account each grid position but only those + which are multiples of xN horizontaly and yN verticaly (null values + are forbidden). + \exception INVALID_REQUEST This exception is thrown when \c xN or \c yN is null. + */ + +/*!\function bool CellWidget::snapGrid() const + \behaviour This function returns \TRUE when the snap grid is enabled. + */ + +/*!\function bool CellWidget::selectionIsVisible() const + \behaviour This function returns \TRUE when the selection is visible. + */ + +/*!\function bool CellWidget::isSelected(const Occurrence& occurrence) const + \behaviour This function returns \TRUE when the specified occurrence is selected in this + porthole. + */ + +/*!\function bool CellWidget::isSelectable(const Occurrence& occurrence) const + \behaviour This function returns \TRUE when the specified occurrence can be selected in this + porthole (meaning that the occurrence is selectable and the view owning the + occurrence is the view bound to this porthole). + */ + +/*!\function bool CellWidget::highlightionIsVisible() const + \behaviour This function returns \TRUE when the highlightion is visible. + */ + +/*!\function bool CellWidget::isHighlighted(const Occurrence& occurrence) const + \behaviour This function returns \TRUE when the specified occurrence is highlighted in this + porthole. + */ + +/*!\function bool CellWidget::isHighlightable(const Occurrence& occurrence) const + \behaviour This function returns \TRUE when the specified occurrence can be highlighted in this + porthole (meaning that the occurrence is highlightable and the view owning the + occurrence is the view bound to this porthole). + */ +//@} + +//@{ +/*!\function void CellWidget::setBackgroundColor(const QColor& color) + \behaviour This function sets the background color of this porthole to the specified value. + \parameter color The new background color. + */ + +/*!\function void CellWidget::setForegroundColor(const QColor& color) + \behaviour This function sets the foreground color of this porthole to the specified value. + \parameter color The new foreground color. + */ + +/*!\function void CellWidget::setDoubleBuffering(bool enable) + \behaviour This function enables or disables the double buffering. + \parameter enable The new status. + */ + +/*!\function void CellWidget::setAutomaticScrolling(bool enable) + \behaviour This function enables or disables the automatic scrolling. + \parameter enable The new status. + \exception INVALID_REQUEST This exception is thrown when this porthole is a map + porthole. + */ + +/*!\function void CellWidget::setVisible(Layer* layer, bool visible) + \behaviour This function sets the visibility status of the specified layer in this porthole to + the specified value. + \parameter layer The layer for which the request is asked. + \parameter visible The new status. + */ + +/*!\function void CellWidget::setGridOrigin(const Point& origin) + \behaviour This function sets the origin of the grid of this porthole to the specified value. + \parameter origin The new grid origin. + */ + +/*!\function void CellWidget::setGridXStep(const Unit& step) + \behaviour This function sets the horizontal grid step of this porthole to the specified value. + \parameter step The new horizontal grid step. + \exception INVALID_REQUEST This exception is thrown when the \c step is null. + */ + +/*!\function void CellWidget::setGridYStep(const Unit& step) + \behaviour This function sets the vertical grid step of this porthole to the specified value. + \parameter step The new vertical grid step. + \exception INVALID_REQUEST This exception is thrown when the \c step is null. + */ + +/*!\function void CellWidget::setGridStep(const Unit& step) + \behaviour This function sets the horizontal and vertical grid steps of this porthole to the + specified value. + \parameter step The new horizontal and vertical grid step. + \exception INVALID_REQUEST This exception is thrown when the \c step is null. + */ + +/*!\function void CellWidget::setGridSteps(const Unit& xStep, const Unit& yStep) + \behaviour This function sets the horizontal and vertical grid step of this porthole to the + specified values. + \parameter xStep The new horizontal grid step. + \parameter yStep The new vertical grid step. + \exception INVALID_REQUEST This exception is thrown when \c xStep or \c yStep is null. + is null. + */ + +/*!\function void CellWidget::setGridDisplayThreshold(unsigned threshold) + \behaviour This function sets the grid display threshold of this porthole to the specified + value. + \parameter threshold The new display threshold. + \exception INVALID_REQUEST This exception is thrown when the new display threshold is too + small (less than 3 pixels). + */ + +/*!\function void CellWidget::setGridColor(const QColor& color) + \behaviour This function sets the grid color of this porthole to the specified value. + \parameter color The new grid color. + */ + +/*!\function void CellWidget::setGridVisible(bool visible) + \behaviour This function sets the visibility status of the grid in this porthole to the + specified value. + \parameter visible The new status. + */ + +/*!\function void CellWidget::setGridAxesVisible(bool visible) + \behaviour This function sets the visibility status of the grid axes in this porthole to the + specified value. + \parameter visible The new status. + */ + +/*!\function void CellWidget::setSnapGrid(bool enable) + \behaviour This function enables or disables the snap grid. + \parameter enable The new status. + */ + +/*!\function void CellWidget::setDisplayDepth(unsigned displayDepth) + \behaviour This function sets the display depth of this porthole to the specified value. + \parameter displayDepth The new display depth. + */ + +/*!\function void CellWidget::setDisplaySize(unsigned displaySize) + \behaviour This function sets the display size of this porthole to the specified value. + \parameter displaySize The new display size. + */ + +/*!\function void CellWidget::setSelectionLimit(unsigned limit) + \behaviour This function sets the selection limit of this porthole to the specified value. + \parameter limit The new selection limit (a null value indicating no limit). + */ + +/*!\function void CellWidget::setSelectionColor(const QColor& color) + \behaviour This function sets the selection color of this porthole to the specified value. + \parameter color The new selection color. + */ + +/*!\function void CellWidget::setSelectionVisible(bool visible) + \behaviour This function sets the visibility status of the selection in this porthole to the + specified value. + \parameter visible The new status. + */ + +/*!\function void CellWidget::setHighlightionLimit(unsigned limit) + \behaviour This function sets the highlightion limit of this porthole to the specified value. + \parameter limit The new highlightion limit (a null value indicating no limit). + */ + +/*!\function void CellWidget::setHighlightionVisible(bool visible) + \behaviour This function sets the visibility status of the highlightion in this porthole to the + specified value. + \parameter visible The new status. + */ + +/*!\function void CellWidget::setFont(const QFont& font) + \behaviour This function sets the font of this porthole to the specified value. + \parameter font The new font. + \note When a layer (or a ghost) is displayed, the graphical characteristics of this layer + (or this ghost) have been positionned. So, in principle, unless very specific needs, + there is no need to call this function. If you do so, dont forget to restore the + previous font after use. + */ + +/*!\function void CellWidget::setPen(const QPen& pen, double brightness) + \behaviour This function sets the pen of this porthole to the specified value. + \parameter pen The new pen. + \parameter brightness The brightness of the new pen. + \exception INVALID_REQUEST This exception is thrown if the brightness isn't in the range + [0.1 1.0]. + \notes When a layer (or a ghost) is displayed, the graphical characteristics of this layer + (or this ghost) have been positionned. So, in principle, unless very specific needs, + there is no need to call this function. If you do so, dont forget to restore the + previous pen after use. + */ + +/*!\function void CellWidget::setBrush(const QBrush& brush, double brightness) + \behaviour This function sets the brush of this porthole to the specified value. + \parameter brush The new brush. + \parameter brightness The brightness of the new brush. + \exception INVALID_REQUEST This exception is thrown if the brightness isn't in the range + [0.1 1.0]. + \notes When a layer (or a ghost) is displayed, the graphical characteristics of this layer + (or this ghost) have been positionned. So, in principle, unless very specific needs, + there is no need to call this function. If you do so, dont forget to restore the + previous brush after use. + */ + +/*!\function void CellWidget::setBrushOrigin(const QPoint& origin) + \behaviour This function sets the brush origin of this porthole to the specified value. + \parameter origin The new brush origin. + \note When a layer (or a ghost) is displayed, the graphical characteristics of this layer + (or this ghost) have been positionned. So, in principle, unless very specific needs, + there is no need to call this function. If you do so, dont forget to restore the + previous brush origin after use. + */ + +/*!\function void CellWidget::setTrackBox(TrackBox* track) + \behaviour This function bounds this porthole with the specified track box. + \parameter track The track box to bound with this porthole (can be \NULL). + */ +//@} + +//@{ +/*!\function void CellWidget::showAllLayers() + \behaviour This function sets the visibility status of all layers to \TRUE for this porthole. + */ + +/*!\function void CellWidget::hideAllLayers() + \behaviour This function sets the visibility status of all layers to \FALSE for this porthole. + */ + +/*!\function bool CellWidget::select(const Occurrence& occurrence) + \behaviour This function selects the specified occurrence in this porthole. + \parameter occurrence The occurrence to select. + */ + +/*!\function void CellWidget::unselect(const Occurrence& occurrence) + \behaviour This function unselects the specified occurrence from this porthole. + \parameter occurrence The occurrence to unselect. + */ + +/*!\function void CellWidget::clearSelection() + \behaviour This function clears the selection. + */ + +/*!\function bool CellWidget::highlight(const Occurrence& occurrence) + \behaviour This function highlights the specified occurrence in this porthole. + \parameter occurrence The occurrence to highlight. + */ + +/*!\function void CellWidget::unhighlight(const Occurrence& occurrence) + \behaviour This function unhighlights the specified occurrence from this porthole. + \parameter occurrence The occurrence to unhighlight. + */ + +/*!\function void CellWidget::clearHighlightion() + \behaviour This function clears the highlightion. + */ + +/*!\function void CellWidget::clearPeeks() + */ + +/*!\function void CellWidget::addPeek(const Box& box) + */ + +/*!\function void CellWidget::invalidate() + \behaviour This function post an invalidation region representing the visible part of the cell + view bound to this porthole. + \example + \code + * void MyCellWidget::refresh() + * { + * invalidate(); + * redraw(); + * } + \endcode + */ + +/*!\function void CellWidget::invalidate(const QRect& screenRect) + \behaviour This convenience function post an invalidation region representing the cell view + box corresponding to a given screen rect. + \parameter screenRect The screen rectangle to invalidate. + */ + +/*!\function void CellWidget::invalidate(const Box& box) + \behaviour This function post an invalidation region representing a given cell view box. + \parameter box The cell view box to invalidate. + */ + +/*!\function void CellWidget::fitToContent(unsigned screenMargin) + \behaviour This function makes the entire cell view visible in this porthole. + \parameter screenMargin Represent the minimal number of pixel we want around the bounding + box of the cell view. + */ + +/*!\function void CellWidget::reframe(double scale) + \behaviour This function sets the scale used to display the content of this porthole to the + specified value. + \parameter scale The new scale. + \examples + \code + * void MyCellWidget::zoomIn() + * { + * reframe(getScale() * 1.2)); + * redraw(); + * } + \endcode + \code + * void MyCellWidget::zoomOut() + * { + * reframe(getScale() / 1.2)); + * redraw(); + * } + \endcode + \note This function does nothing if the new scale is null. + */ + +/*!\function void CellWidget::reframe(const Point& center) + \behaviour This function sets the center of this porthole to the specified value. + \parameter center The new center. + \example + \code + * void MyCellWidget::pan(const Point& point) + * { + * reframe(point); + * redraw(); + * } + \endcode + */ + +/*!\function void CellWidget::reframe(const Point& center, double scale) + \behaviour This function sets the center and the scale of this porthole to the specified + values. + \parameter center The new center. + \parameter scale The new scale. + \note This function does nothing if the new scale is null. + */ + +/*!\function void CellWidget::reframe(const Box& box) + \behaviour This function allows you to map a cell view region into this porthole. + \remark The aspect ratios of the cell view region and the porthole can be differents + but the function ensures that the entire region will becomes visible. + \parameter box The region for which the request is asked. + \note This function does nothing if the region is inverted. + */ + +/*!\function void CellWidget::scroll(const Unit& dx, const Unit& dy) + \behaviour This function scrolls the content of this porthole of the specified quantities. + \parameter dx The horizontal quantity. + \parameter dy The verticaly quantity. + \note The display is updated immediately (it is not differed as it will be with the + reframe or fitToContent functions). So, it is not needed to call the redraw + function to see the effects. + */ + +/*!\function void CellWidget::redraw() + \behaviour This function is called or should be called to redraw the invalidated region. + \important Nothing is done if the invalidated region is empty. + */ + +/*!\function void CellWidget::abortStartedCommand() + \behaviour This function aborts the started command. + \important Nothing is done if no command has started. + */ + +/*!\function void CellWidget::drawLine(const Unit& xo, const Unit& yo, const Unit& xe, const Unit& ye) + \behaviour This function draws the line joining the points defined by the specified + coordinates with the current pen. + \parameter xo The abscissa of the line origin. + \parameter yo The ordinate of the line origin. + \parameter xe The abscissa of the line extremity. + \parameter ye The ordinate of the line extremity. + */ + +/*!\function void CellWidget::drawLine(const Point& origin, const Point& extremity) + \behaviour This function draws the line joining the specified points with the current pen. + \parameter origin The origin of the line. + \parameter extremity The extremity of the line. + */ + +/*!\function void CellWidget::drawPolyline(const Points& points) + \behaviour This function draws the polyline joining the specified points with the current pen. + \parameter points The collection of points defining the polyline. + */ + +/*!\function void CellWidget::drawRectangle(const Unit& xMin, const Unit& yMin, const Unit& xMax, const Unit& yMax) + \behaviour This function draws the rectangle defined by the specified values with the current + pen and brush. + \parameter xMin The left bound of the rectangle. + \parameter yMin The bottom bound of the rectangle. + \parameter xMax The right bound of the rectangle. + \parameter yMax The top bound of the rectangle. + */ + +/*!\function void CellWidget::drawRectangle(const Box& box) + \behaviour This convenience function behaves essentially like the above function. + \parameter box The box which defines the limits of the rectangle. + */ + +/*!\function void CellWidget::drawPolygon(const Points& points) + \behaviour This function draws the polygon defined by the specified points with the current + pen and brush. + \parameter points The collection of points which defining the polygon. + */ + +/*!\function void CellWidget::drawText(const Box& frame, const string& text, const Direction& direction) + \behaviour This function draws the string defined by the specified text, in the specified + direction, inside the specified frame, with the specified area style and using the + current font and pen. + \nn Texts are displayed using a fixed size font. The appearence of each text depend to + the scale factor of this porthole. The frame is used to control the display of a + text. So, to be really drawn, the screen dimensions of a text should be smaller than + the dimensions of the frame. + \parameter frame Defines the maximal dimensions of the text. + \parameter text Defines the string that should be drawn. + \parameter direction Defines the direction of the text. + */ + +/*!\function void CellWidget::drawText(const Box& frame, const Name& name, const Direction& direction) + \behaviour This convenience function behaves essentially like the above function. + \parameter frame Defines the maximal dimensions of the name. + \parameter name Defines the string that should be drawn. + \parameter direction Defines the direction of the text. + */ +//@} + + + +//CLOSE_MY_NAMESPACE +// +//USING_MY_NAMESPACE + +#endif // H_CellWidget + +// ************************************************************************************************* diff --git a/hurricane/src/viewer.xtof/LayersWidget.cpp b/hurricane/src/viewer.xtof/LayersWidget.cpp new file mode 100644 index 00000000..8038944a --- /dev/null +++ b/hurricane/src/viewer.xtof/LayersWidget.cpp @@ -0,0 +1,45 @@ +#include "DataBase.h" +#include "Technology.h" +#include "BasicLayer.h" +using namespace Hurricane; + +#include +#include +#include + +#include "LayersWidget.h" + +LayersWidget::LayersWidget(QWidget* parent) + : QWidget(parent), + widgets() +{ + DataBase* db = getDataBase(); + Technology* techno = db->getTechnology(); + QGridLayout* mainLayout = new QGridLayout; + + int line = 0; + for_each_basic_layer(basicLayer, techno->getBasicLayers()) { + QCheckBox* checkBox = new QCheckBox(); + widgets.insert(checkBox); + mainLayout->addWidget(checkBox, line, 0, Qt::AlignRight); + //connect(checkBox, SIGNAL(toggled(bool)), + // renderArea, SLOT(setAntialiased(bool))); + + string layerName = getString(basicLayer->getName()); + QLabel* label = new QLabel(tr(layerName.c_str())); + widgets.insert(label); + mainLayout->addWidget(label, line, 1, Qt::AlignRight); + ++line; + end_for; + } + setLayout(mainLayout); + setWindowTitle(tr("Layers")); +} + +LayersWidget::~LayersWidget() { + for (set::iterator wsit = widgets.begin(); + wsit != widgets.end(); + wsit++) { + delete *wsit; + } +} diff --git a/hurricane/src/viewer.xtof/LayersWidget.h b/hurricane/src/viewer.xtof/LayersWidget.h new file mode 100644 index 00000000..a797029b --- /dev/null +++ b/hurricane/src/viewer.xtof/LayersWidget.h @@ -0,0 +1,19 @@ +#ifndef LAYERS_WIDGET_H +#define LAYERS_WIDGET_H + +#include +using namespace std; + +#include + +class LayersWidget : public QWidget { + Q_OBJECT + + public : + LayersWidget(QWidget *parent = 0); + ~LayersWidget(); + private: + set widgets; +}; + +#endif diff --git a/hurricane/src/viewer.xtof/View.cpp b/hurricane/src/viewer.xtof/View.cpp new file mode 100644 index 00000000..1bfd319f --- /dev/null +++ b/hurricane/src/viewer.xtof/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 +// ****************************************************************************************************