Files
BBeOS/docs/phases/PHASE_4_UI.md
Eliott 73fb76098e
Some checks failed
CI / markdown-lint (push) Failing after 14s
Reorganize BBeOS project structure for better maintainability
- Reorganized directory structure following open source best practices
- Created src/ directory for all source code components
- Moved build artifacts to build/ subdirectories
- Organized documentation into phases/, guides/, and api/ subdirectories
- Moved third-party code to vendor/ directory
- Moved downloads to downloads/ directory
- Updated all build scripts to reference new directory structure
- Created comprehensive PROJECT_STRUCTURE.md documentation
- Added DEVELOPMENT_GUIDE.md as main entry point
- Improved separation of concerns and maintainability
- Follows standard open source project conventions
2025-08-01 11:48:06 +02:00

17 KiB

Phase 4: User Interface Layer Development

🎯 Objectives

Create a keyboard-centric, trackpad-optimized graphical user interface that provides an intuitive and efficient user experience for the BlackBerry Classic (Q20).

📋 Detailed Tasks

4.1 Display Server Architecture

4.1.1 Wayland Compositor Selection

Options to Evaluate:

  1. Sway: i3-compatible Wayland compositor
  2. Weston: Reference Wayland compositor
  3. Custom Compositor: Tailored for Q20
  4. Hyprland: Modern tiling compositor

Selection Criteria:

  • Keyboard navigation support
  • Trackpad optimization
  • Resource efficiency
  • Customization flexibility
  • Community maintenance

Evaluation Tasks:

  • Test keyboard shortcuts in each compositor
  • Evaluate trackpad gesture support
  • Measure memory and CPU usage
  • Assess customization capabilities
  • Choose optimal compositor

4.1.2 Custom Compositor Development

Architecture Design:

// Compositor structure
struct q20_compositor {
    struct wl_display *display;
    struct wl_event_loop *event_loop;
    struct wl_listener display_destroy;
    
    // Output management
    struct wl_list outputs;
    struct q20_output *primary_output;
    
    // Input handling
    struct wl_list seats;
    struct q20_seat *primary_seat;
    
    // Window management
    struct wl_list views;
    struct q20_view *focused_view;
    
    // Keyboard shortcuts
    struct wl_list shortcuts;
    struct q20_shortcut *active_shortcut;
};

// Output management
struct q20_output {
    struct wl_list link;
    struct wl_output *wl_output;
    struct q20_compositor *compositor;
    
    // Display properties
    int width, height;
    int refresh_rate;
    int scale;
    
    // Rendering
    struct wl_list views;
    struct q20_view *fullscreen_view;
};

// Input handling
struct q20_seat {
    struct wl_list link;
    struct wl_seat *wl_seat;
    struct q20_compositor *compositor;
    
    // Input devices
    struct wl_list keyboards;
    struct wl_list pointers;
    struct wl_list touch;
    
    // Focus management
    struct q20_view *focused_view;
    struct wl_listener view_destroy;
};

Development Tasks:

  • Design compositor architecture
  • Implement output management
  • Create input handling system
  • Add window management
  • Implement keyboard shortcuts

4.2 Application Framework

4.2.1 UI Framework Selection

Options:

  1. Qt 6: Modern, feature-rich framework
  2. GTK 4: GNOME-based framework
  3. EFL: Enlightenment Foundation Libraries
  4. Custom Framework: Tailored for Q20

Selection Criteria:

  • Wayland support
  • Keyboard navigation
  • Resource efficiency
  • Development productivity
  • Community support

Qt 6 Implementation:

// Main application class
class Q20Application : public QApplication
{
    Q_OBJECT
    
public:
    Q20Application(int &argc, char **argv);
    ~Q20Application();
    
    // Keyboard shortcuts
    void registerShortcut(const QString &key, const QString &action);
    void handleShortcut(const QString &key);
    
    // Window management
    void showHomeScreen();
    void showAppLauncher();
    void showSettings();
    
private:
    // UI components
    Q20HomeScreen *homeScreen;
    Q20AppLauncher *appLauncher;
    Q20Settings *settings;
    
    // Keyboard handling
    QHash<QString, QString> shortcuts;
    QShortcut *shortcutHandler;
};

// Home screen implementation
class Q20HomeScreen : public QWidget
{
    Q_OBJECT
    
public:
    Q20HomeScreen(QWidget *parent = nullptr);
    
public slots:
    void showNotifications();
    void showQuickSettings();
    void launchApp(const QString &appName);
    
private:
    // UI elements
    QVBoxLayout *mainLayout;
    QHBoxLayout *topBar;
    QHBoxLayout *bottomBar;
    
    // Widgets
    QLabel *timeLabel;
    QLabel *batteryLabel;
    QLabel *signalLabel;
    QPushButton *menuButton;
    QPushButton *backButton;
    QPushButton *callButton;
    QPushButton *endButton;
    
    // App shortcuts
    QList<QPushButton*> appButtons;
    
private slots:
    void updateTime();
    void updateBattery();
    void updateSignal();
    void handleMenuClick();
    void handleBackClick();
    void handleCallClick();
    void handleEndClick();
};

4.2.2 Application Launcher

Launcher Design:

// App launcher class
class Q20AppLauncher : public QWidget
{
    Q_OBJECT
    
public:
    Q20AppLauncher(QWidget *parent = nullptr);
    
public slots:
    void showAllApps();
    void showFavorites();
    void searchApps(const QString &query);
    void launchApp(const QString &appName);
    
private:
    // UI layout
    QVBoxLayout *mainLayout;
    QHBoxLayout *searchBar;
    QScrollArea *appGrid;
    QWidget *appContainer;
    QGridLayout *appGridLayout;
    
    // App management
    QList<Q20AppInfo> installedApps;
    QList<Q20AppInfo> favoriteApps;
    
    // Search functionality
    QLineEdit *searchInput;
    QList<Q20AppInfo> searchResults;
    
private slots:
    void populateAppGrid();
    void filterApps(const QString &query);
    void handleAppClick(const QString &appName);
    void toggleFavorite(const QString &appName);
};

// App information structure
struct Q20AppInfo {
    QString name;
    QString displayName;
    QString description;
    QString iconPath;
    QString executable;
    QStringList categories;
    bool isFavorite;
    bool isSystem;
};

4.3 Core Applications

4.3.1 Phone Dialer

Dialer Implementation:

// Phone dialer class
class Q20Dialer : public QWidget
{
    Q_OBJECT
    
public:
    Q20Dialer(QWidget *parent = nullptr);
    
public slots:
    void dialNumber(const QString &number);
    void answerCall();
    void endCall();
    void muteCall();
    void speakerToggle();
    void showContacts();
    void showCallHistory();
    
private:
    // UI components
    QVBoxLayout *mainLayout;
    QHBoxLayout *numberDisplay;
    QGridLayout *keypadLayout;
    QHBoxLayout *callControls;
    
    // Display
    QLineEdit *numberInput;
    QLabel *callerName;
    QLabel *callDuration;
    
    // Keypad
    QList<QPushButton*> numberButtons;
    QPushButton *starButton;
    QPushButton *hashButton;
    QPushButton *deleteButton;
    
    // Call controls
    QPushButton *callButton;
    QPushButton *endButton;
    QPushButton *muteButton;
    QPushButton *speakerButton;
    QPushButton *contactsButton;
    QPushButton *historyButton;
    
    // Call state
    bool inCall;
    QString currentNumber;
    QTimer *callTimer;
    
private slots:
    void handleNumberClick(const QString &number);
    void handleDeleteClick();
    void handleCallClick();
    void handleEndClick();
    void updateCallDuration();
    void handleIncomingCall(const QString &number);
};

4.3.2 SMS Application

SMS Implementation:

// SMS application class
class Q20SMS : public QWidget
{
    Q_OBJECT
    
public:
    Q20SMS(QWidget *parent = nullptr);
    
public slots:
    void sendMessage(const QString &number, const QString &message);
    void receiveMessage(const QString &number, const QString &message);
    void showConversation(const QString &number);
    void showAllConversations();
    void deleteConversation(const QString &number);
    
private:
    // UI layout
    QVBoxLayout *mainLayout;
    QHBoxLayout *topBar;
    QSplitter *mainSplitter;
    
    // Conversation list
    QListWidget *conversationList;
    QList<Q20Conversation> conversations;
    
    // Message view
    QVBoxLayout *messageLayout;
    QTextEdit *messageDisplay;
    QHBoxLayout *inputLayout;
    QLineEdit *messageInput;
    QPushButton *sendButton;
    
    // Current conversation
    QString currentNumber;
    QList<Q20Message> currentMessages;
    
private slots:
    void populateConversationList();
    void handleConversationSelect(const QString &number);
    void handleSendClick();
    void handleMessageReceived(const QString &number, const QString &message);
    void updateConversationList();
};

// Message structure
struct Q20Message {
    QString id;
    QString number;
    QString content;
    QDateTime timestamp;
    bool isIncoming;
    bool isRead;
};

// Conversation structure
struct Q20Conversation {
    QString number;
    QString name;
    QString lastMessage;
    QDateTime lastTimestamp;
    int unreadCount;
};

4.3.3 Settings Application

Settings Implementation:

// Settings application class
class Q20Settings : public QWidget
{
    Q_OBJECT
    
public:
    Q20Settings(QWidget *parent = nullptr);
    
public slots:
    void showGeneralSettings();
    void showDisplaySettings();
    void showSoundSettings();
    void showNetworkSettings();
    void showSecuritySettings();
    void showAbout();
    
private:
    // UI layout
    QVBoxLayout *mainLayout;
    QHBoxLayout *navigationLayout;
    QStackedWidget *settingsStack;
    
    // Navigation
    QListWidget *settingsCategories;
    QList<QString> categoryNames;
    
    // Settings pages
    Q20GeneralSettings *generalSettings;
    Q20DisplaySettings *displaySettings;
    Q20SoundSettings *soundSettings;
    Q20NetworkSettings *networkSettings;
    Q20SecuritySettings *securitySettings;
    Q20AboutPage *aboutPage;
    
private slots:
    void handleCategorySelect(int index);
    void saveSettings();
    void loadSettings();
};

// Display settings
class Q20DisplaySettings : public QWidget
{
    Q_OBJECT
    
public:
    Q20DisplaySettings(QWidget *parent = nullptr);
    
private:
    QVBoxLayout *mainLayout;
    
    // Brightness control
    QHBoxLayout *brightnessLayout;
    QLabel *brightnessLabel;
    QSlider *brightnessSlider;
    QLabel *brightnessValue;
    
    // Backlight timeout
    QHBoxLayout *timeoutLayout;
    QLabel *timeoutLabel;
    QComboBox *timeoutCombo;
    
    // Keyboard backlight
    QHBoxLayout *keyboardLayout;
    QLabel *keyboardLabel;
    QSlider *keyboardSlider;
    QLabel *keyboardValue;
    
    // Auto-rotate
    QHBoxLayout *rotateLayout;
    QLabel *rotateLabel;
    QCheckBox *rotateCheck;
    
private slots:
    void handleBrightnessChange(int value);
    void handleTimeoutChange(const QString &timeout);
    void handleKeyboardChange(int value);
    void handleRotateChange(bool enabled);
};

4.4 Keyboard Navigation System

4.4.1 Keyboard Shortcuts

Shortcut Configuration:

// Keyboard shortcut manager
class Q20ShortcutManager : public QObject
{
    Q_OBJECT
    
public:
    Q20ShortcutManager(QObject *parent = nullptr);
    
    void registerShortcut(const QString &key, const QString &action);
    void unregisterShortcut(const QString &key);
    void handleKeyPress(const QString &key);
    
private:
    QHash<QString, QString> shortcuts;
    QHash<QString, QShortcut*> shortcutObjects;
    
    void setupDefaultShortcuts();
    void handleShortcutAction(const QString &action);
};

// Default shortcuts
void Q20ShortcutManager::setupDefaultShortcuts()
{
    // Navigation shortcuts
    registerShortcut("Alt+Tab", "switch_app");
    registerShortcut("Alt+F4", "close_app");
    registerShortcut("Alt+Enter", "fullscreen");
    registerShortcut("Alt+Space", "menu");
    
    // Phone shortcuts
    registerShortcut("Call", "dialer");
    registerShortcut("End", "end_call");
    registerShortcut("Menu", "app_launcher");
    registerShortcut("Back", "go_back");
    
    // System shortcuts
    registerShortcut("Ctrl+Alt+Del", "task_manager");
    registerShortcut("Ctrl+Alt+Backspace", "restart_ui");
    registerShortcut("Ctrl+Alt+T", "terminal");
    registerShortcut("Ctrl+Alt+S", "settings");
}

4.4.2 Focus Management

Focus System:

// Focus manager
class Q20FocusManager : public QObject
{
    Q_OBJECT
    
public:
    Q20FocusManager(QObject *parent = nullptr);
    
    void setFocusWidget(QWidget *widget);
    QWidget* getFocusedWidget();
    void moveFocus(Qt::Key key);
    void cycleFocus();
    
private:
    QWidget *currentFocus;
    QList<QWidget*> focusableWidgets;
    
    void updateFocusableWidgets();
    QWidget* findNextFocusable(QWidget *current, Qt::Key direction);
    void highlightFocus(QWidget *widget);
};

// Focus movement implementation
void Q20FocusManager::moveFocus(Qt::Key key)
{
    QWidget *nextWidget = nullptr;
    
    switch (key) {
    case Qt::Key_Tab:
        nextWidget = findNextFocusable(currentFocus, Qt::Key_Tab);
        break;
    case Qt::Key_Backtab:
        nextWidget = findNextFocusable(currentFocus, Qt::Key_Backtab);
        break;
    case Qt::Key_Left:
        nextWidget = findNextFocusable(currentFocus, Qt::Key_Left);
        break;
    case Qt::Key_Right:
        nextWidget = findNextFocusable(currentFocus, Qt::Key_Right);
        break;
    case Qt::Key_Up:
        nextWidget = findNextFocusable(currentFocus, Qt::Key_Up);
        break;
    case Qt::Key_Down:
        nextWidget = findNextFocusable(currentFocus, Qt::Key_Down);
        break;
    }
    
    if (nextWidget) {
        setFocusWidget(nextWidget);
    }
}

4.5 Trackpad Optimization

4.5.1 Trackpad Gestures

Gesture Recognition:

// Trackpad gesture manager
class Q20TrackpadManager : public QObject
{
    Q_OBJECT
    
public:
    Q20TrackpadManager(QObject *parent = nullptr);
    
    void handleTrackpadEvent(const QPointF &position, int buttons);
    void handleTrackpadGesture(const QString &gesture);
    
private:
    QPointF lastPosition;
    QPointF startPosition;
    QDateTime lastEvent;
    bool isTracking;
    
    // Gesture detection
    void detectSwipeGesture(const QPointF &current, const QPointF &start);
    void detectPinchGesture(const QPointF &point1, const QPointF &point2);
    void detectTapGesture(const QPointF &position);
    void detectDoubleTapGesture(const QPointF &position);
    
    // Gesture actions
    void handleSwipeLeft();
    void handleSwipeRight();
    void handleSwipeUp();
    void handleSwipeDown();
    void handlePinchIn();
    void handlePinchOut();
    void handleTap();
    void handleDoubleTap();
};

// Gesture detection implementation
void Q20TrackpadManager::detectSwipeGesture(const QPointF &current, const QPointF &start)
{
    QPointF delta = current - start;
    qreal distance = QLineF(start, current).length();
    qreal angle = QLineF(start, current).angle();
    
    // Minimum swipe distance
    if (distance < 50) {
        return;
    }
    
    // Determine swipe direction
    if (angle >= 315 || angle < 45) {
        handleSwipeRight();
    } else if (angle >= 45 && angle < 135) {
        handleSwipeUp();
    } else if (angle >= 135 && angle < 225) {
        handleSwipeLeft();
    } else if (angle >= 225 && angle < 315) {
        handleSwipeDown();
    }
}

4.5.2 Cursor Management

Cursor System:

// Cursor manager
class Q20CursorManager : public QObject
{
    Q_OBJECT
    
public:
    Q20CursorManager(QObject *parent = nullptr);
    
    void setCursorPosition(const QPointF &position);
    void setCursorVisible(bool visible);
    void setCursorShape(Qt::CursorShape shape);
    void animateCursor();
    
private:
    QPointF currentPosition;
    QPointF targetPosition;
    bool isVisible;
    Qt::CursorShape currentShape;
    
    // Cursor animation
    QTimer *animationTimer;
    qreal animationProgress;
    
    void updateCursorPosition();
    void drawCursor();
    void handleAnimation();
};

// Cursor animation
void Q20CursorManager::animateCursor()
{
    if (currentPosition != targetPosition) {
        QPointF delta = targetPosition - currentPosition;
        currentPosition += delta * 0.1; // Smooth interpolation
        
        if (QLineF(currentPosition, targetPosition).length() < 1) {
            currentPosition = targetPosition;
        }
        
        updateCursorPosition();
    }
}

📊 Deliverables

4.6 Complete UI System

Requirements:

  • Functional display server
  • Core applications working
  • Keyboard navigation system
  • Trackpad optimization
  • Settings and customization

4.7 Application Framework

Components:

  • Qt-based application framework
  • Window management system
  • Input handling system
  • Theme and styling system
  • Plugin architecture

4.8 User Experience

Features:

  • Intuitive keyboard navigation
  • Efficient trackpad usage
  • Consistent UI design
  • Responsive interface
  • Accessibility support

⏱️ Timeline

Week 1-2: Display server development Week 3-4: Application framework Week 5-6: Core applications Week 7-8: Keyboard navigation Week 9-10: Trackpad optimization Week 11-12: Testing and refinement

Total Duration: 12 weeks (3 months)

🎯 Success Criteria

Phase 4 is successful when:

  1. Complete UI system is functional
  2. Core applications are working
  3. Keyboard navigation is intuitive
  4. Trackpad gestures are responsive
  5. User experience is polished

🚨 Risk Mitigation

High-Risk Scenarios:

  • Performance issues → Optimize rendering and input handling
  • UI framework complexity → Simplify and modularize
  • Keyboard navigation problems → Improve focus management
  • Trackpad issues → Enhance gesture recognition
  • Application bugs → Implement comprehensive testing