예제 #1
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Toolkit input handled here.
 *
 *    @param event Event to handle.
 *    @return 1 if input was used, 0 if it wasn't.
 */
int toolkit_input( SDL_Event* event )
{
   int ret;
   Window *wdw, *wlast;
   Widget *wgt;

   /* Get window that can be focused. */
   wlast = NULL;
   for (wdw = windows; wdw!=NULL; wdw = wdw->next) {
      if (!window_isFlag( wdw, WINDOW_NOINPUT ) &&
            !window_isFlag( wdw, WINDOW_KILL ))
         wlast = wdw;
   }
   if (wlast == NULL)
      return 0;
   wdw = wlast;

   /* See if widget needs event. */
   for (wgt=wdw->widgets; wgt!=NULL; wgt=wgt->next) {
      if (wgt_isFlag( wgt, WGT_FLAG_RAWINPUT )) {
         if (wgt->rawevent != NULL) {
            ret = wgt->rawevent( wgt, event );
            if (ret != 0)
               return ret;
         }
      }
   }

   /* Pass event to window. */
   return toolkit_inputWindow( wdw, event, 1 );
}
예제 #2
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Checks to see if a widget is focusable.
 *
 *    @param wgt Widget to check if is focusable.
 *    @return 1 if it's focusable, 0 if it isn't.
 */
static int toolkit_isFocusable( Widget *wgt )
{
   if (wgt==NULL)
      return 0;

   return wgt_isFlag(wgt, WGT_FLAG_CANFOCUS);
}
예제 #3
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Allocates room for a new widget.
 *
 *    @param w Window to create widget in.
 *    @return Newly allocated widget.
 */
Widget* window_newWidget( Window* w, const char *name )
{
   Widget *wgt, *wlast, *wtmp;

   /* NULL protection. */
   if (w==NULL)
      return NULL;

   /* Try to find one with the same name first. */
   wlast = NULL;
   for (wgt=w->widgets; wgt!=NULL; wgt=wgt->next) {

      /* Must match name. */
      if (strcmp(name, wgt->name)!=0) {
         wlast = wgt;
         continue;
      }

      /* Should be destroyed. */
      if (!wgt_isFlag( wgt, WGT_FLAG_KILL )) {
         WARN("Trying to create widget '%s' over existing one that hasn't been destroyed", 
               name );
         return NULL;
      }

      /* Relink. */
      if (wlast==NULL)
         w->widgets  = wgt->next;
      else
         wlast->next = wgt->next;

      /* Prepare and return this widget. */
      widget_cleanup(wgt);
      break;
   }

   /* Must grow widgets. */
   if (wgt == NULL)
      wgt = malloc( sizeof(Widget) );

   /* Sane defaults. */
   memset( wgt, 0, sizeof(Widget) );
   wgt->type   = WIDGET_NULL;
   wgt->status = WIDGET_STATUS_NORMAL;
   wgt->wdw    = w->id;
   wgt->name   = strdup(name);
   wgt->id     = ++w->idgen;

   /* Set up. */
   wlast = NULL;
   for (wtmp=w->widgets; wtmp!=NULL; wtmp=wtmp->next)
      wlast = wtmp;
   if (wlast == NULL)
      w->widgets  = wgt;
   else
      wlast->next = wgt;

   return wgt;
}
예제 #4
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Checks to see if a widget exists.
 *
 *    @param wid Window to check widget in.
 *    @param wgtname Name of the widget to check;
 *    @return 1 if the widget exists.
 */
int widget_exists( const unsigned int wid, const char* wgtname )
{
   Window *w = window_wget(wid);
   Widget *wgt;

   /* Get window. */
   if (w==NULL) {
      WARN("window '%d' does not exist", wid);
      return 0;
   }

   /* Check for widget. */
   for (wgt=w->widgets; wgt!=NULL; wgt=wgt->next)
      if (strcmp(wgtname, wgt->name)==0)
         return !wgt_isFlag(wgt, WGT_FLAG_KILL);

   return 0;
}
예제 #5
0
파일: input.c 프로젝트: AvanWolf/naev
/**
 * @brief Renders a input widget.
 *
 *    @param inp Input widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void inp_render( Widget* inp, double bx, double by )
{
   double x, y, ty;
   char buf[ PATH_MAX ];
   int w;
   int m;

   x = bx + inp->x;
   y = by + inp->y;

   /* main background */
   toolkit_drawRect( x, y, inp->w, inp->h, &cWhite, NULL );

   /* center vertically */
   if (inp->dat.inp.oneline)
      ty = y - (inp->h - gl_smallFont.h)/2.;
   else {
      WARN("Multi-line input widgets unsupported atm.");
      return;
   }

   /* Draw text. */
   gl_printTextRaw( inp->dat.inp.font, inp->w-10., inp->h,
         x+5., ty, &cBlack, &inp->dat.inp.input[ inp->dat.inp.view ] );

   /* Draw cursor. */
   if (wgt_isFlag( inp, WGT_FLAG_FOCUSED )) {
      m = MIN( inp->dat.inp.pos - inp->dat.inp.view, PATH_MAX-1 );
      strncpy( buf, &inp->dat.inp.input[ inp->dat.inp.view ], m );
      buf[ m ] = '\0';
      w = gl_printWidthRaw( inp->dat.inp.font, buf );
      toolkit_drawRect( x+5.+w, y + (inp->h - inp->dat.inp.font->h - 4.)/2.,
            1., inp->dat.inp.font->h + 4., &cBlack, &cBlack );
   }

   /* inner outline */
   toolkit_drawOutline( x, y, inp->w, inp->h, 0.,
         toolkit_colLight, toolkit_col );
   /* outter outline */
   toolkit_drawOutline( x, y, inp->w, inp->h, 1.,
         toolkit_colDark, NULL );
}
예제 #6
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Updates the toolkit input for repeating keys.
 */
void toolkit_update (void)
{
   unsigned int t;
   Window *wdw;
   Widget *wgt;
   char buf[2];
   SDL_Event event;
   int ret;

   /* Clean up the dead if needed. */
   if (!dialogue_isOpen()) { /* Hack, since dialogues use secondary loop. */
      if (toolkit_delayCounter > 0)
         toolkit_delayCounter--;
      else
         toolkit_purgeDead();
   }

   /* Killed all the windows. */
   if (windows == NULL) {
      SDL_ShowCursor(SDL_DISABLE);
      toolkit_open = 0; /* disable toolkit */
      if (paused)
         unpause_game();
   }

   /* Must have a key pressed. */
   if (input_key == 0)
      return;

   t = SDL_GetTicks();

   /* Should be repeating. */
   if (input_keyTime + INPUT_DELAY + input_keyCounter*INPUT_FREQ > t)
      return;

   /* Increment counter. */
   input_keyCounter++;

   /* Check to see what it affects. */
   if (windows != NULL) {
      /* Get the window. */
      wdw = toolkit_getActiveWindow();
      if (wdw == NULL)
         return;


      /* See if widget needs event. */
      for (wgt=wdw->widgets; wgt!=NULL; wgt=wgt->next) {
         if (wgt_isFlag( wgt, WGT_FLAG_RAWINPUT )) {
            if (wgt->rawevent != NULL) {
               event.type           = SDL_KEYDOWN;
               event.key.state      = SDL_PRESSED;
               event.key.keysym.sym = input_key;
               event.key.keysym.mod = 0;
               ret = wgt->rawevent( wgt, &event );
               if (ret != 0)
                  return;
            }
         }
      }

      /* Handle the focused widget. */
      wgt = toolkit_getFocus( wdw );
      if ((wgt != NULL) && (wgt->keyevent != NULL)) {
         wgt->keyevent( wgt, input_key, 0 );
      }
      if ((input_text != 0) && (wgt != NULL) && (wgt->textevent != NULL)) {
         buf[0] = input_text;
         buf[1] = '\0';
         wgt->textevent( wgt, buf );
      }
   }
}
예제 #7
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Purges the dead windows.
 */
static void toolkit_purgeDead (void)
{
   Window *wdw, *wlast, *wkill;
   Widget *wgt, *wgtlast, *wgtkill;

   /* Only clean up if necessary. */
   if (!window_dead)
      return;

   /* Must be windows. */
   if (windows == NULL)
      return;

   /* Destroy what is needed. */
   wlast = NULL;
   wdw   = windows;
   while (wdw != NULL) {
      if (window_isFlag( wdw, WINDOW_KILL )) {
         /* Save target. */
         wkill = wdw;
         /* Reattach linked list. */
         if (wlast == NULL)
            windows = wdw->next;
         else
            wlast->next = wdw->next;
         wdw = wlast;
         /* Kill target. */
         wkill->next = NULL;
         window_kill( wkill );
      }
      else {
         wgtlast = NULL;
         wgt     = wdw->widgets;
         while (wgt != NULL) {
            if (wgt_isFlag( wgt, WGT_FLAG_KILL )) {
               /* Save target. */
               wgtkill = wgt;
               /* Reattach linked list. */
               if (wgtlast == NULL)
                  wdw->widgets  = wgt->next;
               else
                  wgtlast->next = wgt->next;
               wgt = wgtlast;
               /* Kill target. */
               wgtkill->next = NULL;
               widget_kill( wgtkill );
            }
            /* Save position. */
            wgtlast = wgt;
            if (wgt == NULL)
               wgt = wdw->widgets;
            else
               wgt = wgt->next;
         }
      }
      /* Save position. */
      wlast = wdw;
      if (wdw == NULL)
         wdw = windows;
      else
         wdw = wdw->next;
   }

   /* Nothing left to purge. */
   window_dead = 0;
}
예제 #8
0
파일: toolkit.c 프로젝트: Delll/naev
/**
 * @brief Handle widget mouse input.
 *
 *    @param w Window to which widget belongs.
 *    @param wgt Widget recieving event.
 *    @param event Event recieved by the window.
 */
static void toolkit_mouseEventWidget( Window *w, Widget *wgt,
      Uint8 type, Uint8 button, int x, int y, int rx, int ry )
{
   int inbounds;

   /* Widget translations. */
   x -= wgt->x;
   y -= wgt->y;

   /* Check inbounds. */
   inbounds = !((x < 0) || (x >= wgt->w) || (y < 0) || (y >= wgt->h));

   /* Regular widgets. */
   switch (type) {
      case SDL_MOUSEMOTION:
         /* Change the status of the widget if mouse isn't down. */

         /* Not scrolling. */
         if (wgt->status != WIDGET_STATUS_SCROLLING) {
            if (inbounds) {
               if (wgt->status != WIDGET_STATUS_MOUSEDOWN)
                  wgt->status = WIDGET_STATUS_MOUSEOVER;
            }
            else
               wgt->status = WIDGET_STATUS_NORMAL;
         }
         else
            inbounds = 1; /* Scrolling is always inbounds. */

         /* If always gets the event. */
         if (wgt_isFlag( wgt, WGT_FLAG_ALWAYSMMOVE ))
            inbounds = 1;

         /* Try to give the event to the widget. */
         if (inbounds && (wgt->mmoveevent != NULL))
            (*wgt->mmoveevent)( wgt, x, y, rx, ry );

         break;

      case SDL_MOUSEBUTTONDOWN:
         if (!inbounds)
            break;

         /* Update the status. */
         if (button == SDL_BUTTON_LEFT)
            wgt->status = WIDGET_STATUS_MOUSEDOWN;

         if (toolkit_isFocusable(wgt))
            w->focus = wgt->id;

         /* Try to give the event to the widget. */
         if (wgt->mclickevent != NULL)
            (*wgt->mclickevent)( wgt, button, x, y );
         break;

      case SDL_MOUSEBUTTONUP:
         /* Since basically only buttons are handled here, we ignore
          * it all except the left mouse button. */
         if (button != SDL_BUTTON_LEFT)
            break;

         if (wgt->status==WIDGET_STATUS_MOUSEDOWN) {
            if ((wgt->type==WIDGET_BUTTON) &&
                  (wgt->dat.btn.disabled==0)) {
               if (wgt->dat.btn.fptr==NULL)
                  DEBUG("Toolkit: Button '%s' of Window '%s' "
                        "doesn't have a function trigger",
                        wgt->name, w->name );
               else {
                  (*wgt->dat.btn.fptr)(w->id, wgt->name);
               }
            }
         }

         /* Always goes normal unless is below mouse. */
         if (inbounds)
            wgt->status = WIDGET_STATUS_MOUSEOVER;
         else
            wgt->status = WIDGET_STATUS_NORMAL;

         break;
   }
}