Skip to content

Commit 9a35b28

Browse files
authored
Merge pull request #38 from sandbox-science/update/ui
UI Design
2 parents 1d4d292 + d232632 commit 9a35b28

File tree

10 files changed

+307
-19
lines changed

10 files changed

+307
-19
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
CodeAstra is a modern, extensible, and lightweight code editor built using C++ and Qt6, designed to offer a fast, customizable, and feature-rich development experience. Inspired by NeoVim and VSCode, it **will** provide efficient file navigation, syntax highlighting, and a powerful plugin system, making it an ideal choice for developers who need speed, flexibility, and control. With a focus on performance and usability, the editor **will** support split views, an integrated terminal, customizable key bindings, and seamless Git integration, catering to both beginners and power users.
3030

31+
![CodeAstra Demo](assets/demo_ui.png)
32+
3133
> [!TIP]
3234
>
3335
> Join the [Matrix Server](https://matrix.to/#/#codeastra:matrix.org) for CodeAstra development log and discussion.

assets/demo_ui.png

991 KB
Loading

config/cxx.syntax.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ keywords:
55
- regex: "\\b(char|class|const|double|enum|explicit|friend|inline|int|long|namespace|operator|private|protected|public|short|signals|signed|slots|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|foreach)\\b"
66
color: "#003478" # Dark Blue
77
bold: true
8-
- regex: "\\b(for|while|do|if|else)\\b"
8+
- regex: "\\b(for|while|do|if|else|return)\\b"
99
color: "#D9001D" # Bright Red
1010
- regex: "(?<!\\w)#include(?!\\w)"
1111
color: "#800080" # Purple

include/Tree.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,7 @@ class Tree : public QObject
4242
std::unique_ptr<QFileIconProvider> m_iconProvider;
4343
std::unique_ptr<QFileSystemModel> m_model;
4444
std::unique_ptr<QTreeView> m_tree;
45+
46+
protected:
47+
bool eventFilter(QObject *obj, QEvent *event) override;
4548
};

resources.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<RCC>
22
<qresource prefix="/">
33
<file>resources/app_icon.png</file>
4+
<file>resources/themes/dark.qss</file>
45
</qresource>
56
</RCC>

