Skip to content

Commit

Permalink
Add TextView window
Browse files Browse the repository at this point in the history
TextView is a glyph that is a text editor glyph, that provides
functionality to control glyphs that are drawn, manages pages, etc

Add:
  - DrawAt function to window interface
  - Get key function to KeyboardEvent
  • Loading branch information
Roman Onyshchuk authored and Roman Onyshchuk committed Apr 20, 2020
1 parent 7bf0636 commit 26d0963
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 33 deletions.
1 change: 1 addition & 0 deletions inc/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class KeyBoardEvent: public Event
{
return m_key >= static_cast<uint32_t>(Key::kSpace) && m_key <= static_cast<uint32_t>(Key::kTilde);
}
[[nodiscard]] Key GetKey() const { return static_cast<Key>(m_key); }

uint32_t m_key;
};
Expand Down
7 changes: 7 additions & 0 deletions inc/glyphs/i_composite_glyph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ class ICompositeGlyph: public IGlyph
}
}

void DrawAt(Gui::Window* window, const Point& point) override
{
for(auto& it: m_components) {
it->DrawAt(window, point);
}
}

~ICompositeGlyph() override = default;

void Insert(GlyphPtr glyph, size_t pos) override
Expand Down
5 changes: 5 additions & 0 deletions inc/glyphs/i_glyph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ class IGlyph
using GlyphPtr = std::shared_ptr<IGlyph>;

virtual void Draw(Gui::Window*) = 0; // TODO: const?
/**
* @brief Draw current glyph at specific position.
* @param point New position of glyph.
*/
virtual void DrawAt(Gui::Window* w, const Point& point) { Draw(w); }
virtual void ReDraw(Gui::Window* w)
{
ClearGlyph(w);
Expand Down
31 changes: 23 additions & 8 deletions inc/glyphs/text_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,33 @@
#ifndef LEXI_TEXT_VIEW_HPP
#define LEXI_TEXT_VIEW_HPP

#include "i_glyph.hpp"
#include "window.hpp"

class TextView: public ICompositeGlyph
class Page;

class TextView: public Gui::Window
{
public:
explicit TextView(const GlyphParams& params): ICompositeGlyph(params) {}
explicit TextView(const GlyphParams&, Window*);

void Draw(Gui::Window* window) override;
void ProcessEvent(Gui::Window* w, const Event& event) override;

void DrawRectangle(const GlyphParams& params) const override;
void DrawText(const Point& text_position, std::string text) const override;
void DrawLine(const Point& start_point, const Point& end_point) const override;

void UpdateVisibleArea(height_t h);
void MoveVisibleArea(height_t h);

[[nodiscard]] std::string GetWindowName() const override { return "Text View"; }

private:
// Relative square currently shown on display.
GlyphParams m_visibleArea;

void Draw(Gui::Window* window) override
{
window->FillRectangle({m_params.x, m_params.y}, m_params.width, m_params.height, Color::kWhite);
ICompositeGlyph::Draw(window);
}
std::shared_ptr<Page> m_currentPage;
std::list<std::shared_ptr<Page>> m_visiblePages;
};

#endif // LEXI_TEXT_VIEW_HPP
16 changes: 12 additions & 4 deletions inc/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include "i_composite_glyph.hpp"
#include "i_glyph.hpp"
// TODO: WindowImpl should be private for Window
#include "types.hpp"
#include "window_impl.hpp"

Expand All @@ -28,11 +27,13 @@ class Window: public ICompositeGlyph
void Draw(Gui::Window*) override;
void ReDraw();
void DrawRectangle(const Point& point, const width_t width, const height_t height) const;
void DrawText(const Point& text_position, std::string text) const;
void DrawText(const GlyphParams&, const std::string&, Alignment);
void DrawLine(const Point& start_point, const Point& end_point) const;
virtual void DrawRectangle(const GlyphParams& params) const;
virtual void DrawText(const Point& text_position, std::string text) const;
virtual void DrawText(const GlyphParams&, const std::string&, Alignment);
virtual void DrawLine(const Point& start_point, const Point& end_point) const;

void FillRectangle(const Point& point, const width_t width, const height_t height, const Color color);
virtual void FillRectangle(const GlyphParams& params, const Color color);

void SetForeground(int color) const;

Expand All @@ -52,6 +53,9 @@ class Window: public ICompositeGlyph
void ShowWindow() const;
void HideWindow() const;

[[nodiscard]] virtual std::string GetWindowName() const {
return "Main Window";
}
protected:
friend EventManager;
std::unique_ptr<WindowImpl> m_window_impl;
Expand All @@ -69,6 +73,10 @@ class ChildWindow: public Window
void SetCurrentMenuItem(GlyphPtr item) {
m_currentMenuItem = std::move(item);
}

[[nodiscard]] std::string GetWindowName() const override {
return "Child Window";
}
private:
// TODO(rmn): weak_ptr
Window* m_parent;
Expand Down
22 changes: 14 additions & 8 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "text_label.hpp"
#include "text_view.hpp"
#include "window.hpp"
#include "page.hpp"
#include "scroller.hpp"

const auto Version = "Lexi v1.0";

Expand All @@ -26,16 +28,16 @@ int main()
GlyphParams initial_window_params;
initial_window_params.x = 0;
initial_window_params.y = 0;
initial_window_params.width = 800;
initial_window_params.height = 1024;
initial_window_params.width = 1920;
initial_window_params.height = 1080;

Gui::Window window(initial_window_params);
EventManager eventManager(&window);
eventManager.addWindow(&window);

Lexi::FontManager::Get().Init(&window);

const auto defaultFont = "Ubuntu";
const auto defaultFont = "clean";
Lexi::FontManager::Get().SetFont(defaultFont);

auto top_panel =
Expand All @@ -57,15 +59,18 @@ int main()
top_panel->Add(fontsMenu);
eventManager.addWindow(fontsMenu->getMenuWindow());

// auto text_view_border = std::make_shared<BorderDecorator>(GlyphParams{459, 99, 801, 200}, Color::kBlack);
// text_view_border->Add(std::make_shared<TextView>(GlyphParams{460, 100, 800, 100}));
auto text_view = std::make_shared<TextView>(GlyphParams{360, 100, 1200, 400}, &window);
window.Add(text_view);
eventManager.addWindow(text_view.get());

auto fontSizeMenu = std::make_shared<Gui::DropDownMenu>(GlyphParams{365, 10, 80, 20}, "12", &window);
top_panel->Add(fontSizeMenu);
eventManager.addWindow(fontSizeMenu->getMenuWindow());

auto text_view_border = std::make_shared<BorderDecorator>(GlyphParams{40, 100, 700, 800}, Color::kBlack);
text_view_border->Add(std::make_shared<TextView>(GlyphParams{40, 100, 700, 800}));
window.Add(text_view_border);

auto scroll_board = std::make_shared<BorderDecorator>(GlyphParams{750, 100, 20, 800}, Color::kBlack);
auto scroll_board = std::make_shared<BorderDecorator>(GlyphParams{1900, 100, 20, 800}, Color::kBlack);
scroll_board->Add(std::make_shared<Scroller>(GlyphParams{1905, 200, 10, 40}));
window.Add(scroll_board);

auto bottom_panel =
Expand Down Expand Up @@ -96,6 +101,7 @@ int main()
status_line->ChangeText(it, &window);
bottom_panel->Draw(&window);
});
menuItem->SetOnButtonPressedAction([&, it] { Lexi::FontManager::Get().SetFont(it); });
}

