static int action_toggle_scroll(unsigned type, const char *label,
      unsigned action)
{
   unsigned scroll_speed = 0, fast_scroll_speed = 0;
   menu_handle_t *menu = menu_driver_resolve();
   if (!menu)
      return -1;

   scroll_speed      = (max(menu->navigation.scroll.acceleration, 2) - 2) / 4 + 1;
   fast_scroll_speed = 4 + 4 * scroll_speed;

   switch (action)
   {
      case MENU_ACTION_LEFT:
         if (menu->navigation.selection_ptr > fast_scroll_speed)
            menu_navigation_set(&menu->navigation,
                  menu->navigation.selection_ptr - fast_scroll_speed, true);
         else
            menu_navigation_clear(&menu->navigation, false);
         break;
      case MENU_ACTION_RIGHT:
         if (menu->navigation.selection_ptr + fast_scroll_speed < (menu_list_get_size(menu->menu_list)))
            menu_navigation_set(&menu->navigation,
                  menu->navigation.selection_ptr + fast_scroll_speed, true);
         else
         {
            if ((menu_list_get_size(menu->menu_list) > 0))
                  menu_navigation_set_last(&menu->navigation);
         }
         break;
   }

   return 0;
}
示例#2
0
文件: glui.c 项目: SunGuo/RetroArch
static void glui_navigation_set(void *data, bool scroll)
{
   glui_handle_t *glui = NULL;

   menu_handle_t *menu = (menu_handle_t*)data;

   if (!menu)
      return;

   glui = (glui_handle_t*)menu->userdata;

   if (!glui)
      return;

   if (!scroll)
      return;

   if (driver.menu->selection_ptr < glui->term_height/2)
      driver.menu->begin = 0;
   else if (driver.menu->selection_ptr >= glui->term_height/2
         && driver.menu->selection_ptr <
         menu_list_get_size(driver.menu->menu_list) - glui->term_height/2)
      driver.menu->begin = driver.menu->selection_ptr - glui->term_height/2;
   else if (driver.menu->selection_ptr >=
         menu_list_get_size(driver.menu->menu_list) - glui->term_height/2)
      driver.menu->begin = menu_list_get_size(driver.menu->menu_list)
            - glui->term_height;
}
示例#3
0
/**
 * menu_navigation_increment:
 *
 * Increment the navigation pointer.
 **/
void menu_navigation_increment(menu_navigation_t *nav, unsigned scroll_speed)
{
   settings_t *settings   = config_get_ptr();
   menu_list_t *menu_list = menu_list_get_ptr();

   if (!nav)
      return;

   if (nav->selection_ptr + scroll_speed < (menu_list_get_size(menu_list)))
   {
      menu_navigation_set(nav,
            nav->selection_ptr + scroll_speed, true);
      menu_driver_navigation_increment();
   }
   else
   {
      if (settings->menu.navigation.wraparound.vertical_enable)
         menu_navigation_clear(nav, false);
      else
      {
         if ((menu_list_get_size(menu_list) > 0))
         {
            menu_navigation_set_last(nav);
            menu_driver_navigation_increment();
         }
      }
   }

}
示例#4
0
/**
 * Before a refresh, we could have deleted a 
 * file on disk, causing selection_ptr to 
 * suddendly be out of range.
 *
 * Ensure it doesn't overflow.
 **/
static void menu_entries_refresh(file_list_t *list)
{
   menu_handle_t *menu = menu_driver_get_ptr();
   if (!menu)
      return;
   if (!list)
      return;

   if (menu->navigation.selection_ptr >= menu_list_get_size(menu->menu_list)
         && menu_list_get_size(menu->menu_list))
      menu_navigation_set(&menu->navigation,
            menu_list_get_size(menu->menu_list) - 1, true);
   else if (!menu_list_get_size(menu->menu_list))
      menu_navigation_clear(&menu->navigation, true);
}
示例#5
0
static int mouse_post_iterate(menu_file_list_cbs_t *cbs, const char *path,
      const char *label, unsigned type, unsigned action)
{
   if (!driver.menu->mouse.enable)
      return 0;

   if (driver.menu->mouse.ptr <= menu_list_get_size(driver.menu->menu_list)-1)
      menu_navigation_set(driver.menu, driver.menu->mouse.ptr, false);

   if (driver.menu->mouse.left)
   {
      if (!driver.menu->mouse.oldleft)
      {
         driver.menu->mouse.oldleft = true;

         if (cbs && cbs->action_ok)
            return cbs->action_ok(path, label, type, driver.menu->selection_ptr);
      }
   }
   else
      driver.menu->mouse.oldleft = false;

   if (driver.menu->mouse.right)
   {
      if (!driver.menu->mouse.oldright)
      {
         driver.menu->mouse.oldright = true;
         menu_list_pop_stack(driver.menu->menu_list);
      }
   }
   else
      driver.menu->mouse.oldright = false;

   return 0;
}
static int archive_open(void)
{
   char cat_path[PATH_MAX_LENGTH];
   const char *menu_path  = NULL;
   const char *menu_label = NULL;
   const char* path       = NULL;
   unsigned int type      = 0;
   menu_handle_t *menu    = menu_driver_get_ptr();

   if (!menu)
      return -1;

   menu_list_pop_stack(menu->menu_list);

   menu_list_get_last_stack(menu->menu_list,
         &menu_path, &menu_label, NULL);

   if (menu_list_get_size(menu->menu_list) == 0)
      return 0;

   menu_list_get_at_offset(menu->menu_list->selection_buf,
         menu->navigation.selection_ptr, &path, NULL, &type);

   fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
   menu_list_push_stack_refresh(
         menu->menu_list,
         cat_path,
         menu_label,
         type,
         menu->navigation.selection_ptr);

   return 0;
}
示例#7
0
void menu_navigation_set_last(menu_handle_t *menu)
{
   menu->selection_ptr = menu_list_get_size(driver.menu->menu_list) - 1;

   if (driver.menu_ctx && driver.menu_ctx->navigation_set_last)
      driver.menu_ctx->navigation_set_last(menu);
}
示例#8
0
static int menu_archive_open(void)
{
   char cat_path[PATH_MAX];
   const char *menu_path  = NULL;
   const char *menu_label = NULL;
   const char* path       = NULL;
   unsigned int type = 0;

   menu_list_pop_stack(driver.menu->menu_list);

   menu_list_get_last_stack(driver.menu->menu_list,
         &menu_path, &menu_label, NULL);

   if (menu_list_get_size(driver.menu->menu_list) == 0)
      return 0;

   menu_list_get_at_offset(driver.menu->menu_list->selection_buf,
         driver.menu->selection_ptr, &path, NULL, &type);

   fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
   menu_list_push_stack_refresh(
         driver.menu->menu_list,
         cat_path,
         menu_label,
         type,
         driver.menu->selection_ptr);

   return 0;
}
static int action_bind_up_or_down_generic(unsigned type, const char *label,
      unsigned action)
{
   unsigned scroll_speed  = 0;
   menu_handle_t *menu    = menu_driver_resolve();
   if (!menu)
      return -1;

   scroll_speed = (max(menu->navigation.scroll.acceleration, 2) - 2) / 4 + 1;

   if (menu_list_get_size(menu->menu_list) <= 0)
      return 0;

   switch (action)
   {
      case MENU_ACTION_UP:
         if (menu->navigation.selection_ptr >= scroll_speed)
               menu_navigation_set(&menu->navigation,
                     menu->navigation.selection_ptr - scroll_speed, true);
         else
         {
            if (g_settings.menu.navigation.wraparound.vertical_enable)
               menu_navigation_set(&menu->navigation, 
                     menu_list_get_size(menu->menu_list) - 1, true);
            else
               menu_navigation_set(&menu->navigation, 0, true);
         }
         break;
      case MENU_ACTION_DOWN:
         if (menu->navigation.selection_ptr + scroll_speed < (menu_list_get_size(menu->menu_list)))
            menu_navigation_set(&menu->navigation,
                  menu->navigation.selection_ptr + scroll_speed, true);
         else
         {
            if (g_settings.menu.navigation.wraparound.vertical_enable)
               menu_navigation_clear(&menu->navigation, false);
            else
               menu_navigation_set(&menu->navigation,
                     menu_list_get_size(menu->menu_list) - 1, true);
         }
         break;
   }

   return 0;
}
示例#10
0
// Returns the last index + 1 of the menu entry list
size_t menu_entries_get_end(void)
{
   menu_list_t *menu_list    = menu_list_get_ptr();
   
   if (!menu_list)
      return 0;

   return menu_list_get_size(menu_list);
}
示例#11
0
/**
 * Before a refresh, we could have deleted a 
 * file on disk, causing selection_ptr to 
 * suddendly be out of range.
 *
 * Ensure it doesn't overflow.
 **/
