📄 menus.c
字号:
/******************************************************************
* SEAL 2.0 *
* Copyright (c) 1999-2002 SEAL Developers. All Rights Reserved. *
* *
* Web site: http://sealsystem.sourceforge.net/ *
* E-mail (current maintainer): orudge@users.sourceforge.net *
******************************************************************/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Revision History (as of 02/04/2002):
*
* 02/04/2002: Made compatible with window skinning (orudge)
*/
#include <seal.h>
#include <menus.h>
#include <skin.h>
p_menuview (*menuview_init) ( p_menuview o, t_rect r, p_menu menu ) = &_menuview_init;
p_menuview (*menuview_init_ex) ( p_menuview o, t_rect r, l_rect item_size, l_rect icon_size, p_menu menu ) = &_menuview_init_ex;
p_menuview (*hormenu_init) ( p_menuview o, t_rect r, p_menu menu ) = &_hormenu_init;
p_menuview (*hormenu_init_ex) ( p_menuview o, t_rect r, l_rect item_size, l_rect icon_size, p_menu menu ) = &_hormenu_init_ex;
l_font* standard_menuitem_font = NULL;
/* t_menuview */
l_bool menuview_done ( p_object o ) {
BITMAP *bmp = MENUVIEW(o)->safe_desktop;
l_bool r = view_done(o);
if ( bmp )
destroy_bitmap(bmp);
return r;
};
void menuview_set_state ( p_object o, l_dword st, l_bool set )
{
if ( set && o->owner_view(o) &&
st & OB_SF_VISIBLE && !o->is_state(o, OB_SF_VISIBLE) ) /* go to be visible */
MENUVIEW(o)->save_desktop(MENUVIEW(o));
view_set_state(o, st, set);
// if ( st & OB_SF_FOCUSED ) /* menu is focused */
// MENUVIEW(o)->draw_current_item(MENUVIEW(o)); /* it take a lot of time => draw_item */
};
void menuview_translate_event ( p_object o, t_event *event )
{
RETVIEW(o, event);
view_translate_event(o, event); /* old translate_event function */
if ( event->type & EV_MOUSE &&
OBJECT(mouse)->state & MO_SF_MOUSELDOWN ) { /* mouse events */
l_dword msg = 0;
clear_event(event);
menu_clear_lastitem_called(MENUVIEW(o)->menu);
msg = desktop->execute_view(desktop, VIEW(o));
if ( msg != MSG_NOTHING && msg != MSG_CANCEL ) {
set_event(event, EV_MESSAGE, msg, o);
};
o->put_event(o, event);
clear_event(event);
if ( o->owner->prefer == o ) /* only one item, so redraw it for */
MENUVIEW(o)->draw_current_item(MENUVIEW(o));
};
};
l_dword menuview_execute ( p_object o )
{
p_view vo = VIEW(o);
p_menuview mo = MENUVIEW(o);
l_int action = MA_NONE;
l_bool iamsub = false;
l_dword message = MSG_NOTHING;
p_menuitem current = mo->menu->current;
if ( mo->action == MA_IAMSUBMENU ) iamsub = true;
mo->inside = true;
mo->draw_current_item(mo);
do {
action = MA_NONE;
o->get_event(o, &event_main);
if ( event_main.type & EV_KEYBOARD )
{
if ( OBJECT(keyb)->state & KB_SF_KEYDOWN ) {
l_dword msg;
switch ( keyb->code >> 8 ) {
case KB_DOWN : current = mo->get_next_item(mo, current, true); break;
case KB_UP : current = mo->get_next_item(mo, current, false); break;
case KB_LEFT : if ( iamsub && mo->parent_menu->menu &&
mo->parent_menu->menu->items &&
mo->parent_menu->menu->items->next ) action = MA_BACKWARD; break;
case KB_ESC : action = MA_ESC; break;
case KB_RIGHT : action = MA_FORWARD; break;
case KB_ENTER : action = MA_ENTER; break;
};
msg = menu_get_hotkey_message(mo->top_menuview(mo)->menu, keyb->code);
if ( msg != MSG_NOTHING ) {
message = msg;
action = MA_END;
} else if ( KEYCTRL(KB_F1) ) /* help info */
_show_info_board(vo, current?current->info_text:NULL);
};
} else
if ( event_main.type & EV_MOUSE ) {
if ( OBJECT(mouse)->state & MO_SF_MOUSEPRESS ) {
if ( vo->is_mouse_in_view(vo) ) { /* mouse is in view */
p_menuitem cur = mo->get_item_from_mouse(mo, mouse->where);
if ( cur ) current = cur;
} else {
if ( !mo->is_mouse_in_one_of_parent_item(mo, mouse->where) &&
mo->is_mouse_in_one_of_parent_menu(mo, mouse->where) )
action = MA_OTHER;
else
if ( OBJECT(mouse)->state & MO_SF_MOUSEDOWN &&
!mo->is_mouse_in_one_of_parent_menu(mo, mouse->where) ) {
action = MA_END;
};
};
} else
if ( OBJECT(mouse)->state & MO_SF_MOUSEUP ) { /* */
if ( vo->is_mouse_in_view(vo) ) { /* mouse is in view */
action = MA_ENTER;
};
};
};
if ( current != mo->menu->current ) { /* redraw items */
p_menuitem old_current = mo->menu->current;
mo->menu->current = current; /* set current item */
if ( old_current != mo->menu->current ) { /* check if not same */
mo->draw_item(mo, old_current);
mo->draw_item(mo, mo->menu->current);
};
};
if ( current ) { /* is some item selected */
if ( action == MA_ENTER && current->enable ) { /* action is command */
if ( current->message || current->flags & MIF_CHECK ) { /* it's command item */
action = MA_COMMAND;
message = current->message;
current->lastcall = true;
if ( current->flags & MIF_CHECK )
if ( current->flags & MIF_CHECKOK ) current->flags &= ~MIF_CHECKOK;
else current->flags |= MIF_CHECKOK;
} else /* it's menu item */
action = MA_SUBMENU;
};
if ( action == MA_SUBMENU || action == MA_FORWARD ) { /* make new sub-menu */
if ( current->submenu ) { /* has some submenu */
t_rect r = mo->get_item_box(mo, current);
r.a.x = r.b.x - 5;
r = rect_move(r, vo->bounds.a.x, vo->bounds.a.y);
message = mo->run_new_menu(mo, r, &action, current->submenu);
if ( action == MA_BACKWARD ||
action == MA_ESC ||
action == MA_OTHER ) action = MA_NONE;
} else /* not sub-menu */
if ( action == MA_FORWARD &&
mo->is_hor_menu_one_of_parents(mo) &&
mo->is_hor_menu_one_of_parents(mo)->menu->items->next ) /* if hor-menu is under me */
action = MA_HMFORWARD; /* set action to hor-menu forward */
};
};
if ( action > 0 ) clear_event(&event_main);
} while ( action > 0 );
if ( action == MA_END ) o->put_event(o, &event_main);
mo->action = action;
mo->inside = false;
vo->hide(vo);
return message;
};
t_rect menuview_size_limits ( p_view o )
{
return rect_assign(2, 2, rect_sizex(o->bounds)-2, rect_sizey(o->bounds)-2);
};
void menuview_draw_under_rect ( p_view o, t_rect r )
{
if ( MENUVIEW(o)->safe_desktop ) {
t_point t = point_assign(0,0);
t_point p = o->get_global_point(o, t);
t_rect nr;
r = rect_move(r,-o->bounds.a.x,-o->bounds.a.y);
nr = rect_move(r,p.x,p.y);
BLIT(MENUVIEW(o)->safe_desktop, screen, r.a.x, r.a.y, nr.a.x, nr.a.y,
rect_sizex(r),//CONTEXT_WIDTH(MENUVIEW(o)->safe_desktop),
rect_sizey(r));//CONTEXT_HEIGHT(MENUVIEW(o)->safe_desktop));
/*destroy_bitmap(MENUVIEW(o)->safe_desktop);
MENUVIEW(o)->safe_desktop = NULL;*/
} else
view_draw_under_rect(o, r);
};
void menuview_draw ( p_view o )
{
t_rect r = o->get_local_extent(o);
t_point p;
l_bool old = o->is_draw_mode(o,DWM_DONTDRAWBACK);
BITMAP *out = NULL;
if ( old ) o->set_draw_mode(o,DWM_DONTDRAWBACK,false);
out = o->begin_paint(o, &p, r);
if ( out ) {
p_menuitem item = MENUVIEW(o)->menu?MENUVIEW(o)->menu->items:NULL;
o->background(o, out, rect_move(r, p.x, p.y));
//button3d(o, out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, 0);
while ( item ) {
MENUVIEW(o)->draw_item(MENUVIEW(o), item);
item = item->next;
};
};
o->end_of_paint(o, r);
if ( old ) o->set_draw_mode(o,DWM_DONTDRAWBACK,true);
};
p_menuview menuview_top_menuview ( p_menuview o )
{
while ( o->parent_menu )
o = o->parent_menu;
return o;
};
l_bool menuview_is_mouse_in_one_of_parent_item ( p_menuview o, t_point p )
{
p_menuview m = o;
while ( m ) {
p_menuitem sel = m->menu?m->menu->current:NULL;
if ( sel && m->get_item_from_mouse(m, p) == sel ) return true;
m = m->parent_menu;
};
return false;
};
l_bool menuview_is_mouse_in_one_of_parent_menu ( p_menuview o, t_point p )
{
p_menuview m = o;
while ( m ) {
if ( m->get_item_from_mouse(m, p) ) return true;
m = m->parent_menu;
};
return false;
};
l_bool menuview_is_one_of_subs_state ( p_menuview o, l_dword st )
{
p_menuview m = o;
while ( m ) {
if ( OBJECT(m)->is_state(OBJECT(m), st) ) return true;
m = m->sub_menu;
};
return false;
};
p_menuitem menuview_get_item_from_mouse ( p_menuview o, t_point p )
{
p_view vo = VIEW(o);
t_rect s = vo->get_local_extent(vo);
p = vo->get_local_point(vo, p);
if ( rect_contains(s, p) ) {
p_menuitem i = o->menu?o->menu->items:NULL;
while ( i ) {
t_rect r = o->get_mouseitem_box(o, i);
if ( rect_contains(r, p) ) return i;
i = i->next;
};
};
return NULL;
};
void menuview_save_desktop ( p_menuview o )
{
t_rect r = VIEW(o)->get_global_bounds(VIEW(o), VIEW(o)->get_local_extent(VIEW(o)));
if ( o->safe_desktop ) return; /* if exist, destroy it */
// destroy_bitmap(MENUVIEW(o)->safe_desktop);
/* create new bitmap */
o->safe_desktop = create_bitmap(rect_sizex(r)+1, rect_sizey(r)+1);
if ( o->safe_desktop ) /* blit screen, if there was enough memory */
BLIT(screen, o->safe_desktop, r.a.x, r.a.y, 0, 0, rect_sizex(r), rect_sizey(r));
};
p_menuview menuview_is_hor_menu_one_of_parents ( p_menuview o )
{
p_menuview m = o;
while ( m ) {
if ( m->flags & MF_HORMENU ) return m;
m = m->parent_menu;
};
return m;
};
p_menuitem menuview_prev_item ( p_menuview o, p_menuitem item )
{
p_menuitem p = item;
p_menuitem first = o->menu?o->menu->items:NULL;
if ( p == first ) p = NULL;
if ( item )
do {
item = o->next_item(o, item);
} while ( item->next != p );
return item;
};
p_menuitem menuview_next_item ( p_menuview o, p_menuitem item )
{
if ( item && item->next )
item = item->next;
else
item = o->menu?o->menu->items:NULL;
return item;
};
p_menuitem menuview_get_next_item ( p_menuview o, p_menuitem item, l_bool forward )
{
p_menuitem old = item;
do {
if ( forward )
item = o->next_item(o, item);
else
item = o->prev_item(o, item);
} while ( item != old && !item->name );
return item;
};
p_menuitem menuview_index_of ( p_menuview o, l_int item )
{
p_menuitem i = o->menu?o->menu->items:NULL;
while ( i ) {
if ( item == 0 ) return i;
item--;
i = i->next;
};
return NULL;
};
l_int menuview_at ( p_menuview o, p_menuitem p )
{
p_menuitem i = o->menu?o->menu->items:NULL;
l_int item = 0;
while ( i ) {
if ( i == p ) return item;
item++;
i = i->next;
};
return -1;
};
void menuview_draw_item_ex ( p_menuview o, p_menuitem i, BITMAP *out, t_point p )
{
p_view vo = VIEW(o);
if ( i ) {
t_rect r = o->get_item_box(o, i);
if ( !rect_check_empty(r) ) {
if ( out ) {
t_rect t = rect_assign(r.a.x+o->between.x+2+STANDARD_MENUBOUNDSDIFF_SIZE, r.a.y, r.b.x-STANDARD_MENUBOUNDSDIFF_SIZE, r.b.y);
t_rect f = rect_assign(r.a.x+STANDARD_MENUBOUNDSDIFF_SIZE, r.a.y, t.a.x, r.b.y);
l_color fcolor = color_menu_text;
//vline(out, r.a.x+p.x-1, r.a.y+p.y, r.b.y+p.y, color_3d_light);
//vline(out, r.b.x+p.x+1, r.a.y+p.y, r.b.y+p.y, color_3d_shadow);
if ( !i->name ) { /* draw LINE */
l_rect dy = (rect_sizey(r)-2/*size of line*/)/2;
vo->background(vo, out, rect_move(r, p.x, p.y));
button(out, r.a.x+p.x+6, r.a.y+p.y+dy+1, r.b.x+p.x-6, r.a.y+p.y+dy+2, color_3d_shadow, color_3d_light);
} else { /* draw ITEM or SUB-MENU */
if ( !o->is_one_of_subs_state(o, OB_SF_SELECTED) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -