mirror of
https://github.com/rizinorg/cutter.git
synced 2025-02-21 22:23:46 +00:00
Help not getting lost in empty parts of graph. (#1467)
* Limit how far outside image view can be moved * Allow using main view as overview by zooming out * Fix showBlock position calculation when zoomed out
This commit is contained in:
parent
f45badd026
commit
f1fa05e647
@ -519,6 +519,11 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
|||||||
|
|
||||||
qreal render_height = viewport()->size().height();
|
qreal render_height = viewport()->size().height();
|
||||||
|
|
||||||
|
// Stop rendering text when it's too small
|
||||||
|
if (charHeight * getViewScale() * p.device()->devicePixelRatioF() < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Render node text
|
// Render node text
|
||||||
auto x = blockX + (2 * charWidth);
|
auto x = blockX + (2 * charWidth);
|
||||||
int y = static_cast<int>(blockY + (2 * charWidth));
|
int y = static_cast<int>(blockY + (2 * charWidth));
|
||||||
@ -718,7 +723,7 @@ void DisassemblerGraphView::zoom(QPointF mouseRelativePos, double velocity)
|
|||||||
auto globalMouse = mouseRelativePos + getViewOffset();
|
auto globalMouse = mouseRelativePos + getViewOffset();
|
||||||
mouseRelativePos *= getViewScale();
|
mouseRelativePos *= getViewScale();
|
||||||
qreal newScale = getViewScale() * std::pow(1.25, velocity);
|
qreal newScale = getViewScale() * std::pow(1.25, velocity);
|
||||||
newScale = std::max(newScale, 0.3);
|
newScale = std::max(newScale, 0.05);
|
||||||
mouseRelativePos /= newScale;
|
mouseRelativePos /= newScale;
|
||||||
setViewScale(newScale);
|
setViewScale(newScale);
|
||||||
|
|
||||||
|
@ -111,7 +111,6 @@ void GraphGridLayout::CalculateLayout(std::unordered_map<ut64, GraphBlock> &bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare edge routing
|
// Prepare edge routing
|
||||||
//auto &entryb = layoutState.grid_blocks[entry];
|
|
||||||
int col_count = 1;
|
int col_count = 1;
|
||||||
int row_count = 0;
|
int row_count = 0;
|
||||||
for (const auto &blockIt : layoutState.grid_blocks) {
|
for (const auto &blockIt : layoutState.grid_blocks) {
|
||||||
@ -183,30 +182,30 @@ void GraphGridLayout::CalculateLayout(std::unordered_map<ut64, GraphBlock> &bloc
|
|||||||
row_y.assign(row_count, 0);
|
row_y.assign(row_count, 0);
|
||||||
std::vector<int> col_edge_x(col_count + 1);
|
std::vector<int> col_edge_x(col_count + 1);
|
||||||
std::vector<int> row_edge_y(row_count + 1);
|
std::vector<int> row_edge_y(row_count + 1);
|
||||||
int x = layoutConfig.block_horizontal_margin * 2;
|
int x = layoutConfig.block_horizontal_margin;
|
||||||
for (int i = 0; i < col_count; i++) {
|
for (int i = 0; i <= col_count; i++) {
|
||||||
col_edge_x[i] = x;
|
col_edge_x[i] = x;
|
||||||
x += layoutConfig.block_horizontal_margin * col_edge_count[i];
|
x += layoutConfig.block_horizontal_margin * col_edge_count[i];
|
||||||
col_x[i] = x;
|
if (i < col_count) {
|
||||||
x += col_width[i];
|
col_x[i] = x;
|
||||||
|
x += col_width[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int y = layoutConfig.block_vertical_margin * 2;
|
int y = layoutConfig.block_vertical_margin;
|
||||||
for (int i = 0; i < row_count; i++) {
|
for (int i = 0; i <= row_count; i++) {
|
||||||
row_edge_y[i] = y;
|
row_edge_y[i] = y;
|
||||||
// TODO: The 1 when row_edge_count is 0 is not needed on the original.. not sure why it's required for us
|
|
||||||
if (!row_edge_count[i]) {
|
if (!row_edge_count[i]) {
|
||||||
|
// prevent 2 blocks being put on top of each other without any space
|
||||||
row_edge_count[i] = 1;
|
row_edge_count[i] = 1;
|
||||||
}
|
}
|
||||||
y += layoutConfig.block_vertical_margin * row_edge_count[i];
|
y += layoutConfig.block_vertical_margin * row_edge_count[i];
|
||||||
row_y[i] = y;
|
if (i < row_count) {
|
||||||
y += row_height[i];
|
row_y[i] = y;
|
||||||
|
y += row_height[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
col_edge_x[col_count] = x;
|
width = x + (layoutConfig.block_horizontal_margin);
|
||||||
row_edge_y[row_count] = y;
|
height = y + (layoutConfig.block_vertical_margin);
|
||||||
width = x + (layoutConfig.block_horizontal_margin * 2) + (layoutConfig.block_horizontal_margin *
|
|
||||||
col_edge_count[col_count]);
|
|
||||||
height = y + (layoutConfig.block_vertical_margin * 2) + (layoutConfig.block_vertical_margin *
|
|
||||||
row_edge_count[row_count]);
|
|
||||||
|
|
||||||
//Compute node positions
|
//Compute node positions
|
||||||
for (auto &blockIt : blocks) {
|
for (auto &blockIt : blocks) {
|
||||||
|
@ -145,8 +145,7 @@ void GraphView::beginMouseDrag(QMouseEvent *event)
|
|||||||
|
|
||||||
void GraphView::setViewOffset(QPoint offset)
|
void GraphView::setViewOffset(QPoint offset)
|
||||||
{
|
{
|
||||||
this->offset = offset;
|
setViewOffsetInternal(offset);
|
||||||
emit viewOffsetChanged(offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::setViewScale(qreal scale)
|
void GraphView::setViewScale(qreal scale)
|
||||||
@ -200,12 +199,11 @@ void GraphView::paintEvent(QPaintEvent *)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!qFuzzyCompare(getCacheDevicePixelRatioF(), getRequiredCacheDevicePixelRatioF())
|
if (!qFuzzyCompare(getCacheDevicePixelRatioF(), getRequiredCacheDevicePixelRatioF())
|
||||||
|| getCacheSize() != getRequiredCacheSize()) {
|
|| getCacheSize() != getRequiredCacheSize()) {
|
||||||
setCacheDirty();
|
setCacheDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cacheWasDirty = cacheDirty;
|
if (cacheDirty) {
|
||||||
if(cacheDirty) {
|
|
||||||
paintGraphCache();
|
paintGraphCache();
|
||||||
cacheDirty = false;
|
cacheDirty = false;
|
||||||
}
|
}
|
||||||
@ -228,6 +226,30 @@ void GraphView::paintEvent(QPaintEvent *)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphView::clampViewOffset()
|
||||||
|
{
|
||||||
|
const qreal edgeFraction = 0.25;
|
||||||
|
qreal edgeX = edgeFraction * (viewport()->width() / current_scale);
|
||||||
|
qreal edgeY = edgeFraction * (viewport()->height() / current_scale);
|
||||||
|
offset.rx() = std::max(std::min(qreal(offset.x()), width - edgeX),
|
||||||
|
- viewport()->width() / current_scale + edgeX);
|
||||||
|
offset.ry() = std::max(std::min(qreal(offset.y()), height - edgeY),
|
||||||
|
- viewport()->height() / current_scale + edgeY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphView::setViewOffsetInternal(QPoint pos, bool emitSignal)
|
||||||
|
{
|
||||||
|
offset = pos;
|
||||||
|
clampViewOffset();
|
||||||
|
if (emitSignal)
|
||||||
|
emit viewOffsetChanged(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphView::addViewOffset(QPoint move, bool emitSignal)
|
||||||
|
{
|
||||||
|
setViewOffsetInternal(offset + move, emitSignal);
|
||||||
|
}
|
||||||
|
|
||||||
void GraphView::paintGraphCache()
|
void GraphView::paintGraphCache()
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
@ -248,13 +270,14 @@ void GraphView::paintGraphCache()
|
|||||||
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
resizeTex = true;
|
resizeTex = true;
|
||||||
} else if(cacheSize != viewport()->size()) {
|
} else if (cacheSize != viewport()->size()) {
|
||||||
gl->glBindTexture(GL_TEXTURE_2D, cacheTexture);
|
gl->glBindTexture(GL_TEXTURE_2D, cacheTexture);
|
||||||
resizeTex = true;
|
resizeTex = true;
|
||||||
}
|
}
|
||||||
if (resizeTex) {
|
if (resizeTex) {
|
||||||
cacheSize = viewport()->size();
|
cacheSize = viewport()->size();
|
||||||
gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport()->width(), viewport()->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport()->width(), viewport()->height(), 0, GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE, nullptr);
|
||||||
gl->glGenFramebuffers(1, &cacheFBO);
|
gl->glGenFramebuffers(1, &cacheFBO);
|
||||||
gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO);
|
gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO);
|
||||||
gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cacheTexture, 0);
|
gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cacheTexture, 0);
|
||||||
@ -314,6 +337,9 @@ void GraphView::paintGraphCache()
|
|||||||
EdgeConfiguration ec = edgeConfiguration(block, &blocks[edge.target]);
|
EdgeConfiguration ec = edgeConfiguration(block, &blocks[edge.target]);
|
||||||
QPen pen(ec.color);
|
QPen pen(ec.color);
|
||||||
pen.setWidth(pen.width() / ec.width_scale);
|
pen.setWidth(pen.width() / ec.width_scale);
|
||||||
|
if (pen.width() * current_scale < 2) {
|
||||||
|
pen.setWidth(0);
|
||||||
|
}
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
p.setBrush(ec.color);
|
p.setBrush(ec.color);
|
||||||
p.drawPolyline(polyline);
|
p.drawPolyline(polyline);
|
||||||
@ -358,6 +384,7 @@ void GraphView::centerX(bool emitSignal)
|
|||||||
{
|
{
|
||||||
offset.rx() = -((viewport()->width() - width * current_scale) / 2);
|
offset.rx() = -((viewport()->width() - width * current_scale) / 2);
|
||||||
offset.rx() /= current_scale;
|
offset.rx() /= current_scale;
|
||||||
|
clampViewOffset();
|
||||||
if (emitSignal) {
|
if (emitSignal) {
|
||||||
emit viewOffsetChanged(offset);
|
emit viewOffsetChanged(offset);
|
||||||
}
|
}
|
||||||
@ -367,6 +394,7 @@ void GraphView::centerY(bool emitSignal)
|
|||||||
{
|
{
|
||||||
offset.ry() = -((viewport()->height() - height * current_scale) / 2);
|
offset.ry() = -((viewport()->height() - height * current_scale) / 2);
|
||||||
offset.ry() /= current_scale;
|
offset.ry() /= current_scale;
|
||||||
|
clampViewOffset();
|
||||||
if (emitSignal) {
|
if (emitSignal) {
|
||||||
emit viewOffsetChanged(offset);
|
emit viewOffsetChanged(offset);
|
||||||
}
|
}
|
||||||
@ -388,8 +416,9 @@ void GraphView::showBlock(GraphBlock *block)
|
|||||||
if (height * current_scale <= viewport()->height()) {
|
if (height * current_scale <= viewport()->height()) {
|
||||||
centerY(false);
|
centerY(false);
|
||||||
} else {
|
} else {
|
||||||
offset.ry() = block->y - 30;
|
offset.ry() = block->y - 35 / current_scale;
|
||||||
}
|
}
|
||||||
|
clampViewOffset();
|
||||||
emit viewOffsetChanged(offset);
|
emit viewOffsetChanged(offset);
|
||||||
blockTransitionedTo(block);
|
blockTransitionedTo(block);
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
@ -481,9 +510,7 @@ void GraphView::mousePressEvent(QMouseEvent *event)
|
|||||||
void GraphView::mouseMoveEvent(QMouseEvent *event)
|
void GraphView::mouseMoveEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (scroll_mode) {
|
if (scroll_mode) {
|
||||||
offset.rx() += (scroll_base_x - event->x()) / current_scale;
|
addViewOffset(QPoint(scroll_base_x - event->x(), scroll_base_y - event->y()) / current_scale);
|
||||||
offset.ry() += (scroll_base_y - event->y()) / current_scale;
|
|
||||||
emit viewOffsetChanged(offset);
|
|
||||||
scroll_base_x = event->x();
|
scroll_base_x = event->x();
|
||||||
scroll_base_y = event->y();
|
scroll_base_y = event->y();
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
@ -508,7 +535,7 @@ void GraphView::mouseDoubleClickEvent(QMouseEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::keyPressEvent(QKeyEvent* event)
|
void GraphView::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
const int delta = static_cast<int>(30.0 / current_scale);
|
const int delta = static_cast<int>(30.0 / current_scale);
|
||||||
int dx = 0, dy = 0;
|
int dx = 0, dy = 0;
|
||||||
@ -529,9 +556,7 @@ void GraphView::keyPressEvent(QKeyEvent* event)
|
|||||||
QAbstractScrollArea::keyPressEvent(event);
|
QAbstractScrollArea::keyPressEvent(event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
offset.rx() += dx;
|
addViewOffset(QPoint(dx, dy));
|
||||||
offset.ry() += dy;
|
|
||||||
emit viewOffsetChanged(offset);
|
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
@ -559,11 +584,8 @@ void GraphView::wheelEvent(QWheelEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QPoint delta = -event->angleDelta();
|
QPoint delta = -event->angleDelta();
|
||||||
|
|
||||||
delta /= current_scale;
|
delta /= current_scale;
|
||||||
offset += delta;
|
addViewOffset(delta);
|
||||||
emit viewOffsetChanged(offset);
|
|
||||||
|
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,10 @@ protected:
|
|||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
|
void clampViewOffset();
|
||||||
|
void setViewOffsetInternal(QPoint pos, bool emitSignal = true);
|
||||||
|
void addViewOffset(QPoint move, bool emitSignal = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void centerX(bool emitSignal);
|
void centerX(bool emitSignal);
|
||||||
void centerY(bool emitSignal);
|
void centerY(bool emitSignal);
|
||||||
|
Loading…
Reference in New Issue
Block a user