void menu_list_refresh(file_list_t *list)
{
   menu_navigation_t *nav   = menu_navigation_get_ptr();
   menu_list_t   *menu_list = menu_list_get_ptr();
   if (!nav || !menu_list || !list)
      return;

   nav->scroll.indices.size = 0;

   menu_list_build_scroll_indices(list);

   if (nav->selection_ptr >= menu_list_get_size(menu_list)
         && menu_list_get_size(menu_list))
      menu_navigation_set(nav,
            menu_list_get_size(menu_list) - 1, true);
   else if (!menu_list_get_size(menu_list))
      menu_navigation_clear(nav, true);
}
示例#12
0
/**
 * menu_navigation_set_last:
 *
 * Sets navigation pointer to last index.
 **/
void menu_navigation_set_last(menu_navigation_t *nav)
{
   menu_list_t *menu_list = menu_list_get_ptr();
   if (!menu_list || !nav)
      return;

   nav->selection_ptr = menu_list_get_size(menu_list) - 1;

   menu_driver_navigation_set_last();
}
示例#13
0
static int archive_load(void)
{
   int ret = 0;
   menu_displaylist_info_t info = {0};
   const char *menu_path  = NULL;
   const char *menu_label = NULL;
   const char* path       = NULL;
   size_t entry_idx       = 0;
   settings_t *settings   = config_get_ptr();
   global_t      *global  = global_get_ptr();
   size_t selected        = menu_navigation_get_current_selection();
   menu_handle_t *menu    = menu_driver_get_ptr();
   menu_list_t *menu_list = menu_list_get_ptr();

   if (!menu || !menu_list)
      return -1;

   menu_list_pop_stack(menu_list);

   menu_list_get_last_stack(menu_list, &menu_path, &menu_label, NULL, NULL);

   if (menu_list_get_size(menu_list) == 0)
      return 0;

   menu_list_get_at_offset(menu_list->selection_buf,
         selected, &path, NULL, NULL, &entry_idx);

   ret = rarch_defer_core(global->core_info, menu_path, path, menu_label,
         menu->deferred_path, sizeof(menu->deferred_path));

   fill_pathname_join(detect_content_path, menu_path, path,
         sizeof(detect_content_path));

   switch (ret)
   {
      case -1:
         event_command(EVENT_CMD_LOAD_CORE);
         menu_common_load_content(false, CORE_TYPE_PLAIN);
         break;
      case 0:
         info.list          = menu_list->menu_stack;
         info.type          = 0;
         info.directory_ptr = selected;
         strlcpy(info.path, settings->libretro_directory, sizeof(info.path));
         strlcpy(info.label,
               menu_hash_to_str(MENU_LABEL_DEFERRED_CORE_LIST), sizeof(info.label));

         ret = menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC);
         break;
   }

   return ret;
}
示例#14
0
static int action_right_scroll(unsigned type, const char *label,
      bool wraparound)
{
   unsigned scroll_speed = 0, fast_scroll_speed = 0;
   menu_list_t *menu_list = menu_list_get_ptr();
   menu_navigation_t *nav = menu_navigation_get_ptr();
   if (!nav || !menu_list)
      return -1;

   scroll_speed      = (max(nav->scroll.acceleration, 2) - 2) / 4 + 1;
   fast_scroll_speed = 4 + 4 * scroll_speed;

   if (nav->selection_ptr + fast_scroll_speed < (menu_list_get_size(menu_list)))
      menu_navigation_set(nav, nav->selection_ptr + fast_scroll_speed, true);
   else
   {
      if ((menu_list_get_size(menu_list) > 0))
         menu_navigation_set_last(nav);
   }

   return 0;
}
示例#15
0
int menu_entry_get_current_id(bool use_representation)
{
   size_t i;
   menu_list_t   *menu_list = menu_list_get_ptr();
   size_t               end = menu_list_get_size(menu_list);

   for (i = 0; i < end; i++)
   {
      menu_entry_t entry = {{0}};
      menu_entry_get(&entry, i, NULL, use_representation);

      if (menu_entry_is_currently_selected(entry.idx))
         return i;
   }

   return -1;
}
static int archive_load(void)
{
   int ret;
   const char *menu_path  = NULL;
   const char *menu_label = NULL;
   const char* path       = NULL;
   unsigned int type      = 0;
   menu_handle_t *menu    = menu_driver_get_ptr();
   settings_t *settings   = config_get_ptr();
   global_t      *global  = global_get_ptr();

   if (!menu)
      return -1;

   menu_list_pop_stack(menu->menu_list);

   menu_list_get_last_stack(menu->menu_list,
         &menu_path, &menu_label, NULL);

   if (menu_list_get_size(menu->menu_list) == 0)
      return 0;

   menu_list_get_at_offset(menu->menu_list->selection_buf,
         menu->navigation.selection_ptr, &path, NULL, &type);

   ret = rarch_defer_core(global->core_info, menu_path, path, menu_label,
         menu->deferred_path, sizeof(menu->deferred_path));

   switch (ret)
   {
      case -1:
         event_command(EVENT_CMD_LOAD_CORE);
         menu_entries_common_load_content(false);
         break;
      case 0:
         menu_list_push_stack_refresh(
               menu->menu_list,
               settings->libretro_directory,
               "deferred_core_list",
               0,
               menu->navigation.selection_ptr);
         break;
   }

   return 0;
}
示例#17
0
static int action_bind_down_generic(unsigned type, const char *label)
{
   size_t scroll_accel   = 0;
   unsigned scroll_speed  = 0;
   menu_list_t *menu_list = menu_list_get_ptr();
   if (!menu_list)
      return -1;
   if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL, &scroll_accel))
      return -1;

   scroll_speed = (max(scroll_accel, 2) - 2) / 4 + 1;

   if (menu_list_get_size(menu_list) <= 0)
      return 0;

   menu_navigation_ctl(MENU_NAVIGATION_CTL_INCREMENT, &scroll_speed);

   return 0;
}
示例#18
0
static int menu_archive_load(void)
{
   int ret;
   const char *menu_path  = NULL;
   const char *menu_label = NULL;
   const char* path       = NULL;
   unsigned int type = 0;

   menu_list_pop_stack(driver.menu->menu_list);

   menu_list_get_last_stack(driver.menu->menu_list,
         &menu_path, &menu_label, NULL);

   if (menu_list_get_size(driver.menu->menu_list) == 0)
      return 0;

   menu_list_get_at_offset(driver.menu->menu_list->selection_buf,
         driver.menu->selection_ptr, &path, NULL, &type);

   ret = rarch_defer_core(g_extern.core_info, menu_path, path,
         driver.menu->deferred_path, sizeof(driver.menu->deferred_path));

   switch (ret)
   {
      case -1:
         rarch_main_command(RARCH_CMD_LOAD_CORE);
         menu_common_load_content();
         break;
      case 0:
         menu_list_push_stack_refresh(
               driver.menu->menu_list,
               g_settings.libretro_directory,
               "deferred_core_list",
               0,
               driver.menu->selection_ptr);
         break;
   }

   return 0;
}
示例#19
0
static int archive_open(void)
{
   char cat_path[PATH_MAX_LENGTH] = {0};
   menu_displaylist_info_t info   = {0};
   const char *menu_path          = NULL;
   const char *menu_label         = NULL;
   const char* path               = NULL;
   unsigned int type              = 0;
   size_t entry_idx               = 0;
   menu_navigation_t *nav         = menu_navigation_get_ptr();
   menu_list_t *menu_list         = menu_list_get_ptr();

   if (!menu_list || !nav)
      return -1;

   menu_list_pop_stack(menu_list);

   menu_list_get_last_stack(menu_list,
         &menu_path, &menu_label, NULL, NULL);

   if (menu_list_get_size(menu_list) == 0)
      return 0;

   menu_list_get_at_offset(menu_list->selection_buf,
         nav->selection_ptr, &path, NULL, &type, &entry_idx);

   fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));

   fill_pathname_join(detect_content_path, menu_path, path,
         sizeof(detect_content_path));

   info.list          = menu_list->menu_stack;
   info.type          = type;
   info.directory_ptr = nav->selection_ptr;
   strlcpy(info.path, cat_path, sizeof(info.path));
   strlcpy(info.label, menu_label, sizeof(info.label));

   return menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC);
}
示例#20
0
/**
 * menu_navigation_decrement:
 *
 * Decrement the navigation pointer.
 **/