for(const auto& it: supportedFontSizes) {
Expand Down
18 changes: 10 additions & 8 deletions src/lexi_linux/inc/x_window_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#ifndef LEXI_X_WINDOW_IMPL_CPP_HPP
#define LEXI_X_WINDOW_IMPL_CPP_HPP

#include "window_impl.hpp"
#include "font.hpp"
#include "window_impl.hpp"

#include <X11/Xlib.h>

Expand All @@ -15,7 +15,8 @@ class XWindowImpl: public WindowImpl
{
public:
explicit XWindowImpl(const GlyphParams&);
explicit XWindowImpl(const GlyphParams, XWindowImpl*);
// TODO(rmn): mb make static creator
explicit XWindowImpl(const GlyphParams&, XWindowImpl*);
~XWindowImpl() override;

void DrawRectangle(const Point& point, const width_t width, const height_t height) override;
Expand All @@ -30,9 +31,9 @@ class XWindowImpl: public WindowImpl
void ShowWindow() override;
void HideWindow() override;

unsigned long GetWindow() const override { return m_window; }

void* GetDisplay() const override { return m_display; }
[[nodiscard]] unsigned long GetWindow() const override { return m_window; }
[[nodiscard]] void* GetDisplay() const override { return m_display; }
[[nodiscard]] ::GC GetGc() const { return m_gc; }

void ClearWindow() override;
void ClearGlyph(const GlyphParams& p, bool sendExposureEvent) override;
Expand All @@ -42,13 +43,14 @@ class XWindowImpl: public WindowImpl

std::set<Lexi::FontName> GetFontList() override;
bool ChangeFont(Lexi::Font&) override;

private:
void CreateWindow(const GlyphParams& params);
void CreateGraphicContext();

::Display* m_display;
::Window m_window;
::GC m_gc;
::Display* m_display = nullptr;
::Window m_window = 0;
::GC m_gc = nullptr;

bool m_isChild = false;
};
Expand Down
18 changes: 17 additions & 1 deletion src/lexi_linux/src/event_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <algorithm>
#include "event_manager.hpp"

#include "cursor.hpp"
#include "lexi_linux/inc/x_window_impl.hpp"
#include "window.hpp"

Expand All @@ -30,6 +31,8 @@ bool EventManager::ChangeCurrentWindow(unsigned long window)
return false;
}

std::cout << "Window changed from: " << m_currentWindow->GetWindowName() << " to: " << (*windowsIt)->GetWindowName()
<< std::endl;
m_currentWindow = *windowsIt;
return true;
}
Expand All @@ -42,7 +45,7 @@ void EventManager::RunLoop()
XEvent event;
XNextEvent(display, &event);

