Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ configuration: Release
install:
- git submodule update --init
- cd dependencies
- download-dependencies.py discount qwt zeromq cppzmq msgpack-c katex tclap fmi4c xerces asio zlib libzip dcplib
- download-dependencies.py discount qwt zeromq cppzmq msgpack-c katex tclap fmi4c xerces asio zlib libzip dcplib ssp4c
- cd ..
build_script:
# Remove sh.exe from PATH so that CMake works
Expand All @@ -28,6 +28,7 @@ build_script:
- setupQwt.bat
- setupZeroMQ.bat
- setupMsgpack.bat
- setupSsp4c.bat
- call setHopsanBuildPaths.bat
- cd ..
- mkdir build
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/ci-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Download dependencies
shell: cmd
working-directory: dependencies
run: python download-dependencies.py discount tclap qwt fmi4c xerces asio zlib libzip dcplib
run: python download-dependencies.py discount tclap qwt fmi4c xerces asio zlib libzip dcplib ssp4c

- name: Build dependencies
shell: cmd
Expand All @@ -53,6 +53,7 @@ jobs:
call setupXerces.bat
call setupDCPLib.bat
call setupQwt.bat
call setupSsp4c.bat

- name: Configure
working-directory: hopsan-build
Expand Down Expand Up @@ -94,7 +95,7 @@ jobs:
- name: Download dependencies
shell: bash
working-directory: dependencies
run: ./download-dependencies.py discount tclap fmi4c xerces asio dcplib libzip qwt
run: ./download-dependencies.py discount tclap fmi4c xerces asio dcplib libzip qwt ssp4c

- name: Build dependencies
shell: bash
Expand All @@ -107,6 +108,7 @@ jobs:
./setupXerces.sh
./setupDCPLib.sh
./setupQwt.sh
./setupSsp4c.sh

- name: Configure
working-directory: hopsan-build
Expand Down
4 changes: 2 additions & 2 deletions HopsanCore/include/HopsanCoreGitVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
// $Id$
#ifndef HOPSANCOREGITVERSION_H_INCLUDED
#define HOPSANCOREGITVERSION_H_INCLUDED
#define HOPSANCORE_COMMIT_HASH 250596a1b
#define HOPSANCORE_COMMIT_TIMESTAMP 20200515.1608
#define HOPSANCORE_COMMIT_HASH f6800a955
#define HOPSANCORE_COMMIT_TIMESTAMP 20260217.1325
#endif
3 changes: 2 additions & 1 deletion HopsanGUI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/discount.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/katex.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/libzip.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/xerces.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/ssp4c.cmake)

set(target_name hopsangui)

Expand All @@ -39,7 +40,7 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
endif()

target_link_libraries(${target_name} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Xml Qt5::Svg Qt5::Network Qt5::Test Qt5::PrintSupport
qwt hopsancore hopsangeneratorgui symhop ops hopsandcp xercesc )
qwt hopsancore hopsangeneratorgui symhop ops hopsandcp xercesc ssp4c )
if(UNIX)
target_link_libraries(${target_name} Qt5::WebEngineWidgets)
endif()
Expand Down
12 changes: 11 additions & 1 deletion HopsanGUI/GUIConnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,13 @@ QPointF Connector::getEndPoint()
return mPoints.last();
}


//! @brief Returns all points of the connector
QVector<QPointF> Connector::getPoints() const
{
return mPoints;
}

//! @brief Returns the name of the start port of a connector
//! @see getEndPortName()
QString Connector::getStartPortName() const
Expand Down Expand Up @@ -1258,8 +1265,11 @@ void Connector::setPointsAndGeometries(const QVector<QPointF> &rPoints, const QS
mGeometries.push_back(Horizontal);
else if(mPoints[i].y() == mPoints[i+1].y())
mGeometries.push_back(Vertical);
else
else {
qDebug() << mPoints[i].x() << " != " << mPoints[i+1].x();
qDebug() << mPoints[i].y() << " != " << mPoints[i+1].y();
mGeometries.push_back(Diagonal);
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions HopsanGUI/GUIConnector.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class Connector : public QGraphicsWidget
void setPointsAndGeometries(const QVector<QPointF> &rPoints, const QStringList &rGeometries);
QPointF getStartPoint();
QPointF getEndPoint();
QVector<QPointF> getPoints() const;
ConnectorLine *getLine(int line);
ConnectorLine *getLastLine();
int getNumberOfLines();
Expand Down
267 changes: 267 additions & 0 deletions HopsanGUI/GUIObjects/GUIComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "PlotWindow.h"
#include "Widgets/ModelWidget.h"
#include "LibraryHandler.h"
#include "UndoStack.h"


Component::Component(QPointF position, double rotation, ModelObjectAppearance* pAppearanceData, SystemObject *pParentSystem, SelectionStatusEnumT startSelected, GraphicsTypeEnumT gfxType)
Expand Down Expand Up @@ -461,6 +462,272 @@ QDomElement Component::saveGuiDataToDomElement(QDomElement &rDomElement)
}


//========== ResizableComponent ==========

ResizableComponent::ResizableComponent(QPointF position, double rotation, ModelObjectAppearance* pAppearanceData, SystemObject *pParentSystem, SelectionStatusEnumT startSelected, GraphicsTypeEnumT gfxType)
: Component(position, rotation, pAppearanceData, pParentSystem, startSelected, gfxType)
{
// Initialize resizing members
mResizeTop = false;
mResizeBottom = false;
mResizeLeft = false;
mResizeRight = false;
mIsResizing = false;
mWidthBeforeResize = 0;
mHeightBeforeResize = 0;

// Hide the icon and create a rectangle instead
mpIcon->hide();

// Create rectangle with default size
mpRect = new QGraphicsRectItem(0, 0, 100, 80, this);
QPen borderPen;
borderPen.setWidth(2);
borderPen.setColor(Qt::black);
mpRect->setPen(borderPen);
mpRect->setBrush(QBrush(Qt::lightGray));
mpRect->show();

// Create text item in the center
mpText = new QGraphicsTextItem(this);
mpText->setPlainText("Resizable");
mpText->setAcceptHoverEvents(false);
QFont textFont = mpText->font();
textFont.setPointSize(10);
mpText->setFont(textFont);
mpText->show();

// Center text in rectangle
QRectF textRect = mpText->boundingRect();
mpText->setPos((100 - textRect.width()) / 2, (80 - textRect.height()) / 2);

// Resize the widget to match rectangle size
this->resize(mpRect->boundingRect().width(), mpRect->boundingRect().height());
this->refreshSelectionBoxSize();
}


//! @brief Refreshes the appearance of the object
void ResizableComponent::refreshAppearance()
{
//! @todo should make sure we only do this if we really need to resize (after icon change)
QPointF centerPos = this->getCenterPos(); //Remember center pos for resize
this->setCenterPos(centerPos); //Re-set center pos after resize

this->refreshDisplayName();
this->refreshExternalPortsAppearanceAndPosition();
}

//! @brief Set the outline color of the rectangle
void ResizableComponent::setRectColor(const QColor &color)
{
if(mpRect)
{
QPen pen = mpRect->pen();
pen.setColor(color);
mpRect->setPen(pen);
}
}


//! @brief Set the fill color of the rectangle
void ResizableComponent::setRectFillColor(const QColor &color)
{
if(mpRect)
{
mpRect->setBrush(QBrush(color));
}
}


//! @brief Set the text in the center of the rectangle
void ResizableComponent::setText(const QString &text)
{
if(mpText)
{
mpText->setPlainText(text);
// Re-center the text
QRectF rectSize = mpRect->rect();
QRectF textRect = mpText->boundingRect();
mpText->setPos((rectSize.width() - textRect.width()) / 2, (rectSize.height() - textRect.height()) / 2);
}
}


//! @brief Set the component size (width and height)
void ResizableComponent::setComponentSize(double width, double height)
{
if(width > 0 && height > 0 && mpRect)
{
this->prepareGeometryChange();
mpRect->setRect(0, 0, width, height);
this->resize(width, height);
refreshSelectionBoxSize();

// Refresh port positions for the new component size
for(int i = 0; i < mPortListPtrs.size(); ++i)
{
createRefreshExternalPort(mPortListPtrs[i]->getName());
}
}
}


//! @brief Refresh the selection box to match rectangle size
void ResizableComponent::refreshSelectionBoxSize()
{
mpSelectionBox->setSize(0.0, 0.0, mpRect->rect().width(), mpRect->rect().height());
}


//! @brief Handle hover movement for edge-based resizing
void ResizableComponent::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
Component::hoverMoveEvent(event);

this->setCursor(Qt::ArrowCursor);
mResizeLeft = false;
mResizeRight = false;
mResizeTop = false;
mResizeBottom = false;

int resLim = 5;

if(event->pos().x() > boundingRect().left() && event->pos().x() < boundingRect().left()+resLim)
{
mResizeLeft = true;
}
if(event->pos().x() > boundingRect().right()-resLim && event->pos().x() < boundingRect().right())
{
mResizeRight = true;
}
if(event->pos().y() > boundingRect().top() && event->pos().y() < boundingRect().top()+resLim)
{
mResizeTop = true;
}
if(event->pos().y() > boundingRect().bottom()-resLim && event->pos().y() < boundingRect().bottom())
{
mResizeBottom = true;
}

if( (mResizeLeft && mResizeTop) || (mResizeRight && mResizeBottom) )
this->setCursor(Qt::SizeFDiagCursor);
else if( (mResizeTop && mResizeRight) || (mResizeBottom && mResizeLeft) )
this->setCursor(Qt::SizeBDiagCursor);
else if(mResizeLeft || mResizeRight)
this->setCursor(Qt::SizeHorCursor);
else if(mResizeTop || mResizeBottom)
this->setCursor(Qt::SizeVerCursor);
}


//! @brief Handle mouse press for starting resize operation
void ResizableComponent::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(mResizeLeft || mResizeRight || mResizeTop || mResizeBottom)
{
mPosBeforeResize = this->pos();
mWidthBeforeResize = boundingRect().width();
mHeightBeforeResize = boundingRect().height();
mIsResizing = true;
}
else
{
mIsResizing = false;
}
Component::mousePressEvent(event);
}


//! @brief Handle mouse move for resizing the component
void ResizableComponent::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
Component::mouseMoveEvent(event);

if (getModelLockLevel()==NotLocked && mIsResizing)
{
// Calculate the desired new width and height
double desiredWidth = mWidthBeforeResize;
double desiredHeight = mHeightBeforeResize;
QPointF newPos = mPosBeforeResize;

// Handle left resize
if(mResizeLeft)
{
double deltaX = this->pos().x() - mPosBeforeResize.x();
desiredWidth = qMax(5.0, mWidthBeforeResize - deltaX);
newPos.setX(mPosBeforeResize.x() + (mWidthBeforeResize - desiredWidth));
}
// Handle right resize
else if(mResizeRight)
{
double deltaX = this->pos().x() - mPosBeforeResize.x();
desiredWidth = qMax(5.0, mWidthBeforeResize + deltaX);
newPos.setX(mPosBeforeResize.x());
}

// Handle top resize
if(mResizeTop)
{
double deltaY = this->pos().y() - mPosBeforeResize.y();
desiredHeight = qMax(5.0, mHeightBeforeResize - deltaY);
newPos.setY(mPosBeforeResize.y() + (mHeightBeforeResize - desiredHeight));
}
// Handle bottom resize
else if(mResizeBottom)
{
double deltaY = this->pos().y() - mPosBeforeResize.y();
desiredHeight = qMax(5.0, mHeightBeforeResize + deltaY);
newPos.setY(mPosBeforeResize.y());
}

// Update rectangle size based on the desired new width and height
this->prepareGeometryChange();
mpRect->setRect(0, 0, desiredWidth, desiredHeight);
this->setPos(newPos);

// Resize the widget to match the rectangle size
this->resize(desiredWidth, desiredHeight);

// Re-center the text
if(mpText)
{
QRectF textRect = mpText->boundingRect();
mpText->setPos((desiredWidth - textRect.width()) / 2, (desiredHeight - textRect.height()) / 2);
}

refreshSelectionBoxSize();
mpSelectionBox->setActive();
}
}


//! @brief Handle mouse release to register resize in undo stack
void ResizableComponent::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
Component::mouseReleaseEvent(event);

if(mResizeLeft || mResizeRight || mResizeTop || mResizeBottom)
{
// Refresh port positions for the new component size
for(int i = 0; i < mPortListPtrs.size(); ++i)
{
createRefreshExternalPort(mPortListPtrs[i]->getName());
}

if(mWidthBeforeResize != boundingRect().width() || mHeightBeforeResize != boundingRect().height())
{
mpParentSystemObject->getUndoStackPtr()->newPost();
}
mResizeLeft = false;
mResizeRight = false;
mResizeTop = false;
mResizeBottom = false;
mIsResizing = false;
}
}


void ScopeComponent::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsWidget::mouseDoubleClickEvent(event);
Expand Down
Loading
Loading