resources/themes/dark.qss

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
* {
2+
font-family: 'Fira Code', 'Menlo', 'Monaco', "Consolas", "Courier New", "Monospace";
3+
font-size: 13pt;
4+
}
5+
6+
QMainWindow {
7+
background-color: #1a1a1a;
8+
color: #ffffff;
9+
border-radius: 8px;
10+
}
11+
12+
QStatusBar {
13+
background-color: #252525;
14+
color: #e0e0e0;
15+
border-top: 1px solid #383838;
16+
font-size: 11pt;
17+
padding: 6px 10px;
18+
}
19+
20+
QTreeView {
21+
background-color: #1e1e1e;
22+
color: #e0e0e0;
23+
padding: 6px;
24+
border-radius: 6px;
25+
}
26+
27+
QTreeView::item {
28+
padding: 2px 4px;
29+
}
30+
31+
QTreeView::item:selected {
32+
background: #2b5ea3;
33+
color: white;
34+
border-radius: 4px;
35+
}
36+
37+
QTreeView::item:hover {
38+
background: #3c3c3c;
39+
}
40+
41+
QTreeView::item:focus {
42+
outline: none;
43+
}
44+
45+
QScrollBar:vertical, QScrollBar:horizontal {
46+
background: #1e1e1e;
47+
width: 12px;
48+
margin: 0px;
49+
}
50+
51+
QScrollBar::handle {
52+
background: #666666;
53+
border-radius: 6px;
54+
margin: 2px;
55+
}
56+
57+
QScrollBar::handle:hover {
58+
background: #888888;
59+
}
60+
61+
QMenuBar {
62+
background-color: #252525;
63+
color: white;
64+
padding: 6px 10px;
65+
}
66+
67+
QMenu {
68+
background-color: #2d2d2d;
69+
color: white;
70+
border: 1px solid #444444;
71+
border-radius: 6px;
72+
padding: 4px;
73+
}
74+
75+
QMenu::item {
76+
padding: 6px 20px;
77+
border-radius: 4px;
78+
}
79+
80+
QMenu::item:selected {
81+
background-color: #3c3c3c;
82+
}
83+
84+
QMenu::item:hover {
85+
background-color: #454545;
86+
}
87+
88+
QPlainTextEdit, QLineEdit {
89+
background-color: #1e1e1e;
90+
color: #e0e0e0;
91+
border-radius: 6px;
92+
padding: 8px;
93+
border: 1px solid #333333;
94+
}
95+
96+
QPlainTextEdit {
97+
selection-background-color: #2b5ea3;
98+
selection-color: white;
99+
}
100+
101+
QPlainTextEdit:focus, QTreeView:focus {
102+
border: 1px solid #3d75c2;
103+
}
104+
105+
QTabBar::tab {
106+
background: #2d2d2d;
107+
color: #d4d4d4;
108+
padding: 8px 16px;
109+
border-top-left-radius: 6px;
110+
border-top-right-radius: 6px;
111+
margin-right: 2px;
112+
}
113+
114+
QTabBar::tab:selected {
115+
background: #1e1e1e;
116+
color: white;
117+
border-top: 2px solid #3d75c2;
118+
}
119+
120+
QTabBar::tab:hover {
121+
background: #353535;
122+
}
123+
124+
QToolTip {
125+
background-color: #2d2d2d;
126+
color: #e0e0e0;
127+
border: 1px solid #444444;
128+
padding: 6px;
129+
border-radius: 6px;
130+
}
131+
132+
QPushButton {
133+
background-color: #2b5ea3;
134+
color: white;
135+
border-radius: 6px;
136+
padding: 8px 16px;
137+
border: none;
138+
}
139+
140+
QPushButton:hover {
141+
background-color: #3d75c2;
142+
}
143+
144+
QPushButton:pressed {
145+
background-color: #214a80;
146+
}
147+
148+
QComboBox {
149+
background-color: #2d2d2d;
150+
color: #e0e0e0;
151+
border-radius: 6px;
152+
padding: 6px;
153+
border: 1px solid #444444;
154+
}
155+
156+
QComboBox:hover {
157+
border: 1px solid #3d75c2;
158+
}
159+
160+
QComboBox::drop-down {
161+
border: none;
162+
}
163+
164+
QCheckBox {
165+
color: #e0e0e0;
166+
spacing: 8px;
167+
}
168+
169+
QCheckBox::indicator {
170+
width: 18px;
171+
height: 18px;
172+
border-radius: 4px;
173+
border: 1px solid #444444;
174+
}
175+
176+
QCheckBox::indicator:checked {
177+
background-color: #2b5ea3;
178+
}

src/CodeEditor.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,16 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
7171
}
7272
else if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Slash)
7373
{
74-
addComment();
74+
addComment();
7575
return;
7676
}
7777
else if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Backspace)
7878
{
79-
moveCursor(QTextCursor::WordLeft, QTextCursor::KeepAnchor);
80-
textCursor().removeSelectedText();
81-
textCursor().deletePreviousChar();
79+
QTextCursor cursor = textCursor();
80+
cursor.movePosition(QTextCursor::WordLeft, QTextCursor::KeepAnchor);
81+
cursor.removeSelectedText();
82+
setTextCursor(cursor);
83+
8284
return;
8385
}
8486
else
@@ -263,7 +265,7 @@ void CodeEditor::highlightCurrentLine()
263265
QTextEdit::ExtraSelection selection;
264266

265267
QColor lineColor = QColor(Qt::lightGray).lighter(60);
266-
lineColor.setAlpha(100);
268+
lineColor.setAlpha(80);
267269

268270
selection.format.setBackground(lineColor);
269271
selection.format.setProperty(QTextFormat::FullWidthSelection, true);

src/FileManager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,11 @@ OperationResult FileManager::newFile(const QFileInfo &pathInfo, QString newFileP
387387
file.close();
388388
}
389389

390-
FileManager::getInstance().setCurrentFileName(QString::fromStdString(filePath.string()));
390+
QString fileName = QString::fromStdString(filePath.string());
391+
392+
FileManager::getInstance().setCurrentFileName(fileName);
393+
FileManager::getInstance().loadFileInEditor(fileName);
394+
391395
return {true, filePath.filename().string() + " created successfully."};
392396
}
393397

src/Tree.cpp

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
#include <filesystem>
1111
#include <QMessageBox>
1212
#include <QInputDialog>
13+
#include <QApplication>
14+
#include <QHeaderView>
15+
#include <QMimeData>
1316

1417
Tree::Tree(QSplitter *splitter)
1518
: QObject(splitter),
1619
m_iconProvider(std::make_unique<QFileIconProvider>()),
1720
m_model(std::make_unique<QFileSystemModel>()),
1821
m_tree(std::make_unique<QTreeView>(splitter))
1922
{
20-
connect(m_tree.get(), &QTreeView::doubleClicked, this, &Tree::openFile);
23+
connect(m_tree.get(), &QTreeView::clicked, this, &Tree::openFile);
2124
}
2225

2326
Tree::~Tree() {}
@@ -33,18 +36,33 @@ void Tree::setupModel(const QString &directory)
3336
m_model->setRootPath(directory);
3437
m_model->setIconProvider(m_iconProvider.get());
3538
m_model->setFilter(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot);
39+
m_model->setReadOnly(false);
3640
}
3741

3842
void Tree::setupTree()
3943
{
44+
QFont baseFont = QApplication::font();
45+
QFont treeFont = baseFont;
46+
treeFont.setPointSize(baseFont.pointSize() - 1);
47+
48+
m_tree->setFont(treeFont);
4049
m_tree->setModel(m_model.get());
4150
m_tree->setRootIndex(m_model->index(m_model->rootPath()));
4251
m_tree->setRootIsDecorated(true);
4352
m_tree->setAnimated(true);
44-
m_tree->setIndentation(20);
53+
m_tree->setIndentation(16);
4554
m_tree->setSortingEnabled(false);
4655
m_tree->sortByColumn(1, Qt::AscendingOrder);
4756
m_tree->setHeaderHidden(true);
57+
m_tree->setUniformRowHeights(true);
58+
59+
// Configure file/folder drag & drop
60+
m_tree->setDragDropMode(QAbstractItemView::InternalMove);
61+
m_tree->setDragEnabled(true);
62+
m_tree->setAcceptDrops(true);
63+
m_tree->setDropIndicatorShown(true);
64+
m_tree->setDefaultDropAction(Qt::MoveAction);
65+
m_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
4866

4967
for (int i = 1; i <= m_model->columnCount(); ++i)
5068
{
@@ -53,6 +71,37 @@ void Tree::setupTree()
5371

5472
m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
5573
connect(m_tree.get(), &QTreeView::customContextMenuRequested, this, &Tree::showContextMenu);
74+
75+
// Connect to dragEnter and dragMove events
76+
m_tree->installEventFilter(this);
77+
}
78+
79+
bool Tree::eventFilter(QObject *obj, QEvent *event)
80+
{
81+
if (obj == m_tree.get())
82+
{
83+
if (event->type() == QEvent::DragEnter)
84+
{
85+
QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(event);
86+
if (dragEvent->mimeData()->hasUrls())
87+
{
88+
dragEvent->acceptProposedAction();
89+
return true;
90+
}
91+
}
92+
93+
else if (event->type() == QEvent::DragMove)
94+
{
95+
QDragMoveEvent *dragEvent = static_cast<QDragMoveEvent *>(event);
96+
if (dragEvent->mimeData()->hasUrls())
97+
{
98+
dragEvent->acceptProposedAction();
99+
return true;
100+
}
101+
}
102+
}
103+
104+
return QObject::eventFilter(obj, event);
56105
}
57106

58107
void Tree::openFile(const QModelIndex &index)

0 commit comments

Comments
 (0)