Point p{static_cast<uint32_t>(event.xbutton.x), static_cast<uint32_t>(event.xbutton.y)};
Point p{event.xbutton.x, event.xbutton.y};
switch(event.type) {
case Expose:
if(ChangeCurrentWindow(event.xexpose.window)) {
Expand Down Expand Up @@ -80,8 +83,21 @@ void EventManager::RunLoop()
case FocusOut:
std::cout << "Focus out" << std::endl;
break;
case KeyPress: {
auto mykey = XkbKeycodeToKeysym(display, event.xkey.keycode, 0, event.xkey.state & ShiftMask ? 1 : 0);
if(mykey == NoSymbol) {
std::cout << "Wrong Key:" << std::endl;
} else {
// If cursor is active redirect key press action to it
// TODO(rmn): need stabilization
m_currentWindow->ProcessEvent(
m_currentWindow, Lexi::KeyBoardEvent(Lexi::Cursor::Get().GetPosition(), mykey));
}
} break;
case KeyRelease:
case EnterNotify:
case LeaveNotify:
case ConfigureNotify:
break;
default:
std::cout << "RMN unprocessed event:" << event.type << std::endl;
Expand Down
6 changes: 4 additions & 2 deletions src/lexi_linux/src/x_window_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//
// Created by romaonishuk on 27.10.19.
//

#include "x_window_impl.hpp"

#include "font.hpp"
#include "logger.hpp"

Expand All @@ -20,7 +22,7 @@ XWindowImpl::XWindowImpl(const GlyphParams& params)
std::cout << "XWindowImpl created!" << std::endl;
}

XWindowImpl::XWindowImpl(const GlyphParams params, XWindowImpl* parentImpl):
XWindowImpl::XWindowImpl(const GlyphParams& params, XWindowImpl* parentImpl):
m_display(parentImpl->m_display),
m_gc(parentImpl->m_gc)
{
Expand Down Expand Up @@ -120,7 +122,7 @@ void XWindowImpl::DrawText(const GlyphParams& params, const std::string& text, A
XCharStruct overall_return;

XTextExtents(fontInfo, text.c_str(), text.size(), &direction_return, &font_ascent_return, &font_descent_return,
&overall_return);
&overall_return);

Point point;
// TODO(rmn): errors + too long/big words + other cases where descent !=0 + include bearing
Expand Down
79 changes: 79 additions & 0 deletions src/text_view.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,82 @@
//
// Created by ronyshchuk on 07.04.20.
//

#include "text_view.hpp"
#include "cursor.hpp"
#include "font.hpp"
#include "page.hpp"
#include "window.hpp"

TextView::TextView(const GlyphParams& params, Gui::Window* w):
Gui::Window(params, w),
m_visibleArea(0, 0, params.width, params.height)
{
const auto pageHeight = 200;
m_currentPage = std::make_shared<Page>(this, GlyphParams{0, 0, m_params.width - 1, pageHeight});
ICompositeGlyph::Add(m_currentPage);
m_visiblePages.push_back(m_currentPage);
this->ShowWindow();
}

void TextView::Draw(Gui::Window* window)
{
for(auto& page: m_visiblePages) {
page->Draw(this);
}

m_currentPage->DrawCursor(this);
}

// TODO(rmn): chunking
void TextView::ProcessEvent(Gui::Window* window, const Event& event)
{
if(event.GetEvent() == EventType::KeyPressed) {
m_currentPage->ProcessEvent(window, event);

if(Lexi::Cursor::Get().GetCursorEnd() < m_visibleArea.y) {
m_visibleArea.y -= Lexi::FontManager::Get().GetCharHeight();
IGlyph::ReDraw(window);
}

if(Lexi::Cursor::Get().GetCursorEnd() > m_visibleArea.y + m_params.height) {
m_visibleArea.y += Lexi::FontManager::Get().GetCharHeight();
IGlyph::ReDraw(window);
}

return;
}
}

void TextView::DrawRectangle(const GlyphParams& params) const
{
if(m_visibleArea.IsIntersects(params) || params.IsIntersects(m_visibleArea)) {
m_window_impl->DrawRectangle({params.x, params.y - m_visibleArea.y}, params.width, params.height);
}
}

void TextView::DrawText(const Point& text_position, std::string text) const
{
if(m_visibleArea.IsIntersects({text_position.x, text_position.y})) {
m_window_impl->DrawText({text_position.x, text_position.y - m_visibleArea.y}, text);
}
}

void TextView::DrawLine(const Point& start_point, const Point& end_point) const
{
// TODO(rmn) :intersection
m_window_impl->DrawLine(
{start_point.x, start_point.y - m_visibleArea.y}, {end_point.x, end_point.y - m_visibleArea.y});
}

void TextView::UpdateVisibleArea(height_t h)
{
m_visibleArea.y = h;
Draw(this);
}

void TextView::MoveVisibleArea(height_t h)
{
m_visibleArea.y += h;
Draw(this);
}
Loading

0 comments on commit 26d0963

Please sign in to comment.