void menu_navigation_decrement(menu_navigation_t *nav, unsigned scroll_speed)
{
   menu_list_t *menu_list = menu_list_get_ptr();
   settings_t *settings   = config_get_ptr();

   if (!nav)
      return;

   if (nav->selection_ptr >= scroll_speed)
         menu_navigation_set(nav,
               nav->selection_ptr - scroll_speed, true);
   else
   {
      if (settings->menu.navigation.wraparound.vertical_enable)
         menu_navigation_set(nav, 
               menu_list_get_size(menu_list) - 1, true);
      else
         menu_navigation_set(nav, 0, true);
   }

   menu_driver_navigation_decrement();
}
示例#21
0
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs,
      menu_entry_t *entry, unsigned action)
{
   unsigned header_height;
   size_t selection;
   int ret                  = 0;
   menu_list_t *menu_list   = menu_list_get_ptr();
   menu_input_t *menu_input = menu_input_get_ptr();
   settings_t *settings     = config_get_ptr();

   if (!menu_input)
      return -1;
   if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection))
      return -1;
   menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height);

   if (!settings->menu.pointer.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && input_overlay_is_alive())
#endif
      )
      return 0;

   if (menu_input->pointer.pressed[0])
   {
      int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS);
      int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS);

      if (!menu_input->pointer.oldpressed[0])
      {
         menu_input->pointer.accel         = 0;
         menu_input->pointer.accel0        = 0;
         menu_input->pointer.accel1        = 0;
         menu_input->pointer.start_x       = pointer_x;
         menu_input->pointer.start_y       = pointer_y;
         menu_input->pointer.old_x         = pointer_x;
         menu_input->pointer.old_y         = pointer_y;
         menu_input->pointer.oldpressed[0] = true;
      }
      else if (abs(pointer_x - menu_input->pointer.start_x) > 3
            || abs(pointer_y - menu_input->pointer.start_y) > 3)
      {
         float s, delta_time;
         menu_input->pointer.dragging      = true;
         menu_input->pointer.dx            = pointer_x - menu_input->pointer.old_x;
         menu_input->pointer.dy            = pointer_y - menu_input->pointer.old_y;
         menu_input->pointer.old_x         = pointer_x;
         menu_input->pointer.old_y         = pointer_y;

         menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time);

         s =  menu_input->pointer.dy / delta_time * 1000000.0;
         menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3;
         menu_input->pointer.accel0 = menu_input->pointer.accel1;
         menu_input->pointer.accel1 = menu_input->pointer.accel;
      }
   }
   else
   {
      if (menu_input->pointer.oldpressed[0])
      {
         if (!menu_input->pointer.dragging)
         {
            if ((unsigned)menu_input->pointer.start_y < header_height)
            {
               menu_list_pop_stack(menu_list, &selection);
               menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
            }
            else if (menu_input->pointer.ptr <= menu_list_get_size(menu_list)-1)
            {
               menu_input->pointer.oldpressed[0] = false;
               ret = pointer_tap(cbs, entry, action);
            }
         }

         menu_input->pointer.oldpressed[0] = false;
         menu_input->pointer.start_x       = 0;
         menu_input->pointer.start_y       = 0;
         menu_input->pointer.old_x         = 0;
         menu_input->pointer.old_y         = 0;
         menu_input->pointer.dx            = 0;
         menu_input->pointer.dy            = 0;
         menu_input->pointer.dragging      = false;
      }
   }

   if (menu_input->pointer.back)
   {
      if (!menu_input->pointer.oldback)
      {
         menu_input->pointer.oldback = true;
         menu_list_pop_stack(menu_list, &selection);
         menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
      }
   }
   menu_input->pointer.oldback = menu_input->pointer.back;

   return ret;
}
示例#22
0
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs,
      const char *path,
      const char *label, unsigned type, unsigned action)
{
   menu_handle_t *menu    = menu_driver_get_ptr();
   settings_t *settings   = config_get_ptr();
   driver_t *driver       = driver_get_ptr();

   if (!menu)
      return -1;

   if (!settings->menu.pointer.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && driver && driver->overlay)
#endif
       )
      return 0;

#if defined(HAVE_XMB)
   if (driver->menu_ctx == &menu_ctx_xmb)
      return 0;
#endif

   if (menu->pointer.pressed[0])
   {
      if (menu->pointer.oldpressed[0])
      {
         if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list)-1)
            menu_navigation_set(&menu->navigation, menu->mouse.ptr, false);
      }
      else
         menu->pointer.oldpressed[0] = true;
   }
   else
   {
      if (menu->pointer.oldpressed[0])
      {
         rarch_setting_t *setting = NULL;

         menu->pointer.oldpressed[0] = false;
         setting = (rarch_setting_t*)setting_find_setting
            (menu->list_settings,
             menu->menu_list->selection_buf->list[menu->navigation.selection_ptr].label);

         if (menu->mouse.ptr == menu->navigation.selection_ptr && !menu->pointer.cancel
            && cbs && cbs->action_toggle && setting &&
            (setting->type == ST_BOOL || setting->type == ST_UINT || setting->type == ST_FLOAT
             || setting->type == ST_STRING))
            return cbs->action_toggle(type, label, MENU_ACTION_RIGHT, true);
         if (menu->mouse.ptr == menu->navigation.selection_ptr && !menu->pointer.cancel
            && cbs && cbs->action_ok)
            return cbs->action_ok(path, label, type,
                  menu->navigation.selection_ptr);
         else if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list) - 1)
            menu_navigation_set(&menu->navigation, menu->mouse.ptr, false);
      }
   }

   if (menu->pointer.back)
   {
      if (!menu->pointer.oldback)
      {
         menu->pointer.oldback = true;
         menu_list_pop_stack(menu->menu_list);
      }
   }
   menu->pointer.oldback = menu->pointer.back;

   return 0;
}
示例#23
0
static int menu_input_mouse_post_iterate(menu_file_list_cbs_t *cbs,
      const char *path,
      const char *label, unsigned type, unsigned action)
{
   driver_t      *driver  = driver_get_ptr();
   menu_handle_t *menu    = menu_driver_get_ptr();
   settings_t *settings   = config_get_ptr();

   if (!menu)
      return -1;

   if (!settings->menu.mouse.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && driver && driver->overlay)
#endif
       )
   {
      menu->mouse.wheeldown = false;
      menu->mouse.wheelup   = false;
      menu->mouse.oldleft   = false;
      menu->mouse.oldright  = false;
      return 0;
   }

   if (menu->mouse.left)
   {
      if (!menu->mouse.oldleft)
      {
         rarch_setting_t *setting =
            (rarch_setting_t*)setting_find_setting
            (menu->list_settings,
             menu->menu_list->selection_buf->list[menu->navigation.selection_ptr].label);
         menu->mouse.oldleft = true;

#if 0
         RARCH_LOG("action OK: %d\n", cbs && cbs->action_ok);
         RARCH_LOG("action toggle: %d\n", cbs && cbs->action_toggle);
         if (setting && setting->type)
            RARCH_LOG("action type: %d\n", setting->type);
#endif

         if (menu->mouse.ptr == menu->navigation.selection_ptr
            && cbs && cbs->action_toggle && setting &&
            (setting->type == ST_BOOL || setting->type == ST_UINT || setting->type == ST_FLOAT
             || setting->type == ST_STRING))
            return cbs->action_toggle(type, label, MENU_ACTION_RIGHT, true);
         if (menu->mouse.ptr == menu->navigation.selection_ptr
            && cbs && cbs->action_ok)
            return cbs->action_ok(path, label, type,
                  menu->navigation.selection_ptr);
         else if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list)-1)
            menu_navigation_set(&menu->navigation, menu->mouse.ptr, false);
      }
   }
   else
      menu->mouse.oldleft = false;

   if (menu->mouse.right)
   {
      if (!menu->mouse.oldright)
      {
         menu->mouse.oldright = true;
         menu_list_pop_stack(menu->menu_list);
      }
   }
   else
      menu->mouse.oldright = false;

   if (menu->mouse.wheeldown)
      menu_navigation_increment(&menu->navigation, 1);

   if (menu->mouse.wheelup)
      menu_navigation_decrement(&menu->navigation, 1);


   return 0;
}
示例#24
0
static int action_iterate_main(const char *label, unsigned action)
{
   menu_entry_t entry;
   static bool did_messagebox = false;
   char msg[PATH_MAX_LENGTH]      = {0};
   enum action_iterate_type iterate_type;
   size_t selected;
   size_t *pop_selected      = NULL;
   bool do_messagebox        = false;
   bool do_pop_stack         = false;
   bool do_post_iterate      = false;
   bool do_render            = false;
   int ret                   = 0;
   menu_handle_t *menu       = menu_driver_get_ptr();
   menu_navigation_t *nav    = menu_navigation_get_ptr();
   menu_display_t *disp      = menu_display_get_ptr();
   menu_list_t *menu_list    = menu_list_get_ptr();
   uint32_t hash             = menu_hash_calculate(label);
   if (!menu || !menu_list)
      return 0;
   
   iterate_type              = action_iterate_type(hash);

   switch (iterate_type)
   {
      case ITERATE_TYPE_HELP:
         ret = action_iterate_help(msg, sizeof(msg), label);
         pop_selected    = NULL;
         do_messagebox   = true;
         do_pop_stack    = true;
         do_post_iterate = true;
         if (ret == 1)
            action = MENU_ACTION_OK;
         break;
      case ITERATE_TYPE_BIND:
         if (menu_input_bind_iterate())
            menu_list_pop_stack(menu_list);
         break;
      case ITERATE_TYPE_VIEWPORT:
         ret = action_iterate_menu_viewport(msg, sizeof(msg), label, action, hash);
         break;
      case ITERATE_TYPE_INFO:
         ret = action_iterate_info(msg, sizeof(msg), label);
         pop_selected    = &nav->selection_ptr;
         do_messagebox   = true;
         do_pop_stack    = true;
         do_post_iterate = true;
         break;
      case ITERATE_TYPE_MESSAGE:
         strlcpy(msg, disp->message_contents, sizeof(msg));
         pop_selected    = &nav->selection_ptr;
         do_messagebox   = true;
         do_pop_stack    = true;
         break;
      case ITERATE_TYPE_DEFAULT:
         selected = menu_navigation_get_current_selection();
         /* FIXME: selected > selection_buf->list->size, i don't know why. */
         selected = max(min(selected, menu_list_get_size(menu_list)-1), 0);

         menu_entry_get(&entry,    selected, NULL, false);
         ret = menu_entry_action(&entry, selected, (enum menu_action)action);

         if (ret)
            return ret;

         do_post_iterate = true;
         do_render       = true;

         /* Have to defer it so we let settings refresh. */
         if (menu->push_help_screen)
         {
            menu_displaylist_info_t info = {0};

            info.list = menu_list->menu_stack;
            strlcpy(info.label,
                  menu_hash_to_str(MENU_LABEL_HELP),
                  sizeof(info.label));

            menu_displaylist_push_list(&info, DISPLAYLIST_HELP);
         }
         break;
   }

   did_messagebox = did_messagebox != do_messagebox;

   if (did_messagebox)
      menu_display_fb_set_dirty();

   if (do_messagebox)
      menu_driver_render_messagebox(msg);

   if (do_pop_stack && action == MENU_ACTION_OK)
      menu_list_pop(menu_list->menu_stack, pop_selected);
   
   if (do_post_iterate)
      menu_input_post_iterate(&ret, action);

   if (do_render)
      menu_driver_render();

   return ret;
}
示例#25
0
/**
 * menu_iterate:
 * @input                    : input sample for this frame
 * @old_input                : input sample of the previous frame
 * @trigger_input            : difference' input sample - difference
 *                             between 'input' and 'old_input'
 *
 * Runs RetroArch menu for one frame.
 *
 * Returns: 0 on success, -1 if we need to quit out of the loop. 
 **/
