ACAV f0ba4b7c9529
Abstract Syntax Tree (AST) visualization tool for C, C++, and Objective-C
Loading...
Searching...
No Matches
NodeCycleWidget.cpp
1/*$!{
2* Aurora Clang AST Viewer (ACAV)
3*
4* Copyright (c) 2026 Min Liu
5* Copyright (c) 2026 Michael David Adams
6*
7* SPDX-License-Identifier: GPL-2.0-or-later
8*
9* This program is free software; you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by
11* the Free Software Foundation; either version 2 of the License, or
12* (at your option) any later version.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License along
20* with this program; if not, see <https://www.gnu.org/licenses/>.
21}$!*/
22
23#include "ui/NodeCycleWidget.h"
24#include "core/AstNode.h"
25#include <QHBoxLayout>
26#include <QVBoxLayout>
27
28namespace acav {
29
30NodeCycleWidget::NodeCycleWidget(QWidget *parent) : QWidget(parent) {
31 // Make this a popup window
32 setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
33 setAttribute(Qt::WA_DeleteOnClose, false);
34
35 // Create UI elements
36 infoLabel_ = new QLabel(this);
37 prevButton_ = new QPushButton("Previous", this);
38 nextButton_ = new QPushButton("Next", this);
39 closeButton_ = new QPushButton("Close", this);
40
41 // Layout
42 QVBoxLayout *mainLayout = new QVBoxLayout(this);
43 mainLayout->addWidget(infoLabel_);
44
45 QHBoxLayout *buttonLayout = new QHBoxLayout();
46 buttonLayout->addWidget(prevButton_);
47 buttonLayout->addWidget(nextButton_);
48 buttonLayout->addWidget(closeButton_);
49 mainLayout->addLayout(buttonLayout);
50
51 setLayout(mainLayout);
52
53 // Connect signals
54 connect(prevButton_, &QPushButton::clicked, this, &NodeCycleWidget::onPrevious);
55 connect(nextButton_, &QPushButton::clicked, this, &NodeCycleWidget::onNext);
56 connect(closeButton_, &QPushButton::clicked, this, &NodeCycleWidget::onClose);
57
58 // Style — handled by NodeCycleWidget selector in style.qss
59}
60
61void NodeCycleWidget::showMatches(const std::vector<AstViewNode *> &matches,
62 const QPoint &clickPos) {
63 if (matches.empty()) {
64 return;
65 }
66
67 matches_ = matches;
68 currentIndex_ = 0;
69
70 updateDisplay();
71
72 // Position near click
73 move(clickPos + QPoint(10, 10));
74 show();
75 raise();
76 activateWindow();
77
78 // Emit first node
79 emit nodeSelected(matches_[currentIndex_]);
80}
81
82void NodeCycleWidget::onNext() {
83 if (matches_.empty()) {
84 return;
85 }
86
87 currentIndex_ = (currentIndex_ + 1) % matches_.size();
88 updateDisplay();
89 emit nodeSelected(matches_[currentIndex_]);
90}
91
92void NodeCycleWidget::onPrevious() {
93 if (matches_.empty()) {
94 return;
95 }
96
97 if (currentIndex_ == 0) {
98 currentIndex_ = matches_.size() - 1;
99 } else {
100 --currentIndex_;
101 }
102
103 updateDisplay();
104 emit nodeSelected(matches_[currentIndex_]);
105}
106
107void NodeCycleWidget::onClose() {
108 hide();
109 emit closed();
110}
111
112void NodeCycleWidget::updateDisplay() {
113 if (matches_.empty()) {
114 return;
115 }
116
117 AstViewNode *node = matches_[currentIndex_];
118 const AcavJson &props = node->getProperties();
119
120 QString kind = "<unknown>";
121 if (props.contains("kind") && props.at("kind").is_string()) {
122 kind = QString::fromStdString(
123 props.at("kind").get<InternedString>().str());
124 }
125 QString name;
126 if (props.contains("name")) {
127 name = QString::fromStdString(props["name"].get<InternedString>().str());
128 }
129
130 QString info = QString("Match %1 of %2: %3")
131 .arg(currentIndex_ + 1)
132 .arg(matches_.size())
133 .arg(kind);
134
135 if (!name.isEmpty()) {
136 info += QString(" (%1)").arg(name);
137 }
138
139 infoLabel_->setText(info);
140
141 // Enable/disable buttons
142 prevButton_->setEnabled(matches_.size() > 1);
143 nextButton_->setEnabled(matches_.size() > 1);
144}
145
146} // namespace acav
AST data structures and memory management.
nlohmann::basic_json< std::map, std::vector, InternedString, bool, int64_t, uint64_t, double, std::allocator, nlohmann::adl_serializer, std::vector< uint8_t > > AcavJson
Custom JSON type using InternedString for automatic string deduplication.
Definition AstNode.h:51
Popup widget for cycling through overlapping AST nodes.
void nodeSelected(AstViewNode *node)
Emitted when user navigates to a node.
void showMatches(const std::vector< AstViewNode * > &matches, const QPoint &clickPos)
Show widget with list of matches.