Procházet zdrojové kódy

LibGUI: Start bringing up GTextBox in the standalone world.

Andreas Kling před 6 roky
rodič
revize
d72575d196

+ 110 - 0
Kernel/KeyCode.h

@@ -0,0 +1,110 @@
+#pragma once
+
+#include <AK/Types.h>
+
+enum KeyCode : byte {
+    Key_Invalid = 0,
+    Key_Escape,
+    Key_Tab,
+    Key_Backspace,
+    Key_Return,
+    Key_Insert,
+    Key_Delete,
+    Key_PrintScreen,
+    Key_SysRq,
+    Key_Home,
+    Key_End,
+    Key_Left,
+    Key_Up,
+    Key_Right,
+    Key_Down,
+    Key_PageUp,
+    Key_PageDown,
+    Key_Shift,
+    Key_Control,
+    Key_Alt,
+    Key_CapsLock,
+    Key_NumLock,
+    Key_ScrollLock,
+    Key_F1,
+    Key_F2,
+    Key_F3,
+    Key_F4,
+    Key_F5,
+    Key_F6,
+    Key_F7,
+    Key_F8,
+    Key_F9,
+    Key_F10,
+    Key_F11,
+    Key_F12,
+    Key_Space,
+    Key_ExclamationPoint,
+    Key_DoubleQuote,
+    Key_Hashtag,
+    Key_Dollar,
+    Key_Percent,
+    Key_Ampersand,
+    Key_Apostrophe,
+    Key_LeftParen,
+    Key_RightParen,
+    Key_Asterisk,
+    Key_Plus,
+    Key_Comma,
+    Key_Minus,
+    Key_Period,
+    Key_Slash,
+    Key_0,
+    Key_1,
+    Key_2,
+    Key_3,
+    Key_4,
+    Key_5,
+    Key_6,
+    Key_7,
+    Key_8,
+    Key_9,
+    Key_Colon,
+    Key_Semicolon,
+    Key_LessThan,
+    Key_Equal,
+    Key_GreaterThan,
+    Key_QuestionMark,
+    Key_AtSign,
+    Key_A,
+    Key_B,
+    Key_C,
+    Key_D,
+    Key_E,
+    Key_F,
+    Key_G,
+    Key_H,
+    Key_I,
+    Key_J,
+    Key_K,
+    Key_L,
+    Key_M,
+    Key_N,
+    Key_O,
+    Key_P,
+    Key_Q,
+    Key_R,
+    Key_S,
+    Key_T,
+    Key_U,
+    Key_V,
+    Key_W,
+    Key_X,
+    Key_Y,
+    Key_Z,
+    Key_LeftBracket,
+    Key_RightBracket,
+    Key_Backslash,
+    Key_Circumflex,
+    Key_Underscore,
+    Key_LeftBrace,
+    Key_RightBrace,
+    Key_Pipe,
+    Key_Tilde,
+    Key_Backtick,
+};

+ 1 - 107
Kernel/Keyboard.h

@@ -5,116 +5,10 @@
 #include <AK/CircularQueue.h>
 #include <Kernel/CharacterDevice.h>
 #include "IRQHandler.h"
+#include "KeyCode.h"
 
 class KeyboardClient;
 
-enum KeyCode : byte {
-    Key_Invalid = 0,
-    Key_Escape,
-    Key_Tab,
-    Key_Backspace,
-    Key_Return,
-    Key_Insert,
-    Key_Delete,
-    Key_PrintScreen,
-    Key_SysRq,
-    Key_Home,
-    Key_End,
-    Key_Left,
-    Key_Up,
-    Key_Right,
-    Key_Down,
-    Key_PageUp,
-    Key_PageDown,
-    Key_Shift,
-    Key_Control,
-    Key_Alt,
-    Key_CapsLock,
-    Key_NumLock,
-    Key_ScrollLock,
-    Key_F1,
-    Key_F2,
-    Key_F3,
-    Key_F4,
-    Key_F5,
-    Key_F6,
-    Key_F7,
-    Key_F8,
-    Key_F9,
-    Key_F10,
-    Key_F11,
-    Key_F12,
-    Key_Space,
-    Key_ExclamationPoint,
-    Key_DoubleQuote,
-    Key_Hashtag,
-    Key_Dollar,
-    Key_Percent,
-    Key_Ampersand,
-    Key_Apostrophe,
-    Key_LeftParen,
-    Key_RightParen,
-    Key_Asterisk,
-    Key_Plus,
-    Key_Comma,
-    Key_Minus,
-    Key_Period,
-    Key_Slash,
-    Key_0,
-    Key_1,
-    Key_2,
-    Key_3,
-    Key_4,
-    Key_5,
-    Key_6,
-    Key_7,
-    Key_8,
-    Key_9,
-    Key_Colon,
-    Key_Semicolon,
-    Key_LessThan,
-    Key_Equal,
-    Key_GreaterThan,
-    Key_QuestionMark,
-    Key_AtSign,
-    Key_A,
-    Key_B,
-    Key_C,
-    Key_D,
-    Key_E,
-    Key_F,
-    Key_G,
-    Key_H,
-    Key_I,
-    Key_J,
-    Key_K,
-    Key_L,
-    Key_M,
-    Key_N,
-    Key_O,
-    Key_P,
-    Key_Q,
-    Key_R,
-    Key_S,
-    Key_T,
-    Key_U,
-    Key_V,
-    Key_W,
-    Key_X,
-    Key_Y,
-    Key_Z,
-    Key_LeftBracket,
-    Key_RightBracket,
-    Key_Backslash,
-    Key_Circumflex,
-    Key_Underscore,
-    Key_LeftBrace,
-    Key_RightBrace,
-    Key_Pipe,
-    Key_Tilde,
-    Key_Backtick,
-};
-
 class Keyboard final : public IRQHandler, public CharacterDevice {
     AK_MAKE_ETERNAL
 public:

+ 0 - 10
LibGUI/GEvent.h

@@ -99,16 +99,6 @@ enum class GMouseButton : byte {
     Middle = 4,
 };
 
-enum GKeyboardKey {
-    Invalid,
-    LeftArrow,
-    RightArrow,
-    UpArrow,
-    DownArrow,
-    Backspace,
-    Return,
-};
-
 class GKeyEvent final : public GEvent {
 public:
     GKeyEvent(Type type, int key)

+ 16 - 0
LibGUI/GEventLoop.cpp

@@ -83,6 +83,17 @@ void GEventLoop::handle_paint_event(const GUI_Event& event, GWindow& window)
     post_event(&window, make<GPaintEvent>(event.paint.rect));
 }
 
+void GEventLoop::handle_key_event(const GUI_Event& event, GWindow& window)
+{
+    auto key_event = make<GKeyEvent>(event.type == GUI_Event::Type::KeyDown ? GEvent::KeyDown : GEvent::KeyUp, event.key.key);
+    key_event->m_alt = event.key.alt;
+    key_event->m_ctrl = event.key.ctrl;
+    key_event->m_shift = event.key.shift;
+    if (event.key.character != '\0')
+        key_event->m_text = String(&event.key.character, 1);
+    post_event(&window, move(key_event));
+}
+
 void GEventLoop::handle_mouse_event(const GUI_Event& event, GWindow& window)
 {
     GMouseEvent::Type type;
@@ -149,6 +160,11 @@ void GEventLoop::wait_for_event()
         case GUI_Event::Type::WindowDeactivated:
             dbgprintf("WID=%x WindowDeactivated\n", event.window_id);
             break;
+        case GUI_Event::Type::KeyDown:
+        case GUI_Event::Type::KeyUp:
+            dbgprintf("WID=%x KeyEvent character=0x%b\n", event.window_id, event.key.character);
+            handle_key_event(event, *window);
+            break;
         }
     }
 }

+ 1 - 0
LibGUI/GEventLoop.h

@@ -27,6 +27,7 @@ private:
     void wait_for_event();
     void handle_paint_event(const GUI_Event&, GWindow&);
     void handle_mouse_event(const GUI_Event&, GWindow&);
+    void handle_key_event(const GUI_Event&, GWindow&);
 
     struct QueuedEvent {
         GObject* receiver { nullptr };

+ 5 - 4
LibGUI/GTextBox.cpp

@@ -3,6 +3,7 @@
 #include <SharedGraphics/CharacterBitmap.h>
 #include <SharedGraphics/Font.h>
 #include <SharedGraphics/Painter.h>
+#include <Kernel/KeyCode.h>
 
 GTextBox::GTextBox(GWidget* parent)
     : GWidget(parent)
@@ -91,21 +92,21 @@ void GTextBox::handle_backspace()
 void GTextBox::keydown_event(GKeyEvent& event)
 {
     switch (event.key()) {
-    case GKeyboardKey::LeftArrow:
+    case KeyCode::Key_Left:
         if (m_cursorPosition)
             --m_cursorPosition;
         m_cursorBlinkState = true;
         update();
         return;
-    case GKeyboardKey::RightArrow:
+    case KeyCode::Key_Right:
         if (m_cursorPosition < m_text.length())
             ++m_cursorPosition;
         m_cursorBlinkState = true;
         update();
         return;
-    case GKeyboardKey::Backspace:
+    case KeyCode::Key_Backspace:
         return handle_backspace();
-    case GKeyboardKey::Return:
+    case KeyCode::Key_Return:
         if (onReturnPressed)
             onReturnPressed(*this);
         return;

+ 16 - 0
LibGUI/GWindow.cpp

@@ -96,6 +96,12 @@ void GWindow::event(GEvent& event)
         ASSERT(rc == 0);
     }
 
+    if (event.is_key_event()) {
+        if (!m_focused_widget)
+            return;
+        return m_focused_widget->event(event);
+    }
+
     return GObject::event(event);
 }
 
@@ -128,3 +134,13 @@ void GWindow::set_main_widget(GWidget* widget)
         widget->set_window(this);
     update();
 }
+
+void GWindow::set_focused_widget(GWidget* widget)
+{
+    if (m_focused_widget == widget)
+        return;
+    if (m_focused_widget)
+        m_focused_widget->update();
+    m_focused_widget = widget;
+    m_focused_widget->update();
+}

+ 2 - 0
LibGUI/GWindow.h

@@ -38,6 +38,7 @@ public:
     GWidget* main_widget() { return m_main_widget; }
     const GWidget* main_widget() const { return m_main_widget; }
     void set_main_widget(GWidget*);
+    void set_focused_widget(GWidget*);
 
     void show();
 
@@ -47,5 +48,6 @@ private:
     RetainPtr<GraphicsBitmap> m_backing;
     int m_window_id { -1 };
     GWidget* m_main_widget { nullptr };
+    GWidget* m_focused_widget { nullptr };
 };
 

+ 6 - 0
Userland/guitest2.cpp

@@ -13,6 +13,7 @@
 #include <LibGUI/GLabel.h>
 #include <LibGUI/GButton.h>
 #include <LibGUI/GEventLoop.h>
+#include <LibGUI/GTextBox.h>
 
 static GWindow* make_font_test_window();
 static GWindow* make_launcher_window();
@@ -107,5 +108,10 @@ GWindow* make_launcher_window()
     dummy_button->set_relative_rect({ 5, 80, 90, 20 });
     dummy_button->set_caption("Dummy");
 
+    auto* textbox = new GTextBox(widget);
+    textbox->set_relative_rect({ 5, 110, 90, 20 });
+
+    window->set_focused_widget(textbox);
+
     return window;
 }

+ 8 - 0
WindowServer/WSWindow.cpp

@@ -90,6 +90,14 @@ void WSWindow::on_message(WSMessage& message)
         gui_event.key.ctrl = static_cast<WSKeyEvent&>(message).ctrl();
         gui_event.key.shift = static_cast<WSKeyEvent&>(message).shift();
         break;
+    case WSMessage::KeyUp:
+        gui_event.type = GUI_Event::Type::KeyUp;
+        gui_event.key.character = static_cast<WSKeyEvent&>(message).character();
+        gui_event.key.key = static_cast<WSKeyEvent&>(message).key();
+        gui_event.key.alt = static_cast<WSKeyEvent&>(message).alt();
+        gui_event.key.ctrl = static_cast<WSKeyEvent&>(message).ctrl();
+        gui_event.key.shift = static_cast<WSKeyEvent&>(message).shift();
+        break;
     case WSMessage::WM_ClientFinishedPaint:
         WSWindowManager::the().invalidate(*this, static_cast<WSClientFinishedPaintMessage&>(message).rect());
         return;