int menu_iterate(bool render_this_frame, unsigned action)
{
   menu_entry_t entry;
   enum action_iterate_type iterate_type;
   size_t selected;
   const char *label         = NULL;
   int ret                   = 0;
   uint32_t hash             = 0;
   menu_handle_t *menu       = menu_driver_get_ptr();
   menu_navigation_t *nav    = menu_navigation_get_ptr();
   menu_display_t *disp      = menu_display_get_ptr();
   menu_list_t *menu_list    = menu_list_get_ptr();

   if (render_this_frame)
      menu_animation_update_time();
   menu_list_get_last_stack(menu_list, NULL, &label, NULL, NULL);

   if (!menu || !menu_list)
      return 0;

   menu->state.fb_is_dirty     = false;
   menu->state.do_messagebox   = false;
   menu->state.do_render       = false;
   menu->state.do_pop_stack    = false;
   menu->state.do_post_iterate = false;
   menu->state.pop_selected    = NULL;
   menu->state.msg[0]          = '\0';

   hash = menu_hash_calculate(label);
   
   iterate_type              = action_iterate_type(hash);

   if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_update_pending())
   {
      if (render_this_frame)
         menu->state.fb_is_dirty = true;
   }

   switch (iterate_type)
   {
      case ITERATE_TYPE_HELP:
         ret = action_iterate_help(menu->state.msg, sizeof(menu->state.msg), label);
         if (render_this_frame)
            menu->state.do_render       = true;
         menu->state.pop_selected    = NULL;
         menu->state.do_messagebox   = true;
         menu->state.do_pop_stack    = true;
         menu->state.do_post_iterate = true;
         if (ret == 1)
            action = MENU_ACTION_OK;
         break;
      case ITERATE_TYPE_BIND:
         if (menu_input_bind_iterate(menu->state.msg, sizeof(menu->state.msg)))
            menu_list_pop_stack(menu_list, &nav->selection_ptr);
         else
            menu->state.do_messagebox = true;
         if (render_this_frame)
            menu->state.do_render        = true;
         break;
      case ITERATE_TYPE_VIEWPORT:
         ret = action_iterate_menu_viewport(menu->state.msg, sizeof(menu->state.msg), label, action, hash);
         if (render_this_frame)
            menu->state.do_render       = true;
         menu->state.do_messagebox   = true;
         break;
      case ITERATE_TYPE_INFO:
         ret = action_iterate_info(menu->state.msg, sizeof(menu->state.msg), label);
         menu->state.pop_selected    = &nav->selection_ptr;
         if (render_this_frame)
            menu->state.do_render       = true;
         menu->state.do_messagebox   = true;
         menu->state.do_pop_stack    = true;
         menu->state.do_post_iterate = true;
         break;
      case ITERATE_TYPE_MESSAGE:
         strlcpy(menu->state.msg, disp->message_contents, sizeof(menu->state.msg));
         menu->state.pop_selected    = &nav->selection_ptr;
         menu->state.do_messagebox   = true;
         menu->state.do_pop_stack    = true;
         break;
      case ITERATE_TYPE_DEFAULT:
         selected = menu_navigation_get_selection(nav);
         /* FIXME: selected > selection_buf->list->size, i don't know why. */
         selected = max(min(selected, menu_list_get_size(menu_list)-1), 0);

         menu_entry_get(&entry,    selected, NULL, false);
         ret = menu_entry_action(&entry, selected, (enum menu_action)action);

         if (ret)
            goto end;

         menu->state.do_post_iterate = true;
         if (render_this_frame)
            menu->state.do_render       = true;

         /* Have to defer it so we let settings refresh. */
         if (menu->push_help_screen)
         {
            menu_displaylist_info_t info = {0};

            info.list = menu_list->menu_stack;
            strlcpy(info.label,
                  menu_hash_to_str(MENU_LABEL_HELP),
                  sizeof(info.label));

            menu_displaylist_push_list(&info, DISPLAYLIST_HELP);
         }
         break;
   }

   if (menu->state.do_pop_stack && action == MENU_ACTION_OK)
      menu_list_pop_stack(menu_list, menu->state.pop_selected);
   
   if (menu->state.do_post_iterate)
      menu_input_post_iterate(&ret, action);

end:
   if (ret)
      return -1;
   return 0;
}
示例#26
0
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs,
      menu_entry_t *entry, unsigned action)
{
   int ret = 0;
   menu_handle_t *menu  = menu_driver_get_ptr();
   driver_t *driver     = driver_get_ptr();
   settings_t *settings = config_get_ptr();

   if (!menu)
      return -1;

   if (!settings->menu.pointer.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && driver && driver->overlay)
#endif
      )
      return 0;

   if (menu->pointer.pressed[0])
   {
      if (!menu->pointer.oldpressed[0])
      {
         menu->pointer.start_x = menu->pointer.x;
         menu->pointer.start_y = menu->pointer.y;
         menu->pointer.old_x = menu->pointer.x;
         menu->pointer.old_y = menu->pointer.y;
         menu->pointer.oldpressed[0] = true;
      }
      else if (menu->pointer.x != menu->pointer.start_x
         && menu->pointer.y != menu->pointer.start_y)
      {
         menu->pointer.dragging = true;
         menu->pointer.dx = menu->pointer.x - menu->pointer.old_x;
         menu->pointer.dy = menu->pointer.y - menu->pointer.old_y;
         menu->pointer.old_x = menu->pointer.x;
         menu->pointer.old_y = menu->pointer.y;
      }
   }
   else
   {
      if (menu->pointer.oldpressed[0])
      {
         if (!menu->pointer.dragging)
         {
            if (menu->pointer.start_y < menu->header_height)
            {
               menu_list_pop_stack(menu->menu_list);
            }
            else if (menu->pointer.ptr <= menu_list_get_size(menu->menu_list)-1)
            {
               menu->pointer.oldpressed[0] = false;
               ret = pointer_tap(cbs, entry, action);
            }
         }
         menu->pointer.oldpressed[0] = false;
         menu->pointer.start_x = 0;
         menu->pointer.start_y = 0;
         menu->pointer.old_x = 0;
         menu->pointer.old_y = 0;
         menu->pointer.dx = 0;
         menu->pointer.dy = 0;
         menu->pointer.dragging = false;
      }
   }

   if (menu->pointer.back)
   {
      if (!menu->pointer.oldback)
      {
         menu->pointer.oldback = true;
         menu_list_pop_stack(menu->menu_list);
      }
   }
   menu->pointer.oldback = menu->pointer.back;

   return ret;
}
示例#27
0
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs,
      menu_entry_t *entry, unsigned action)
{
   int ret                  = 0;
   menu_display_t *disp     = menu_display_get_ptr();
   menu_navigation_t *nav   = menu_navigation_get_ptr();
   menu_list_t *menu_list   = menu_list_get_ptr();
   menu_input_t *menu_input = menu_input_get_ptr();
   settings_t *settings     = config_get_ptr();

   if (!menu_input)
      return -1;

   if (!settings->menu.pointer.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && input_overlay_is_alive())
#endif
      )
      return 0;

   if (menu_input->pointer.pressed[0])
   {
      if (!menu_input->pointer.oldpressed[0])
      {
         menu_input->pointer.accel  = 0;
         menu_input->pointer.accel0 = 0;
         menu_input->pointer.accel1 = 0;
         menu_input->pointer.start_x       = menu_input->pointer.x;
         menu_input->pointer.start_y       = menu_input->pointer.y;
         menu_input->pointer.old_x         = menu_input->pointer.x;
         menu_input->pointer.old_y         = menu_input->pointer.y;
         menu_input->pointer.oldpressed[0] = true;
      }
      else if (abs(menu_input->pointer.x - menu_input->pointer.start_x) > 3
            || abs(menu_input->pointer.y - menu_input->pointer.start_y) > 3)
      {
         float s;
         menu_input->pointer.dragging = true;
         menu_input->pointer.dx       = menu_input->pointer.x - menu_input->pointer.old_x;
         menu_input->pointer.dy       = menu_input->pointer.y - menu_input->pointer.old_y;
         menu_input->pointer.old_x    = menu_input->pointer.x;
         menu_input->pointer.old_y    = menu_input->pointer.y;

         s =  menu_input->pointer.dy / menu_animation_get_delta_time(disp->animation) * 1000000.0;
         menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3;
         menu_input->pointer.accel0 = menu_input->pointer.accel1;
         menu_input->pointer.accel1 = menu_input->pointer.accel;
      }
   }
   else
   {
      if (menu_input->pointer.oldpressed[0])
      {
         if (!menu_input->pointer.dragging)
         {
            if ((unsigned)menu_input->pointer.start_y < disp->header_height)
               menu_list_pop_stack(menu_list, &nav->selection_ptr);
            else if (menu_input->pointer.ptr <= menu_list_get_size(menu_list)-1)
            {
               menu_input->pointer.oldpressed[0] = false;
               ret = pointer_tap(cbs, entry, action);
            }
         }

         menu_input->pointer.oldpressed[0] = false;
         menu_input->pointer.start_x       = 0;
         menu_input->pointer.start_y       = 0;
         menu_input->pointer.old_x         = 0;
         menu_input->pointer.old_y         = 0;
         menu_input->pointer.dx            = 0;
         menu_input->pointer.dy            = 0;
         menu_input->pointer.dragging      = false;
      }
   }

   if (menu_input->pointer.back)
   {
      if (!menu_input->pointer.oldback)
      {
         menu_input->pointer.oldback = true;
         menu_list_pop_stack(menu_list, &nav->selection_ptr);
      }
   }
   menu_input->pointer.oldback = menu_input->pointer.back;

   return ret;
}
示例#28
0
static void rmenu_xui_render(void)
{
   size_t begin, end;
   char title[256];
   const char *dir = NULL;
   const char *label = NULL;
   unsigned menu_type = 0;

   if (!driver.menu || driver.menu->need_refresh && 
         g_extern.is_menu && !driver.menu->msg_force)
      return;

   begin = driver.menu->selection_ptr;
   end   = menu_list_get_size(driver.menu->menu_list);

   rmenu_xui_render_background();

   menu_list_get_last_stack(driver.menu->menu_list, &dir,
         &label, &menu_type);

   get_title(label, dir, menu_type,
         title, sizeof(title));

   mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t));
   XuiTextElementSetText(m_menutitle, strw_buffer);

   char title_buf[256];
   menu_ticker_line(title_buf, RXUI_TERM_WIDTH - 3,
         g_extern.frame_count / 15, title, true);
   blit_line(RXUI_TERM_START_X + 15, 15, title_buf, true);

   char title_msg[64];
   const char *core_name = g_extern.menu.info.library_name;
   if (!core_name)
      core_name = g_extern.system.info.library_name;
   if (!core_name)
      core_name = "No Core";

   const char *core_version = g_extern.menu.info.library_version;
   if (!core_version)
      core_version = g_extern.system.info.library_version;
   if (!core_version)
      core_version = "";

   snprintf(title_msg, sizeof(title_msg), "%s - %s %s",
         PACKAGE_VERSION, core_name, core_version);
   blit_line(RXUI_TERM_START_X + 15,
         (RXUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RXUI_TERM_START_Y + 2,
         title_msg, true);

   unsigned x, y;
   size_t i;

   x = RXUI_TERM_START_X;
   y = RXUI_TERM_START_Y;

   for (i = begin; i < end; i++/*, y += FONT_HEIGHT_STRIDE */)
   {
      char message[PATH_MAX], type_str[PATH_MAX],
           entry_title_buf[PATH_MAX], type_str_buf[PATH_MAX],
           path_buf[PATH_MAX];
      const char *path = NULL, *entry_label = NULL;
      unsigned type = 0, w = 0;
      bool selected = false;

      menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path,
            &entry_label, &type);

      disp_set_label(driver.menu->menu_list->selection_buf,
		  &w, type, i, label,
            type_str, sizeof(type_str), 
            entry_label, path,
            path_buf, sizeof(path_buf));

      selected = (i == driver.menu->selection_ptr);

#if 0
      if ((type == MENU_FILE_PLAIN || type == MENU_FILE_DIRECTORY))
         menu_ticker_line(entry_title_buf, RXUI_TERM_WIDTH - (w + 1 + 2), g_extern.frame_count / 15, path, selected);
      else
         menu_ticker_line(type_str_buf, w, g_extern.frame_count / 15, type_str, selected);
#endif

      snprintf(message, sizeof(message), "%s : %s",
            entry_title_buf,
            type_str_buf);

      wchar_t msg_w[256];
      mbstowcs(msg_w, message, sizeof(msg_w) / sizeof(wchar_t));
      XuiListSetText(m_menulist, i, msg_w);
      blit_line(x, y, message, i);
   }

   if (driver.menu->keyboard.display)
   {
      char msg[1024];
      const char *str = *driver.menu->keyboard.buffer;
      if (!str)
         str = "";
      snprintf(msg, sizeof(msg), "%s\n%s", driver.menu->keyboard.label, str);
      rmenu_xui_render_messagebox(msg);
   }
}
示例#29
0
文件: rmenu.c 项目: SAKUJ0/RetroArch
static void rmenu_render(void)
{
   size_t begin, end, i, j;
   struct font_params font_parms;
   char title[256], title_buf[256];
   char title_msg[64];
   const char *dir          = NULL;
   const char *label        = NULL;
   const char *core_name    = NULL;
   const char *core_version = NULL;
   unsigned menu_type       = 0;
   menu_handle_t *menu      = menu_driver_get_ptr();
   global_t    *global      = global_get_ptr();
   runloop_t *runloop       = rarch_main_get_ptr();

   if (!menu)
      return;

   if (!render_normal)
   {
      render_normal = true;
      return;
   }

   if (menu->need_refresh && runloop->is_menu
         && !menu->msg_force)
      return;

   runloop->frames.video.current.menu.animation.is_active = false;
   runloop->frames.video.current.menu.label.is_updated    = false;
   runloop->frames.video.current.menu.framebuf.dirty      = false;

   if (!menu->menu_list->selection_buf)
      return;

   begin = (menu->navigation.selection_ptr >= (ENTRIES_HEIGHT / 2)) ? 
      (menu->navigation.selection_ptr - (ENTRIES_HEIGHT / 2)) : 0;
   end   = ((menu->navigation.selection_ptr + ENTRIES_HEIGHT) <= 
         menu_list_get_size(menu->menu_list)) ?
      menu->navigation.selection_ptr + ENTRIES_HEIGHT :
      menu_list_get_size(menu->menu_list);

   if (menu_list_get_size(menu->menu_list) <= ENTRIES_HEIGHT)
      begin = 0;

   if (end - begin > ENTRIES_HEIGHT)
      end = begin + ENTRIES_HEIGHT;
   
   rmenu_render_background();

   menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type);

   get_title(label, dir, menu_type, title, sizeof(title));

   menu_animation_ticker_line(title_buf, RMENU_TERM_WIDTH,
         runloop->frames.video.count / 15, title, true);

   font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET;
   font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET
      - (POSITION_OFFSET*2);
   font_parms.scale = FONT_SIZE_NORMAL;
   font_parms.color = WHITE;

   video_driver_set_osd_msg(title_buf, &font_parms, NULL);

   core_name = global->menu.info.library_name;
   if (!core_name)
      core_name = global->system.info.library_name;
   if (!core_name)
      core_name = "No Core";

   core_version = global->menu.info.library_version;
   if (!core_version)
      core_version = global->system.info.library_version;
   if (!core_version)
      core_version = "";

   font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET;
   font_parms.y = POSITION_EDGE_MAX - (POSITION_OFFSET*2);
   font_parms.scale = FONT_SIZE_NORMAL;
   font_parms.color = WHITE;

   snprintf(title_msg, sizeof(title_msg), "%s - %s %s",
         PACKAGE_VERSION, core_name, core_version);

   video_driver_set_osd_msg(title_msg, &font_parms, NULL);

   j = 0;

   for (i = begin; i < end; i++, j++)
   {
      char message[PATH_MAX_LENGTH], type_str[PATH_MAX_LENGTH],
           entry_title_buf[PATH_MAX_LENGTH], type_str_buf[PATH_MAX_LENGTH],
           path_buf[PATH_MAX_LENGTH];
      const char *path = NULL, *entry_label = NULL;
      unsigned type = 0, w = 0;
      bool selected = false;
      menu_file_list_cbs_t *cbs = NULL;

      menu_list_get_at_offset(menu->menu_list->selection_buf, i,
            &path, &entry_label, &type);

      cbs = (menu_file_list_cbs_t*)
         menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf,
               i);

      if (cbs && cbs->action_get_representation)
         cbs->action_get_representation(menu->menu_list->selection_buf,
               &w, type, i, label,
               type_str, sizeof(type_str), 
               entry_label, path,
               path_buf, sizeof(path_buf));

      selected = (i == menu->navigation.selection_ptr);

      menu_animation_ticker_line(entry_title_buf, RMENU_TERM_WIDTH - (w + 1 + 2),
            runloop->frames.video.count / 15, path, selected);
      menu_animation_ticker_line(type_str_buf, w, runloop->frames.video.count / 15,
            type_str, selected);

      snprintf(message, sizeof(message), "%c %s",
            selected ? '>' : ' ', entry_title_buf);

#if 0
      blit_line(x, y, message, selected);
#endif
      font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET;
      font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET
         + (POSITION_OFFSET * j);
      font_parms.scale = FONT_SIZE_NORMAL;
      font_parms.color = WHITE;

      video_driver_set_osd_msg(message, &font_parms, NULL);

      font_parms.x = POSITION_EDGE_CENTER + POSITION_OFFSET;

      video_driver_set_osd_msg(type_str_buf, &font_parms, NULL);
   }
}
示例#30
0
static int menu_input_mouse_post_iterate(uint64_t *input_mouse,
      menu_file_list_cbs_t *cbs, unsigned action)
{
   settings_t *settings     = config_get_ptr();
   menu_display_t *disp     = menu_display_get_ptr();
   menu_input_t *menu_input = menu_input_get_ptr();
   menu_list_t *menu_list   = menu_list_get_ptr();
   menu_navigation_t *nav   = menu_navigation_get_ptr();

   *input_mouse = MOUSE_ACTION_NONE;

   if (!settings->menu.mouse.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && input_overlay_is_alive())
#endif
       )
   {
      menu_input->mouse.wheeldown = false;
      menu_input->mouse.wheelup   = false;
      menu_input->mouse.oldleft   = false;
      menu_input->mouse.oldright  = false;
      return 0;
   }

   if (menu_input->mouse.left)
   {
      if (!menu_input->mouse.oldleft)
      {
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L);

         menu_input->mouse.oldleft = true;

         if ((unsigned)menu_input->mouse.y < disp->header_height)
         {
            menu_list_pop_stack(menu_list, &nav->selection_ptr);
            return 0;
         }
         if (
               (menu_input->mouse.ptr == nav->selection_ptr) &&
               cbs &&
               cbs->action_select            )
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE);
         }
         else if (menu_input->mouse.ptr <= menu_list_get_size(menu_list)-1)
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION);
         }
      }
   }
   else
      menu_input->mouse.oldleft = false;

   if (menu_input->mouse.right)
   {
      if (!menu_input->mouse.oldright)
      {
         menu_input->mouse.oldright = true;
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R);
      }
   }
   else
      menu_input->mouse.oldright = false;

   if (menu_input->mouse.wheeldown)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN);
   }

   if (menu_input->mouse.wheelup)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP);
   }

   return 0;
}