mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:48:11 +00:00
Add API's and plumbing for WindowServer clients to make menus.
This commit is contained in:
parent
bb31d961b4
commit
133706d697
17 changed files with 322 additions and 24 deletions
|
@ -81,7 +81,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
auto help_menu = make<GMenu>("?");
|
auto help_menu = make<GMenu>("?");
|
||||||
help_menu->add_item(2, "About");
|
help_menu->add_item(2, "About");
|
||||||
menubar->add_menu(move(app_menu));
|
menubar->add_menu(move(help_menu));
|
||||||
|
|
||||||
app.set_menubar(move(menubar));
|
app.set_menubar(move(menubar));
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,14 @@ public:
|
||||||
int gui$get_window_rect(int window_id, GUI_Rect*);
|
int gui$get_window_rect(int window_id, GUI_Rect*);
|
||||||
int gui$set_window_rect(int window_id, const GUI_Rect*);
|
int gui$set_window_rect(int window_id, const GUI_Rect*);
|
||||||
int gui$set_global_cursor_tracking_enabled(int window_id, bool enabled);
|
int gui$set_global_cursor_tracking_enabled(int window_id, bool enabled);
|
||||||
|
int gui$menubar_create();
|
||||||
|
int gui$menubar_destroy(int menubar_id);
|
||||||
|
int gui$menubar_add_menu(int menubar_id, int menu_id);
|
||||||
|
int gui$menu_create(const char* name);
|
||||||
|
int gui$menu_destroy(int menu_id);
|
||||||
|
int gui$menu_add_separator(int menu_id);
|
||||||
|
int gui$menu_add_item(int menu_id, unsigned identifier, const char* text);
|
||||||
|
int gui$set_menubar(int menubar_id);
|
||||||
|
|
||||||
DisplayInfo set_video_resolution(int width, int height);
|
DisplayInfo set_video_resolution(int width, int height);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <WindowServer/WSMessageLoop.h>
|
#include <WindowServer/WSMessageLoop.h>
|
||||||
#include <WindowServer/WSWindow.h>
|
#include <WindowServer/WSWindow.h>
|
||||||
#include <WindowServer/WSWindowManager.h>
|
#include <WindowServer/WSWindowManager.h>
|
||||||
|
#include <WindowServer/WSMenuBar.h>
|
||||||
#include <Kernel/BochsVGADevice.h>
|
#include <Kernel/BochsVGADevice.h>
|
||||||
|
|
||||||
//#define LOG_GUI_SYSCALLS
|
//#define LOG_GUI_SYSCALLS
|
||||||
|
@ -284,3 +285,48 @@ DisplayInfo Process::set_video_resolution(int width, int height)
|
||||||
BochsVGADevice::the().set_resolution(width, height);
|
BochsVGADevice::the().set_resolution(width, height);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Process::gui$menubar_create()
|
||||||
|
{
|
||||||
|
return WSWindowManager::the().api$menubar_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$menubar_destroy(int menubar_id)
|
||||||
|
{
|
||||||
|
return WSWindowManager::the().api$menubar_destroy(menubar_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$menubar_add_menu(int menubar_id, int menu_id)
|
||||||
|
{
|
||||||
|
return WSWindowManager::the().api$menubar_add_menu(menubar_id, menu_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$menu_create(const char* name)
|
||||||
|
{
|
||||||
|
if (!validate_read_str(name))
|
||||||
|
return -EFAULT;
|
||||||
|
return WSWindowManager::the().api$menu_create(String(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$menu_destroy(int menu_id)
|
||||||
|
{
|
||||||
|
return WSWindowManager::the().api$menu_destroy(menu_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$menu_add_separator(int menu_id)
|
||||||
|
{
|
||||||
|
return WSWindowManager::the().api$menu_add_separator(menu_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$menu_add_item(int menu_id, unsigned identifier, const char* text)
|
||||||
|
{
|
||||||
|
if (!validate_read_str(text))
|
||||||
|
return -EFAULT;
|
||||||
|
return WSWindowManager::the().api$menu_add_item(menu_id, identifier, String(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::gui$set_menubar(int menubar_id)
|
||||||
|
{
|
||||||
|
kprintf("gui$set_menubar %d\n", menubar_id);
|
||||||
|
return WSWindowManager::the().api$app_set_menubar(menubar_id);
|
||||||
|
}
|
||||||
|
|
|
@ -223,6 +223,22 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
|
||||||
return current->sys$rmdir((const char*)arg1);
|
return current->sys$rmdir((const char*)arg1);
|
||||||
case Syscall::SC_chmod:
|
case Syscall::SC_chmod:
|
||||||
return current->sys$chmod((const char*)arg1, (mode_t)arg2);
|
return current->sys$chmod((const char*)arg1, (mode_t)arg2);
|
||||||
|
case Syscall::SC_gui_menubar_create:
|
||||||
|
return current->gui$menubar_create();
|
||||||
|
case Syscall::SC_gui_menubar_destroy:
|
||||||
|
return current->gui$menubar_destroy((int)arg1);
|
||||||
|
case Syscall::SC_gui_menubar_add_menu:
|
||||||
|
return current->gui$menubar_add_menu((int)arg1, (int)arg2);
|
||||||
|
case Syscall::SC_gui_menu_create:
|
||||||
|
return current->gui$menu_create((const char*)arg1);
|
||||||
|
case Syscall::SC_gui_menu_destroy:
|
||||||
|
return current->gui$menu_destroy((int)arg1);
|
||||||
|
case Syscall::SC_gui_menu_add_separator:
|
||||||
|
return current->gui$menu_add_separator((int)arg1);
|
||||||
|
case Syscall::SC_gui_menu_add_item:
|
||||||
|
return current->gui$menu_add_item((int)arg1, (unsigned)arg2, (const char*)arg3);
|
||||||
|
case Syscall::SC_gui_app_set_menubar:
|
||||||
|
return current->gui$set_menubar((int)arg1);
|
||||||
default:
|
default:
|
||||||
kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
|
kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -85,6 +85,14 @@
|
||||||
__ENUMERATE_SYSCALL(rmdir) \
|
__ENUMERATE_SYSCALL(rmdir) \
|
||||||
__ENUMERATE_SYSCALL(chmod) \
|
__ENUMERATE_SYSCALL(chmod) \
|
||||||
__ENUMERATE_SYSCALL(usleep) \
|
__ENUMERATE_SYSCALL(usleep) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menubar_create) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menubar_destroy) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menubar_add_menu) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menu_create) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menu_destroy) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menu_add_separator) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_menu_add_item) \
|
||||||
|
__ENUMERATE_SYSCALL(gui_app_set_menubar) \
|
||||||
|
|
||||||
|
|
||||||
#ifdef SERENITY
|
#ifdef SERENITY
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
__ERROR(EBADWINDOW, "Bad window ID") \
|
__ERROR(EBADWINDOW, "Bad window ID") \
|
||||||
__ERROR(EBADBACKING, "Bad backing store ID") \
|
__ERROR(EBADBACKING, "Bad backing store ID") \
|
||||||
__ERROR(ENOTEMPTY, "Directory not empty") \
|
__ERROR(ENOTEMPTY, "Directory not empty") \
|
||||||
|
__ERROR(EBADMENUBAR, "Bad menubar ID") \
|
||||||
|
__ERROR(EBADMENU, "Bad menu ID") \
|
||||||
|
|
||||||
|
|
||||||
enum __errno_values {
|
enum __errno_values {
|
||||||
|
|
48
LibC/gui.cpp
48
LibC/gui.cpp
|
@ -68,3 +68,51 @@ int gui_set_global_cursor_tracking_enabled(int window_id, bool enabled)
|
||||||
int rc = syscall(SC_gui_set_global_cursor_tracking_enabled, window_id, enabled);
|
int rc = syscall(SC_gui_set_global_cursor_tracking_enabled, window_id, enabled);
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gui_menubar_create()
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menubar_create);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_menubar_destroy(int menubar_id)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menubar_destroy, menubar_id);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_menubar_add_menu(int menubar_id, int menu_id)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menubar_add_menu, menubar_id, menu_id);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_menu_create(const char* name)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menu_create, name);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_menu_destroy(int menu_id)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menu_destroy, menu_id);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_menu_add_separator(int menu_id)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menu_add_separator, menu_id);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_menu_add_item(int menu_id, unsigned identifier, const char* text)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_menu_add_item, menu_id, identifier, text);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gui_app_set_menubar(int menubar_id)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_gui_app_set_menubar, menubar_id);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,14 @@ int gui_set_window_title(int window_id, const char*, size_t);
|
||||||
int gui_get_window_rect(int window_id, GUI_Rect*);
|
int gui_get_window_rect(int window_id, GUI_Rect*);
|
||||||
int gui_set_window_rect(int window_id, const GUI_Rect*);
|
int gui_set_window_rect(int window_id, const GUI_Rect*);
|
||||||
int gui_set_global_cursor_tracking_enabled(int window_id, bool);
|
int gui_set_global_cursor_tracking_enabled(int window_id, bool);
|
||||||
|
int gui_menubar_create();
|
||||||
|
int gui_menubar_destroy(int menubar_id);
|
||||||
|
int gui_menubar_add_menu(int menubar_id, int menu_id);
|
||||||
|
int gui_menu_create(const char* name);
|
||||||
|
int gui_menu_destroy(int menu_id);
|
||||||
|
int gui_menu_add_separator(int menu_id);
|
||||||
|
int gui_menu_add_item(int menu_id, unsigned identifier, const char* text);
|
||||||
|
int gui_app_set_menubar(int menubar_id);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <LibGUI/GMenu.h>
|
#include <LibGUI/GMenu.h>
|
||||||
|
#include <LibC/gui.h>
|
||||||
|
|
||||||
GMenu::GMenu(const String& name)
|
GMenu::GMenu(const String& name)
|
||||||
: m_name(name)
|
: m_name(name)
|
||||||
|
@ -7,6 +8,10 @@ GMenu::GMenu(const String& name)
|
||||||
|
|
||||||
GMenu::~GMenu()
|
GMenu::~GMenu()
|
||||||
{
|
{
|
||||||
|
if (m_menu_id) {
|
||||||
|
gui_menu_destroy(m_menu_id);
|
||||||
|
m_menu_id = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMenu::add_item(unsigned identifier, const String& text)
|
void GMenu::add_item(unsigned identifier, const String& text)
|
||||||
|
@ -18,3 +23,16 @@ void GMenu::add_separator()
|
||||||
{
|
{
|
||||||
m_items.append(GMenuItem(GMenuItem::Separator));
|
m_items.append(GMenuItem(GMenuItem::Separator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GMenu::realize_menu()
|
||||||
|
{
|
||||||
|
m_menu_id = gui_menu_create(m_name.characters());
|
||||||
|
ASSERT(m_menu_id > 0);
|
||||||
|
for (auto& item : m_items) {
|
||||||
|
if (item.type() == GMenuItem::Separator)
|
||||||
|
gui_menu_add_separator(m_menu_id);
|
||||||
|
else if (item.type() == GMenuItem::Text)
|
||||||
|
gui_menu_add_item(m_menu_id, item.identifier(), item.text().characters());
|
||||||
|
}
|
||||||
|
return m_menu_id;
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ public:
|
||||||
void add_separator();
|
void add_separator();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class GMenuBar;
|
||||||
|
int menu_id() const { return m_menu_id; }
|
||||||
|
int realize_menu();
|
||||||
|
|
||||||
|
int m_menu_id { 0 };
|
||||||
String m_name;
|
String m_name;
|
||||||
Vector<GMenuItem> m_items;
|
Vector<GMenuItem> m_items;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <LibGUI/GMenuBar.h>
|
#include <LibGUI/GMenuBar.h>
|
||||||
|
#include <LibC/gui.h>
|
||||||
|
|
||||||
GMenuBar::GMenuBar()
|
GMenuBar::GMenuBar()
|
||||||
{
|
{
|
||||||
|
@ -15,8 +16,22 @@ void GMenuBar::add_menu(OwnPtr<GMenu>&& menu)
|
||||||
|
|
||||||
void GMenuBar::notify_added_to_application(Badge<GApplication>)
|
void GMenuBar::notify_added_to_application(Badge<GApplication>)
|
||||||
{
|
{
|
||||||
|
ASSERT(!m_menubar_id);
|
||||||
|
m_menubar_id = gui_menubar_create();
|
||||||
|
ASSERT(m_menubar_id > 0);
|
||||||
|
for (auto& menu : m_menus) {
|
||||||
|
ASSERT(menu);
|
||||||
|
int menu_id = menu->realize_menu();
|
||||||
|
ASSERT(menu_id > 0);
|
||||||
|
int rc = gui_menubar_add_menu(m_menubar_id, menu_id);
|
||||||
|
ASSERT(rc == 0);
|
||||||
|
}
|
||||||
|
gui_app_set_menubar(m_menubar_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMenuBar::notify_removed_from_application(Badge<GApplication>)
|
void GMenuBar::notify_removed_from_application(Badge<GApplication>)
|
||||||
{
|
{
|
||||||
|
ASSERT(m_menubar_id);
|
||||||
|
gui_menubar_destroy(m_menubar_id);
|
||||||
|
m_menubar_id = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,5 +18,6 @@ public:
|
||||||
void notify_removed_from_application(Badge<GApplication>);
|
void notify_removed_from_application(Badge<GApplication>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int m_menubar_id { 0 };
|
||||||
Vector<OwnPtr<GMenu>> m_menus;
|
Vector<OwnPtr<GMenu>> m_menus;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include <SharedGraphics/Painter.h>
|
#include <SharedGraphics/Painter.h>
|
||||||
#include <SharedGraphics/Font.h>
|
#include <SharedGraphics/Font.h>
|
||||||
|
|
||||||
WSMenu::WSMenu(const String& name)
|
WSMenu::WSMenu(int menu_id, String&& name)
|
||||||
: m_name(name)
|
: m_menu_id(menu_id)
|
||||||
|
, m_name(move(name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,11 @@ class Font;
|
||||||
|
|
||||||
class WSMenu {
|
class WSMenu {
|
||||||
public:
|
public:
|
||||||
WSMenu(const String& name);
|
WSMenu(int menu_id, String&& name);
|
||||||
~WSMenu();
|
~WSMenu();
|
||||||
|
|
||||||
|
int menu_id() const { return m_menu_id; }
|
||||||
|
|
||||||
WSMenuBar* menu_bar() { return m_menubar; }
|
WSMenuBar* menu_bar() { return m_menubar; }
|
||||||
const WSMenuBar* menu_bar() const { return m_menubar; }
|
const WSMenuBar* menu_bar() const { return m_menubar; }
|
||||||
|
|
||||||
|
@ -70,6 +72,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void did_activate(WSMenuItem&);
|
void did_activate(WSMenuItem&);
|
||||||
|
|
||||||
|
int m_menu_id { 0 };
|
||||||
String m_name;
|
String m_name;
|
||||||
Rect m_rect_in_menubar;
|
Rect m_rect_in_menubar;
|
||||||
Rect m_text_rect_in_menubar;
|
Rect m_text_rect_in_menubar;
|
||||||
|
|
|
@ -8,7 +8,7 @@ public:
|
||||||
WSMenuBar();
|
WSMenuBar();
|
||||||
~WSMenuBar();
|
~WSMenuBar();
|
||||||
|
|
||||||
void add_menu(OwnPtr<WSMenu>&& menu) { m_menus.append(move(menu)); }
|
void add_menu(WSMenu* menu) { m_menus.append(menu); }
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each_menu(Callback callback)
|
void for_each_menu(Callback callback)
|
||||||
|
@ -20,5 +20,5 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<OwnPtr<WSMenu>> m_menus;
|
Vector<WSMenu*> m_menus;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <SharedGraphics/CharacterBitmap.h>
|
#include <SharedGraphics/CharacterBitmap.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
#include <Kernel/BochsVGADevice.h>
|
#include <Kernel/BochsVGADevice.h>
|
||||||
|
#include <LibC/errno_numbers.h>
|
||||||
#include "WSMenu.h"
|
#include "WSMenu.h"
|
||||||
#include "WSMenuBar.h"
|
#include "WSMenuBar.h"
|
||||||
#include "WSMenuItem.h"
|
#include "WSMenuItem.h"
|
||||||
|
@ -185,28 +186,28 @@ WSWindowManager::WSWindowManager()
|
||||||
|
|
||||||
{
|
{
|
||||||
byte system_menu_name[] = { 0xfc, 0 };
|
byte system_menu_name[] = { 0xfc, 0 };
|
||||||
auto menu = make<WSMenu>(String((const char*)system_menu_name));
|
auto& menu = create_menu(String((const char*)system_menu_name));
|
||||||
menu->add_item(make<WSMenuItem>(0, "Launch Terminal"));
|
menu.add_item(make<WSMenuItem>(0, "Launch Terminal"));
|
||||||
menu->add_item(make<WSMenuItem>(WSMenuItem::Separator));
|
menu.add_item(make<WSMenuItem>(WSMenuItem::Separator));
|
||||||
menu->add_item(make<WSMenuItem>(1, "Hello again"));
|
menu.add_item(make<WSMenuItem>(1, "Hello again"));
|
||||||
menu->add_item(make<WSMenuItem>(2, "To all my friends"));
|
menu.add_item(make<WSMenuItem>(2, "To all my friends"));
|
||||||
menu->add_item(make<WSMenuItem>(3, "Together we can play some rock&roll"));
|
menu.add_item(make<WSMenuItem>(3, "Together we can play some rock&roll"));
|
||||||
menu->add_item(make<WSMenuItem>(WSMenuItem::Separator));
|
menu.add_item(make<WSMenuItem>(WSMenuItem::Separator));
|
||||||
menu->add_item(make<WSMenuItem>(4, "About..."));
|
menu.add_item(make<WSMenuItem>(4, "About..."));
|
||||||
menu->on_item_activation = [] (WSMenuItem& item) {
|
menu.on_item_activation = [] (WSMenuItem& item) {
|
||||||
kprintf("WSMenu 1 item activated: '%s'\n", item.text().characters());
|
kprintf("WSMenu 1 item activated: '%s'\n", item.text().characters());
|
||||||
};
|
};
|
||||||
menubar->add_menu(move(menu));
|
menubar->add_menu(&menu);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto menu = make<WSMenu>("Dummy");
|
auto& menu = create_menu("Dummy");
|
||||||
menu->add_item(make<WSMenuItem>(5, "Foo."));
|
menu.add_item(make<WSMenuItem>(5, "Foo."));
|
||||||
menu->add_item(make<WSMenuItem>(6, "Bar?"));
|
menu.add_item(make<WSMenuItem>(6, "Bar?"));
|
||||||
menu->add_item(make<WSMenuItem>(7, "Baz!"));
|
menu.add_item(make<WSMenuItem>(7, "Baz!"));
|
||||||
menu->on_item_activation = [] (WSMenuItem& item) {
|
menu.on_item_activation = [] (WSMenuItem& item) {
|
||||||
kprintf("WSMenu 2 item activated: '%s'\n", item.text().characters());
|
kprintf("WSMenu 2 item activated: '%s'\n", item.text().characters());
|
||||||
};
|
};
|
||||||
menubar->add_menu(move(menu));
|
menubar->add_menu(&menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_current_menubar(menubar.ptr());
|
set_current_menubar(menubar.ptr());
|
||||||
|
@ -223,11 +224,10 @@ WSWindowManager::~WSWindowManager()
|
||||||
|
|
||||||
void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
|
void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
|
||||||
{
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
if (m_current_menubar == menubar)
|
if (m_current_menubar == menubar)
|
||||||
return;
|
return;
|
||||||
m_current_menubar = menubar;
|
m_current_menubar = menubar;
|
||||||
if (!m_current_menubar)
|
|
||||||
return;
|
|
||||||
int menu_margin = 16;
|
int menu_margin = 16;
|
||||||
Point next_menu_location { menu_margin / 2, 3 };
|
Point next_menu_location { menu_margin / 2, 3 };
|
||||||
m_current_menubar->for_each_menu([&] (WSMenu& menu) {
|
m_current_menubar->for_each_menu([&] (WSMenu& menu) {
|
||||||
|
@ -237,6 +237,7 @@ void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
|
||||||
next_menu_location.move_by(menu.rect_in_menubar().width(), 0);
|
next_menu_location.move_by(menu.rect_in_menubar().width(), 0);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* s_close_button_bitmap_data = {
|
static const char* s_close_button_bitmap_data = {
|
||||||
|
@ -445,6 +446,7 @@ void WSWindowManager::handle_close_button_mouse_event(WSWindow& window, WSMouseE
|
||||||
|
|
||||||
void WSWindowManager::process_mouse_event(WSMouseEvent& event)
|
void WSWindowManager::process_mouse_event(WSMouseEvent& event)
|
||||||
{
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
if (event.type() == WSMessage::MouseUp && event.button() == MouseButton::Left) {
|
if (event.type() == WSMessage::MouseUp && event.button() == MouseButton::Left) {
|
||||||
if (m_drag_window) {
|
if (m_drag_window) {
|
||||||
#ifdef DRAG_DEBUG
|
#ifdef DRAG_DEBUG
|
||||||
|
@ -770,3 +772,106 @@ void WSWindowManager::close_menu(WSMenu& menu)
|
||||||
ASSERT(m_current_menu == &menu);
|
ASSERT(m_current_menu == &menu);
|
||||||
close_current_menu();
|
close_current_menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WSMenu& WSWindowManager::create_menu(String&& name)
|
||||||
|
{
|
||||||
|
int menu_id = m_next_menu_id++;
|
||||||
|
auto menu = make<WSMenu>(menu_id, move(name));
|
||||||
|
auto* menu_ptr = menu.ptr();
|
||||||
|
m_menus.set(menu_id, move(menu));
|
||||||
|
return *menu_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WSWindowManager::api$menubar_create()
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto menubar = make<WSMenuBar>();
|
||||||
|
int menubar_id = m_next_menubar_id++;
|
||||||
|
m_menubars.set(menubar_id, move(menubar));
|
||||||
|
return menubar_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$menubar_destroy(int menubar_id)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto it = m_menubars.find(menubar_id);
|
||||||
|
if (it == m_menubars.end())
|
||||||
|
return -EBADMENUBAR;
|
||||||
|
auto& menubar = *(*it).value;
|
||||||
|
if (&menubar == m_current_menubar)
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
m_menubars.remove(it);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$menubar_add_menu(int menubar_id, int menu_id)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto it = m_menubars.find(menubar_id);
|
||||||
|
if (it == m_menubars.end())
|
||||||
|
return -EBADMENUBAR;
|
||||||
|
auto& menubar = *(*it).value;
|
||||||
|
|
||||||
|
auto jt = m_menus.find(menu_id);
|
||||||
|
if (jt == m_menus.end())
|
||||||
|
return -EBADMENU;
|
||||||
|
auto& menu = *(*jt).value;
|
||||||
|
|
||||||
|
menubar.add_menu(&menu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$menu_create(String&& name)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
return create_menu(move(name)).menu_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$menu_destroy(int menu_id)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto it = m_menus.find(menu_id);
|
||||||
|
if (it == m_menus.end())
|
||||||
|
return -EBADMENU;
|
||||||
|
m_menus.remove(it);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$menu_add_separator(int menu_id)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto it = m_menus.find(menu_id);
|
||||||
|
if (it == m_menus.end())
|
||||||
|
return -EBADMENU;
|
||||||
|
auto& menu = *(*it).value;
|
||||||
|
menu.add_item(make<WSMenuItem>(WSMenuItem::Separator));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$menu_add_item(int menu_id, unsigned identifier, String&& text)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto it = m_menus.find(menu_id);
|
||||||
|
if (it == m_menus.end())
|
||||||
|
return -EBADMENU;
|
||||||
|
auto& menu = *(*it).value;
|
||||||
|
menu.add_item(make<WSMenuItem>(identifier, move(text)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WSWindowManager::api$app_set_menubar(int menubar_id)
|
||||||
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
|
auto it = m_menubars.find(menubar_id);
|
||||||
|
if (it == m_menubars.end())
|
||||||
|
return -EBADMENUBAR;
|
||||||
|
auto& menubar = *(*it).value;
|
||||||
|
if (&menubar == m_current_menubar)
|
||||||
|
return 0;
|
||||||
|
set_current_menubar(&menubar);
|
||||||
|
// FIXME: Maybe leave the system menu even if the app menu changes?
|
||||||
|
close_current_menu();
|
||||||
|
invalidate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,15 @@ public:
|
||||||
|
|
||||||
void close_menu(WSMenu&);
|
void close_menu(WSMenu&);
|
||||||
|
|
||||||
|
int api$menubar_create();
|
||||||
|
int api$menubar_destroy(int menubar_id);
|
||||||
|
int api$menubar_add_menu(int menubar_id, int menu_id);
|
||||||
|
int api$menu_create(String&&);
|
||||||
|
int api$menu_destroy(int menu_id);
|
||||||
|
int api$menu_add_separator(int menu_id);
|
||||||
|
int api$menu_add_item(int menu_id, unsigned identifier, String&& text);
|
||||||
|
int api$app_set_menubar(int menubar_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WSWindowManager();
|
WSWindowManager();
|
||||||
virtual ~WSWindowManager() override;
|
virtual ~WSWindowManager() override;
|
||||||
|
@ -66,6 +75,7 @@ private:
|
||||||
void set_active_window(WSWindow*);
|
void set_active_window(WSWindow*);
|
||||||
|
|
||||||
void close_current_menu();
|
void close_current_menu();
|
||||||
|
WSMenu& create_menu(String&& name);
|
||||||
|
|
||||||
virtual void on_message(WSMessage&) override;
|
virtual void on_message(WSMessage&) override;
|
||||||
|
|
||||||
|
@ -128,7 +138,11 @@ private:
|
||||||
Lockable<bool> m_flash_flush;
|
Lockable<bool> m_flash_flush;
|
||||||
bool m_buffers_are_flipped { false };
|
bool m_buffers_are_flipped { false };
|
||||||
|
|
||||||
|
int m_next_menubar_id = 100;
|
||||||
|
int m_next_menu_id = 900;
|
||||||
|
|
||||||
WSMenuBar* m_current_menubar { nullptr };
|
WSMenuBar* m_current_menubar { nullptr };
|
||||||
WSMenu* m_current_menu { nullptr };
|
WSMenu* m_current_menu { nullptr };
|
||||||
HashMap<int, OwnPtr<WSMenuBar>> m_menubars;
|
HashMap<int, OwnPtr<WSMenuBar>> m_menubars;
|
||||||
|
HashMap<int, OwnPtr<WSMenu>> m_menus;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue