⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menus.c

📁 SEAL是DOS 下的32位保护模式的GUI程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************
 * 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 + -