Skip to content

Commit 47068f4

Browse files
committed
Typewriter & center on scroll 🎩
- Updated Readme - Added UserData / MainWindow menu options for Cursor "center on scroll" and "Typewriter" positioning - Rewrote how Splitter/SplitterHandle handle initialization - Added Splitter::hasHover check - Added the toggling methods for Cursor COS/Typewriter to PlainTextEdit/Editor
1 parent 524e107 commit 47068f4

File tree

14 files changed

+101
-53
lines changed

14 files changed

+101
-53
lines changed

Fernanda/docs/Notes.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,11 @@
1313
<a href="https://github.com/fairybow/Fernanda/search?l=c%2B%2B"><img src="https://img.shields.io/badge/C%2B%2B20-5B5B5B?logo=c%2B%2B" alt="C++20"/></a>
1414
<br>
1515
<a href="https://shields.io/"><img src="https://img.shields.io/badge/omg-these%20are%20so%20cute-00b3b3"/></a>
16-
</p>
16+
</p>
17+
18+
```
19+
auto view = viewport();
20+
auto height = view->height();
21+
auto y = (height / 2) - cursorRect().y();
22+
viewport()->setGeometry(view->x(), y, view->width(), height);
23+
```

Fernanda/docs/To-do.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
- [x] ~~Probably should combine `elements()` and `elementsByAttribute()`~~
8383

8484
### Editor / PlainTextEdit / LineNumberArea
85+
- [ ] "Ribbon" mode
86+
- [ ] A toggleable for every relevant `QPlainTextEdit` toggleable (`centerOnScroll` for example)
8587
- [ ] It is not clear to me that `updateLineNumberAreaWidth(int newBlockCount)` actually uses `newBlockCount` arg
8688
- [ ] Save undo/redo stacks
8789
- [ ] Editor spacing and kerning sliders
@@ -91,6 +93,7 @@
9193
- [ ] Wrap for parentheses and other closables
9294
- [ ] If a filter was just applied, backspace should function as undo
9395
- [ ] Make thin cursor change color when there's a selection?
96+
- [x] ~~Typewriter mode~~
9497
- [x] ~~Avoid passing entire document for cursor underpaint lol~~
9598
- [x] ~~Toggle chonky cursor vs regular~~
9699
- [x] ~~Style horizontal scrollbar~~

Fernanda/source/Editor.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,25 @@ void Editor::devRemoveStyle()
5858
void Editor::toggle(bool checked, Has has)
5959
{
6060
switch (has) {
61-
case Has::BlockCursor:
62-
hasBlockCursor = checked;
63-
plainTextEdit->cursorPositionChanged();
64-
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlock, checked);
65-
break;
6661
case Has::CursorBlink:
6762
hasCursorBlink = checked;
6863
startBlinker();
6964
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlink, checked);
7065
break;
66+
case Has::CursorBlock:
67+
hasCursorBlock = checked;
68+
plainTextEdit->cursorPositionChanged();
69+
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlock, checked);
70+
break;
71+
case Has::CursorCenterOnScroll:
72+
askToggleCenterOnScroll(checked);
73+
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorCenterOnScroll, checked);
74+
break;
75+
case Has::CursorTypewriter:
76+
hasCursorTypewriter = checked;
77+
plainTextEdit->textChanged();
78+
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorTypewriter, checked);
79+
break;
7180
case Has::ExtraScrolls:
7281
askToggleExtraScrolls(checked);
7382
UserData::saveConfig(UserData::IniGroup::Editor, UserData::IniValue::ToggleScrollsPrevNext, checked);
@@ -185,6 +194,7 @@ void Editor::close(bool isFinal)
185194

186195
void Editor::connections()
187196
{
197+
connect(this, &Editor::askToggleCenterOnScroll, plainTextEdit, &PlainTextEdit::toggleCenterOnScroll);
188198
connect(this, &Editor::askToggleLineNumberArea, plainTextEdit, &PlainTextEdit::toggleLineNumberArea);
189199
connect(this, &Editor::askToggleScrolls, plainTextEdit, &PlainTextEdit::toggleScrolls);
190200
connect(this, &Editor::askToggleExtraScrolls, plainTextEdit, &PlainTextEdit::toggleExtraScrolls);
@@ -205,7 +215,8 @@ void Editor::connections()
205215
connect(plainTextEdit, &PlainTextEdit::askHasLineHighlight, this, [&]() { return hasLineHighlight; });
206216
connect(plainTextEdit, &PlainTextEdit::askHasKeyFilter, this, [&]() { return hasKeyFilter; });
207217
connect(plainTextEdit, &PlainTextEdit::askHasCursorBlink, this, [&]() { return hasCursorBlink; });
208-
connect(plainTextEdit, &PlainTextEdit::askHasBlockCursor, this, [&]() { return hasBlockCursor; });
218+
connect(plainTextEdit, &PlainTextEdit::askHasCursorBlock, this, [&]() { return hasCursorBlock; });
219+
connect(plainTextEdit, &PlainTextEdit::askHasCursorTypewriter, this, [&]() { return hasCursorTypewriter; });
209220
connect(plainTextEdit, &PlainTextEdit::askCursorVisible, this, [&]() { return cursorVisible; });
210221
connect(plainTextEdit, &PlainTextEdit::cursorPositionChanged, this, [&]() { cursorPositionChanged(); });
211222
connect(plainTextEdit, &PlainTextEdit::selectionChanged, this, [&]() { selectionChanged(); });

Fernanda/source/Editor.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ class Editor : public QWidget
3737
AcceptNew
3838
};
3939
enum class Has {
40-
BlockCursor,
4140
CursorBlink,
41+
CursorBlock,
42+
CursorCenterOnScroll,
43+
CursorTypewriter,
4244
ExtraScrolls,
4345
KeyFilter,
4446
LineHighlight,
@@ -92,7 +94,8 @@ public slots:
9294
bool hasLineHighlight = true;
9395
bool hasKeyFilter = true;
9496
bool hasCursorBlink = true;
95-
bool hasBlockCursor = true;
97+
bool hasCursorBlock = true;
98+
bool hasCursorTypewriter = false;
9699
bool cursorVisible = true;
97100

98101
void connections();
@@ -109,6 +112,7 @@ public slots:
109112
bool askHasProject();
110113
QAction* askTheme();
111114
QActionGroup* askThemes();
115+
void askToggleCenterOnScroll(bool checked);
112116
void askToggleExtraScrolls(bool checked);
113117
void askToggleLineNumberArea(bool checked);
114118
void askToggleScrolls(bool checked);

Fernanda/source/MainWindow.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ void MainWindow::makeToggleMenu()
382382
auto load_most_recent_toggle = new QAction(tr("&Load most recent project on open"), this);
383383
auto cursor_blink_toggle = new QAction(tr("&Blink"), this);
384384
auto cursor_block_toggle = new QAction(tr("&Block"), this);
385+
auto cursor_center_on_scroll_toggle = new QAction(tr("&Center on scroll"), this);
386+
auto cursor_typewriter_toggle = new QAction(tr("&Typewriter"), this);
385387
auto current_line_highlight_toggle = new QAction(tr("&Current line highlight"), this);
386388
auto editor_shadow_toggle = new QAction(tr("&Editor shadow"), this);
387389
auto editor_theme_toggle = new QAction(tr("&Editor theme"), this);
@@ -393,7 +395,7 @@ void MainWindow::makeToggleMenu()
393395
auto indicator_toggle = new QAction(tr("&Indicator"), this);
394396
auto preview_toggle = new QAction(tr("&Preview"), this);
395397
auto status_bar_toggle = new QAction(tr("&Status bar"), this);
396-
auto aot_toggle = new QAction(tr("&Always-on-top"), this);
398+
auto aot_toggle = new QAction(tr("&Always on top"), this);
397399
auto stay_awake_toggle = new QAction(tr("&Stay awake"), this);
398400
auto timer_toggle = new QAction(tr("&Timer"), this);
399401
auto window_theme_toggle = new QAction(tr("&Window theme"), this);
@@ -402,7 +404,9 @@ void MainWindow::makeToggleMenu()
402404
UserData::saveConfig(UserData::IniGroup::Data, UserData::IniValue::ToggleLoadMostRecent, checked); // move to story?
403405
});
404406
connect(cursor_blink_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorBlink); });
405-
connect(cursor_block_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::BlockCursor); });
407+
connect(cursor_block_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorBlock); });
408+
connect(cursor_center_on_scroll_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorCenterOnScroll); });
409+
connect(cursor_typewriter_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::CursorTypewriter); });
406410
connect(current_line_highlight_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::LineHighlight); });
407411
connect(editor_shadow_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::Shadow); });
408412
connect(editor_theme_toggle, &QAction::toggled, this, [&](bool checked) { editor->toggle(checked, Editor::Has::Theme); });
@@ -436,6 +440,8 @@ void MainWindow::makeToggleMenu()
436440
load_most_recent_toggle,
437441
cursor_blink_toggle,
438442
cursor_block_toggle,
443+
cursor_center_on_scroll_toggle,
444+
cursor_typewriter_toggle,
439445
current_line_highlight_toggle,
440446
editor_shadow_toggle,
441447
editor_theme_toggle,
@@ -456,6 +462,8 @@ void MainWindow::makeToggleMenu()
456462
loadMenuToggle(load_most_recent_toggle, UserData::IniGroup::Data, UserData::IniValue::ToggleLoadMostRecent, false);
457463
loadMenuToggle(cursor_blink_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlink, true);
458464
loadMenuToggle(cursor_block_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorBlock, true);
465+
loadMenuToggle(cursor_center_on_scroll_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorCenterOnScroll, false);
466+
loadMenuToggle(cursor_typewriter_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleCursorTypewriter, false);
459467
loadMenuToggle(current_line_highlight_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleLineHighlight, true);
460468
loadMenuToggle(editor_shadow_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleEditorShadow, true);
461469
loadMenuToggle(editor_theme_toggle, UserData::IniGroup::Editor, UserData::IniValue::ToggleEditorTheme, true);
@@ -475,7 +483,7 @@ void MainWindow::makeToggleMenu()
475483
toggle->addAction(load_most_recent_toggle);
476484
toggle->addSeparator();
477485
auto cursor = toggle->addMenu(tr("&Cursor"));
478-
for (const auto& action : { cursor_blink_toggle, cursor_block_toggle })
486+
for (const auto& action : { cursor_blink_toggle, cursor_block_toggle, cursor_center_on_scroll_toggle, cursor_typewriter_toggle })
479487
cursor->addAction(action);
480488
for (const auto& action : { current_line_highlight_toggle, editor_shadow_toggle, editor_theme_toggle, key_filter_toggle, line_number_area_toggle, scrolls_previous_next_toggle })
481489
toggle->addAction(action);

Fernanda/source/PlainTextEdit.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ void PlainTextEdit::paintEvent(QPaintEvent* event)
184184
auto current_char = currentChar();
185185
auto rect = reshapeCursor(current_char);
186186
painter.fillRect(rect, recolorCursor());
187-
if (!current_char.isNull() && askHasBlockCursor())
187+
if (!current_char.isNull() && askHasCursorBlock())
188188
{
189189
painter.setPen(recolorCursor(true));
190190
painter.drawText(rect, current_char);
@@ -315,6 +315,8 @@ void PlainTextEdit::connections()
315315
connect(this, &PlainTextEdit::blockCountChanged, this, &PlainTextEdit::updateLineNumberAreaWidth);
316316
connect(this, &PlainTextEdit::updateRequest, this, &PlainTextEdit::updateLineNumberArea);
317317
connect(this, &PlainTextEdit::cursorPositionChanged, this, &PlainTextEdit::highlightCurrentLine);
318+
connect(this, &PlainTextEdit::cursorPositionChanged, this, &PlainTextEdit::typewriter);
319+
connect(this, &PlainTextEdit::textChanged, this, &PlainTextEdit::typewriter);
318320
connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &PlainTextEdit::scrollButtonEnabledHandler);
319321
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &PlainTextEdit::scrollButtonEnabledHandler);
320322
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, [&]() { sendBlockNumber(firstVisibleBlock().blockNumber()); });
@@ -334,7 +336,7 @@ void PlainTextEdit::connections()
334336

335337
const QRect PlainTextEdit::reshapeCursor(QChar currentChar)
336338
{
337-
if (askHasBlockCursor())
339+
if (askHasCursorBlock())
338340
{
339341
QFontMetrics metrics(font());
340342
currentChar.isNull()
@@ -386,4 +388,10 @@ void PlainTextEdit::updateLineNumberArea(const QRect& rect, int dy)
386388
updateLineNumberAreaWidth(0);
387389
}
388390

391+
void PlainTextEdit::typewriter()
392+
{
393+
if (!askHasCursorTypewriter()) return;
394+
centerCursor();
395+
}
396+
389397
// PlainTextEdit.cpp, Fernanda

Fernanda/source/PlainTextEdit.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public slots:
7272
void toggleScrolls(bool checked);
7373
void toggleExtraScrolls(bool checked);
7474

75+
void toggleCenterOnScroll(bool checked) { setCenterOnScroll(checked); }
76+
7577
protected:
7678
void resizeEvent(QResizeEvent* event) override;
7779
void paintEvent(QPaintEvent* event) override;
@@ -103,6 +105,7 @@ public slots:
103105
private slots:
104106
void scrollButtonEnabledHandler();
105107
void updateLineNumberArea(const QRect& rect, int dy);
108+
void typewriter();
106109

107110
void updateLineNumberAreaWidth(int newBlockCount) { setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); }
108111

@@ -111,8 +114,9 @@ private slots:
111114
void askFontSliderZoom(Zoom direction);
112115
void askGoNext();
113116
void askGoPrevious();
114-
bool askHasBlockCursor();
115117
bool askHasCursorBlink();
118+
bool askHasCursorBlock();
119+
bool askHasCursorTypewriter();
116120
bool askHasKeyFilter();
117121
bool askHasLineHighlight();
118122
bool askHasProject();
@@ -122,7 +126,6 @@ private slots:
122126

123127
class LineNumberArea : public QWidget
124128
{
125-
126129
public:
127130
LineNumberArea(PlainTextEdit* parent) : QWidget(parent), parent(parent) {}
128131

Fernanda/source/Splitter.cpp

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ SplitterHandle* Splitter::createHandle()
9393
{
9494
auto handle = new SplitterHandle(orientation(), this);
9595
connect(handle, &SplitterHandle::askHoverExpand, this, &Splitter::hoverExpand);
96-
connect(handle, &SplitterHandle::askIsInitialized, this, &Splitter::initialize);
9796
connect(handle, &SplitterHandle::askStoreWidths, this, &Splitter::storeWidths);
9897
connect(handle, &SplitterHandle::askToggleExpansion, this, &Splitter::toggleExpansion);
9998
connect(handle, &SplitterHandle::askUnhoverAll, this, &Splitter::unhoverAll);
@@ -147,6 +146,16 @@ bool Splitter::eventFilter(QObject* watched, QEvent* event)
147146
return false;
148147
}
149148

149+
void Splitter::initialize()
150+
{
151+
for (auto& widget_info : widgets)
152+
{
153+
if (widget_info.width) continue;
154+
widget_info.state = State::Collapsed;
155+
isInitialized = true;
156+
}
157+
}
158+
150159
void Splitter::checkStates(int position, int index)
151160
{
152161
for (auto& widget_info : widgets)
@@ -157,11 +166,11 @@ void Splitter::checkStates(int position, int index)
157166
auto& widget_state = widget_info.state;
158167
(handle_index < 2)
159168
? (position != 0)
160-
? widget_state = State::Expanded
161-
: widget_state = State::Collapsed
169+
? widget_state = State::Expanded
170+
: widget_state = State::Collapsed
162171
: (position != (askWindowSize().width() - handleWidth()))
163-
? widget_state = State::Expanded
164-
: widget_state = State::Collapsed;
172+
? widget_state = State::Expanded
173+
: widget_state = State::Collapsed;
165174
}
166175
}
167176

@@ -175,24 +184,10 @@ void Splitter::hoverExpand(SplitterHandle* handlePtr)
175184
}
176185
}
177186

178-
void Splitter::initialize()
179-
{
180-
if (isInitialized)
181-
{
182-
storeWidths();
183-
return;
184-
}
185-
for (auto& widget_info : widgets)
186-
{
187-
if (widget_info.width) continue;
188-
widget_info.state = State::Collapsed;
189-
}
190-
storeWidths();
191-
isInitialized = true;
192-
}
193-
194187
void Splitter::storeWidths()
195188
{
189+
if (!isInitialized)
190+
initialize();
196191
for (auto& widget_info : widgets)
197192
{
198193
if (!isExpanded(widget_info)) continue;
@@ -220,7 +215,7 @@ void Splitter::unhoverAll()
220215
if (!isHoverExpanded(widget_info)) continue;
221216
QTimer::singleShot(250, this, [&]()
222217
{
223-
if (!widget(widget_info.index)->underMouse() && !handle(widget_info.handleIndex)->underMouse())
218+
if (!hasHover(widget_info))
224219
collapse(widget_info);
225220
});
226221
}

Fernanda/source/Splitter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,19 @@ class Splitter : public QSplitter
6666
void expand(Info& widgetInfo, bool isHover = false);
6767
void uncollapseAll();
6868
bool eventFilter(QObject* watched, QEvent* event);
69+
void initialize();
6970

7071
int toWindowX(int index, int size) { return (index < 2) ? size : askWindowSize().width() - size; }
7172
bool match(SplitterHandle* handlePtr, Info& widgetInfo) const { return (handlePtr == handle(widgetInfo.handleIndex)); }
7273
bool isCollapsed(Info& widgetInfo) const { return (widgetInfo.state == State::Collapsed); }
7374
bool isExpanded(Info& widgetInfo) const { return (widgetInfo.state == State::Expanded); }
7475
bool isHoverExpanded(Info& widgetInfo) const { return (widgetInfo.state == State::HoverExpanded); }
76+
bool hasHover(Info& widgetInfo) const { return (widget(widgetInfo.index)->underMouse() || handle(widgetInfo.handleIndex)->underMouse()); }
7577

7678

7779
private slots:
7880
void checkStates(int position, int index);
7981
void hoverExpand(SplitterHandle* handlePtr);
80-
void initialize();
8182
void storeWidths();
8283
void toggleExpansion(SplitterHandle* handlePtr);
8384
void unhoverAll();

Fernanda/source/SplitterHandle.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class SplitterHandle : public QSplitterHandle
3131
expanding->setDuration(100);
3232
expanding->setEasingCurve(QEasingCurve::OutQuad);
3333
expanding->setStartValue(splitter()->handleWidth());
34-
expanding->setEndValue(splitter()->handleWidth() * 1.5);
34+
expanding->setEndValue(splitter()->handleWidth() * 1.6);
3535
connect(hoverTrigger, &QTimer::timeout, this, [&]()
3636
{
3737
askHoverExpand(this);
@@ -62,7 +62,7 @@ class SplitterHandle : public QSplitterHandle
6262
result = true;
6363
break;
6464
case QEvent::MouseButtonRelease:
65-
askIsInitialized();
65+
askStoreWidths();
6666
result = true;
6767
break;
6868
case QEvent::MouseButtonDblClick:
@@ -78,7 +78,6 @@ class SplitterHandle : public QSplitterHandle
7878

7979
signals:
8080
void askHoverExpand(SplitterHandle* handlePtr);
81-
void askIsInitialized();
8281
void askStoreWidths();
8382
void askToggleExpansion(SplitterHandle* handlePtr);
8483
void askUnhoverAll();

Fernanda/source/UserData.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ const QString UserData::valueName(IniValue valueType)
171171
case IniValue::ToggleCursorBlock:
172172
result = "toggle__cursor_block";
173173
break;
174+
case IniValue::ToggleCursorCenterOnScroll:
175+
result = "toggle__cursor_center_on_scroll";
176+
break;
177+
case IniValue::ToggleCursorTypewriter:
178+
result = "toggle__cursor_typewriter";
179+
break;
174180
case IniValue::ToggleEditorShadow:
175181
result = "toggle__editor_shadow";
176182
break;

Fernanda/source/UserData.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ namespace UserData
5353
ToggleColorBar,
5454
ToggleCursorBlink,
5555
ToggleCursorBlock,
56+
ToggleCursorCenterOnScroll,
57+
ToggleCursorTypewriter,
5658
ToggleEditorShadow,
5759
ToggleEditorTheme,
5860
ToggleIndicator,

Fernanda/source/Version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
#pragma once
1515

16-
#define VER_FILEVERSION 0,24,4,53
17-
#define VER_FILEVERSION_STR "v0.24.4-beta53"
16+
#define VER_FILEVERSION 0,25,0,54
17+
#define VER_FILEVERSION_STR "v0.25.0-beta54"
1818
#define VER_PRODUCTVERSION VER_FILEVERSION
1919
#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
2020
#define VER_COMPANYNAME_STR "fairybow"

0 commit comments

Comments
 (0)