Applications/Internet/Cyberia: Add a link context menu and some hanbaga menu placeholders

This commit is contained in:
Alec Murphy
2025-09-24 18:16:26 -04:00
parent 9820018d77
commit ea44c28461

View File

@@ -28,9 +28,10 @@ I64 prev_win_height = -1;
I64 prev_mouse_z = Mouse.z;
Window* hanbaga_menu = Menu.New("Cyberia");
Menu.AddItem(hanbaga_menu, "New Tab", NULL, &Reboot, NULL, NULL);
Menu.AddItem(hanbaga_menu, "New Window", NULL, NULL, NULL, NULL);
Menu.AddItem(hanbaga_menu, "New Private Window", NULL, NULL, NULL, NULL);
Window* link_context_menu = Menu.New("Cyberia");
Bool close_tabs_do_not_ask = FALSE;
Bool close_tabs_toggle_do_not_ask = close_tabs_do_not_ask;
class @browser
{
@@ -116,6 +117,9 @@ U8* @cyberia_urlencode_str(U8* str, I64* output_len)
U0 @cyberia_win_really_close(Window* win)
{
if (close_tabs_toggle_do_not_ask) {
// FIXME: Handle this
}
// Free everything
if (win == Compositor.active_win) {
Gui.Window.SetFocus(Compositor.GetWindowByTitle("Wallpaper"));
@@ -125,13 +129,6 @@ U0 @cyberia_win_really_close(Window* win)
Kill(app_event_loop);
}
U0 @cyberia_win_close(Window* win)
{
if (KeyDown(SC_CTRL) && KeyDown(Char2ScanCode('w')))
return;
@cyberia_win_really_close(win);
}
U8* @browser_tls_connection_state(@http_response* resp)
{
if (!resp || !resp->s || !resp->s->ctx)
@@ -162,7 +159,17 @@ U0 @cyberia_hanbaga_show(Widget* widget)
Gui.Window.Refresh(hanbaga_menu);
}
U0 @cyberia_link_clicked(Widget* widget)
U0 @cyberia_link_context_show(Widget* widget)
{
no_warn widget;
link_context_menu->x = Mouse.x;
link_context_menu->y = Mouse.y;
Gui.Window.Show(link_context_menu);
Gui.Window.SetFocus(link_context_menu);
Gui.Window.Refresh(link_context_menu);
}
U0 @cyberia_link_left_clicked(Widget* widget)
{
@html_dom_node* node = @self_or_ancestor_matches_tag_name(widget->data, "a");
if (!node)
@@ -178,6 +185,23 @@ U0 @cyberia_link_clicked(Widget* widget)
Spawn(&@cyberia_navigate);
}
U0 @cyberia_link_right_clicked(Widget* widget)
{
@cyberia_link_context_show(widget);
}
U0 @cyberia_link_clicked(Widget* widget)
{
if (Compositor.mouse.left) {
@cyberia_link_left_clicked(widget);
return;
}
if (Compositor.mouse.right) {
@cyberia_link_right_clicked(widget);
return;
}
}
U0 @cyberia_collect_form_nodes(JsonArray* array, @html_dom_node* node)
{
if (!array || !node)
@@ -430,6 +454,13 @@ U0 @cyberia_init_renderer(HtmlRenderer* renderer, U8* url_string)
renderer->task = browser_task;
}
U0 @cyberia_msgbox_error_wrapper(U8* msg)
{
while (*msg) {
OutU8(0xe9, *msg++);
}
}
U0 @cyberia_navigate(Bool refresh = FALSE)
{
win->focused_widget = NULL;
@@ -470,14 +501,14 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
if (!renderer->current_url) {
StrCpy(err_msg_buffer, "ERROR: Could not parse URL");
MessageBox.Error(err_msg_buffer);
Spawn(&@cyberia_msgbox_error_wrapper, err_msg_buffer);
Free(url_string);
return;
}
if (!@is_supported_url_scheme(renderer->current_url)) {
StrPrint(err_msg_buffer, "ERROR: Unsupported URL scheme: %s", renderer->current_url->scheme);
MessageBox.Error(err_msg_buffer);
Spawn(&@cyberia_msgbox_error_wrapper, err_msg_buffer);
Free(url_string);
return;
}
@@ -578,10 +609,22 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
@cyberia_history;
@fetch_images_for_page(renderer);
if (!StrCmp(&addressbar1->text, "about:newtab")) {
win->focused_widget = addressbar1;
addressbar1->selected_region_start = 0;
addressbar1->selected_region_end = StrLen(&addressbar1->text) - 1;
}
}
U0 @cyberia_new_tab()
U0 @cyberia_new_tab(Bool from_link_context_menu = FALSE)
{
Gui.Window.SetFocus(win);
Gui.Window.Refresh(win);
U8* new_tab_destination_url = "about:newtab";
if (from_link_context_menu) {
new_tab_destination_url = &status2->text;
}
TabPanelTab* new_tab = CAlloc(sizeof(TabPanelTab));
new_tab->icon = DEFAULT_FAVICON;
StrCpy(&new_tab->text, "New Tab");
@@ -616,7 +659,7 @@ U0 @cyberia_new_tab()
tabpanel1->index = i;
++tabpanel1->count;
StrCpy(&addressbar1->text, "about:newtab");
StrCpy(&addressbar1->text, new_tab_destination_url);
Spawn(&@cyberia_navigate);
win->focused_widget = addressbar1;
}
@@ -906,6 +949,50 @@ U0 @cyberia_init_widgets_base()
}
}
U0 @cyberia_confirm_close_all_tabs(U64 o)
{
// Assign value of win depending on if callback event is on a window, or a widget
Window* dialog = @t(o(Window*)->signature == WIN_SIGNATURE, o, o(Widget*)->parent_win);
if (dialog != o) {
switch (o(Widget*)->tag) {
case TRUE:
Compositor.DestroyWindow(dialog);
@cyberia_win_really_close(win);
return;
case MESSAGEBOX_TAG_CONFIRM_NO_ASK:
close_tabs_toggle_do_not_ask = !close_tabs_toggle_do_not_ask;
return;
default:
// Fall-through to destroy the confirm dialog by default
close_tabs_toggle_do_not_ask = close_tabs_do_not_ask;
break;
}
}
Compositor.DestroyWindow(dialog);
}
U0 @cyberia_close_tabs_confirm_no_ask()
{
if (tabpanel1->count > 1 && !close_tabs_do_not_ask) {
close_tabs_toggle_do_not_ask = close_tabs_do_not_ask;
MessageBox.ConfirmNoAsk("Are you sure you want to close all tabs?", &@cyberia_confirm_close_all_tabs);
} else {
@cyberia_win_really_close(win);
}
}
U0 @cyberia_win_close(Window* win)
{
if (KeyDown(SC_CTRL) && KeyDown(Char2ScanCode('w')))
return;
if (tabpanel1->count > 1 && !close_tabs_do_not_ask) {
close_tabs_toggle_do_not_ask = close_tabs_do_not_ask;
MessageBox.ConfirmNoAsk("Are you sure you want to close all tabs?", &@cyberia_confirm_close_all_tabs);
} else {
@cyberia_win_really_close(win);
}
}
U0 @cyberia_init()
{
win = Compositor.CreateWindow(24, 24, 992, 768, WIN_FLAGS_DEFAULT);
@@ -985,13 +1072,64 @@ U0 @cyberia_init()
@cyberia_win_repaint(win);
}
U0 @cyberia_context_menu_new_tab()
{
@cyberia_new_tab(0);
}
U0 @cyberia_context_menu_open_link_in_new_tab()
{
@cyberia_new_tab(1);
}
U0 @cyberia_copy_link()
{
Gui.Window.SetFocus(win);
Gui.Window.Refresh(win);
Clipboard.Insert(CLIP_TYPE_TEXT, &status2->text);
}
U0 @cyberia_context_menu_null_op()
{
Gui.Window.SetFocus(win);
Gui.Window.Refresh(win);
}
// Initialize context menus
Menu.AddItem(hanbaga_menu, "New Tab", NULL, &@cyberia_context_menu_new_tab, NULL, NULL);
Menu.AddItem(hanbaga_menu, "New Window", NULL, &@cyberia_context_menu_null_op, NULL, NULL)->disabled = TRUE;
Menu.AddItem(hanbaga_menu, "New Private Window", NULL, &@cyberia_context_menu_null_op, NULL, NULL)->disabled = TRUE;
Menu.AddSeparator(hanbaga_menu);
Menu.AddItem(hanbaga_menu, "Bookmarks", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddItem(hanbaga_menu, "History", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddItem(hanbaga_menu, "Downloads", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddSeparator(hanbaga_menu);
Menu.AddItem(hanbaga_menu, "Settings", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddItem(hanbaga_menu, "Help", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddItem(hanbaga_menu, "Quit", NULL, &@cyberia_close_tabs_confirm_no_ask, NULL, NULL);
Menu.AddItem(link_context_menu, "Open Link in New Tab", NULL, &@cyberia_context_menu_open_link_in_new_tab, NULL, NULL);
Menu.AddItem(link_context_menu, "Open Link in New Window", NULL, &@cyberia_context_menu_null_op, NULL, NULL)->disabled = TRUE;
Menu.AddItem(link_context_menu, "Open Link in New Private Window", NULL, &@cyberia_context_menu_null_op, NULL, NULL)->disabled = TRUE;
Menu.AddSeparator(link_context_menu);
Menu.AddItem(link_context_menu, "Bookmark Link", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddItem(link_context_menu, "Save Link as...", NULL, &@cyberia_context_menu_null_op, NULL, NULL);
Menu.AddItem(link_context_menu, "Copy Link", NULL, &@cyberia_copy_link, NULL, NULL);
@cyberia_init;
U0 @cyberia_hide_menu_if_inactive(Window* menu)
{
if (Compositor.active_win != menu && Gui.Window.IsVisible(menu))
Gui.Window.Hide(menu);
}
U0 Main()
{
while (1) {
if (Compositor.active_win != hanbaga_menu && Gui.Window.IsVisible(hanbaga_menu))
Gui.Window.Hide(hanbaga_menu);
@cyberia_hide_menu_if_inactive(hanbaga_menu);
@cyberia_hide_menu_if_inactive(link_context_menu);
Sleep(1);
}
}