Logo Search packages:      
Sourcecode: vdrift version File versions

controlgrab.cpp

#include <sstream>
#include "keyman.h"
#include "controls.h"
#include "globals.h"
#include "gui/controlgrab.h"
using namespace VGUI;

ControlGrab::ControlGrab( Widget* w )
{
      setting = "";
      center = w->GetCenter();
      name = w->GetName();
      text = w->GetText();
      type = w->GetType();
      tip = w->GetTip();
      rel_width = w->GetRelWidth();
      rel_height = w->GetRelHeight();
      enabled = w->GetEnabled();
      selected = w->GetSelected();
      is_default = w->GetDefault();
      is_cancel = w->GetCancel();
      has_icon = w->GetHasIcon();
      width_auto = w->GetWidthAuto();
      height_auto = w->GetHeightAuto();
      font_size = w->GetFontSize();
      color_r = w->GetColorR();
      color_g = w->GetColorG();
      color_b = w->GetColorB();
      spacing = 0.3;
      selected_icon = 0;
      pressed_icon = clicked_icon = 10000;

      string skin_path = settings.GetSkinPath();
      add_tex.Load( skin_path + "/textures/widgets/controls/add.png", false );
      add_tex_sel.Load( skin_path + "/textures/widgets/controls/add_sel.png", false );
      key_tex.Load( skin_path + "/textures/widgets/controls/key.png", false );
      key_tex_x.Load( skin_path + "/textures/widgets/controls/key_x.png", false );
      joy_axis_tex.Load( skin_path + "/textures/widgets/controls/joy_axis.png", false );
      joy_axis_tex_x.Load( skin_path + "/textures/widgets/controls/joy_axis_x.png", false );
      joy_btn_tex.Load( skin_path + "/textures/widgets/controls/joy_btn.png", false );
      joy_btn_tex_x.Load( skin_path + "/textures/widgets/controls/joy_btn_x.png", false );
      mouse_btn_tex.Load( skin_path + "/textures/widgets/controls/mouse.png", false );
      mouse_btn_tex_x.Load( skin_path + "/textures/widgets/controls/mouse_x.png", false );
      mouse_move_tex.Load( skin_path + "/textures/widgets/controls/mouse.png", false );
      mouse_move_tex_x.Load( skin_path + "/textures/widgets/controls/mouse_x.png", false );
/*
      tex_width = 0.0277;
      tex_height = 0.0370;
*/
      // width = dist from left of text to wheel + width of wheel + texture width
      if( width_auto )
      {
            rel_width = spacing + ( 0.03 * 3 );
      }

      // height = button texture height
      if( height_auto )
      {
            rel_height = 0.04;
      }
      
      analog=adding=l_down=r_down=mbtn_down = false;
}

ControlGrab::~ControlGrab()
{
}

void ControlGrab::BuildControlVectors()
{
      local_controls.clear();
      for( gamecontrols.ControlIteratorReset(); gamecontrols.ControlIteratorGetControl() != NULL; gamecontrols.ControlIteratorIncrement() )
      {
            ControlSet ctrl_set;
            CONTROL & ctrls = *(gamecontrols.ControlIteratorGetControl());
            CONTROL new_ctrl;
            TEXTURE_HANDLE * icon_tex, * icon_tex_x;
            icon_tex = &key_tex;
            icon_tex_x = &key_tex_x;
            std::ostringstream ctrl_desc;

            if( ctrls.GetName() == setting )
            {
                  new_ctrl.SetName( setting );

                  if( ctrls.GetType() == Joy )
                  {
                        int joy_idx = ctrls.GetJoyNum();

                        std::ostringstream joy_desc;
                        ctrl_desc << "Joy" << joy_idx;

                        new_ctrl.SetType( "joy" );
                        new_ctrl.SetJoyNum( joy_idx );

                        if( ctrls.GetJoyType() == Axis )
                        {
                              string joy_type;
                              int joy_axis = ctrls.GetJoyAxis();

                              new_ctrl.SetJoyType( "axis" );
                              new_ctrl.SetJoyAxis( joy_axis );

                              if( ctrls.GetJoyAxisType() == Positive )
                              {
                                    joy_type = "(+)";
                                    new_ctrl.SetJoyAxisType( Positive );
                              }
                              else
                              {
                                    joy_type = "(-)";
                                    new_ctrl.SetJoyAxisType( Negative );
                              }

                              ctrl_desc << " Axis" << joy_axis << " " << joy_type;
                              icon_tex = &joy_axis_tex;
                              icon_tex_x = &joy_axis_tex_x;
                        }
                        else if( ctrls.GetJoyType() == Button )
                        {
                              string joy_once, joy_btnup;
                              int joy_btn = ctrls.GetJoyButton();

                              new_ctrl.SetJoyType( "button" );
                              new_ctrl.SetJoyButton( joy_btn );

                              if( ctrls.GetOneTime() )
                              {
                                    joy_once = "(once)";
                                    new_ctrl.SetOneTime( true );
                              }
                              else
                              {
                                    joy_once = "(held)";
                                    new_ctrl.SetOneTime( false );
                              }
                              
                              if( ctrls.GetJoyPushDown() )
                              {
                                    joy_btnup = "press";
                                    new_ctrl.SetJoyPushDown( true );
                              }
                              else
                              {
                                    joy_btnup = "release";
                                    new_ctrl.SetJoyPushDown( false );
                              }

                              ctrl_desc << " Btn" << joy_btn << " " << joy_btnup << " " << joy_once;
                              icon_tex = &joy_btn_tex;
                              icon_tex_x = &joy_btn_tex_x;
                        }
                  }
                  else if( ctrls.GetType() == Key )
                  {
                        int key_code = ctrls.GetKeyCode();
                        ctrl_desc << "Key " << keyman.GetKeyName( (int)key_code ) << " ";

                        new_ctrl.SetType( "key" );
                        new_ctrl.SetKeyCode( key_code );

                        if( ctrls.GetKeyPushDown() )
                        {
                              ctrl_desc << "press";
                              new_ctrl.SetKeyPushDown( true );
                        }
                        else
                        {
                              ctrl_desc << "release";
                              new_ctrl.SetKeyPushDown( false );
                        }
                        if( ctrls.GetOneTime() )
                        {
                              ctrl_desc << " (once)";
                              new_ctrl.SetOneTime( true );
                        }
                        else
                        {
                              ctrl_desc << " (held)";
                              new_ctrl.SetOneTime( false );
                        }
                        
                        icon_tex = &key_tex;
                        icon_tex_x = &key_tex_x;
                  }
                  else if( ctrls.GetType() == Mouse )
                  {
                        ctrl_desc << "Mouse";
                        new_ctrl.SetType( "mouse" );
                        if( ctrls.GetMouseType() == MButton )
                        {
                              new_ctrl.SetMouseType( "button" );
                              int mbtn = ctrls.GetMouseButton();
                              new_ctrl.SetMouseButton( mbtn );
                              ctrl_desc << " button " << mbtn << " ";

                              if( ctrls.GetMousePushDown() )
                              {
                                    ctrl_desc << "press";
                                    new_ctrl.SetMousePushDown( true );
                              }
                              else
                              {
                                    ctrl_desc << "release";
                                    new_ctrl.SetMousePushDown( false );
                              }
                              if( ctrls.GetOneTime() )
                              {
                                    ctrl_desc << " (once)";
                                    new_ctrl.SetOneTime( true );
                              }
                              else
                              {
                                    ctrl_desc << " (held)";
                                    new_ctrl.SetOneTime( false );
                              }

                              icon_tex = &mouse_btn_tex;
                              icon_tex_x = &mouse_btn_tex_x;
                        }
                        else if( ctrls.GetMouseType() == Motion )
                        {
                              new_ctrl.SetMouseType( "motion" );
                              ctrl_desc << " move";
                              string mdir;
                              switch( ctrls.GetMouseDirection() )
                              {
                              case Up:
                                    mdir = "up";
                                    break;
                              case Down:
                                    mdir = "down";
                                    break;
                              case Left:
                                    mdir = "left";
                                    break;
                              case Right:
                                    mdir = "right";
                                    break;
                              default:
                                    mdir = "error!";
                                    break;
                              }
                              ctrl_desc << " " << mdir;
                              new_ctrl.SetMouseDirection( mdir );

                              icon_tex = &mouse_move_tex;
                              icon_tex_x = &mouse_move_tex_x;
                        }
                  }
                  ctrl_set.SetTex( icon_tex );
                  ctrl_set.SetTexX( icon_tex_x );
                  ctrl_set.SetName( ctrl_desc.str() );
                  ctrl_set.SetControl( new_ctrl );

                  local_controls.push_back( ctrl_set );
            }
      }           
}

void ControlGrab::SetSpacing( float new_spacing )
{
      spacing = new_spacing;
      if( width_auto )
      {
            rel_width = spacing + 0.03 * 3;
      }
}

void ControlGrab::Save()
{
      gamecontrols.DeleteControlsWithAction( setting );

      for( unsigned int i = 0; i < local_controls.size(); i++ )
      {
            gamecontrols.AddControl( local_controls[i].GetControl() );
      }
}

void ControlGrab::ResetValue()
{
      BuildControlVectors();
}

void ControlGrab::Draw()
{
      Draw( 1.0 );
}

void ControlGrab::Draw( float opacity )
{
      float center_x = center.GetXPercent();
      float center_y = center.GetYPercent();
      float rel_width_half = rel_width / 2.0f;
      float rel_height_half = 0.0370 / 2.0f;
      float opacity_txt = selected ? 0.9 : enabled ? 0.75 : 0.4;
      unsigned int i = 0;
      TEXTURE_HANDLE * cur_tex;
      TEXTURE_HANDLE * add_icon_tex = selected && ( 0 == selected_icon ) ? &add_tex_sel : &add_tex;

      // draw the add control button
      utility.DrawButton( center_x - rel_width_half + spacing,
                          center_y - rel_height_half,
                          center_x - rel_width_half + spacing,
                          center_y + rel_height_half,
                          0.0138888, add_icon_tex, opacity * opacity_txt );

      // draw the individual controls' icons
      for( i = 0; i < local_controls.size(); i++ )
      {
            cur_tex = selected && ( ( i + 1 ) == selected_icon ) ?
                      local_controls[i].GetTexX() :
                      local_controls[i].GetTex();

            utility.DrawButton( center_x - rel_width_half + spacing + ( ( i + 1 ) * 0.03 ),
                                center_y - rel_height_half,
                                center_x - rel_width_half + spacing + ( ( i + 1 ) * 0.03 ),
                                center_y + rel_height_half,
                                0.0138888, cur_tex, opacity * opacity_txt );
      }

      // draw text
      font.Print( center_x - rel_width_half,
                  center_y - ( font.Height( text.c_str(), 1, font_size ) / 2.0f ),
                  text.c_str(), 1, font_size, color_r, color_g, color_b, opacity_txt * opacity );

      if( selected )
      {
            if( adding )
            {
                  // when a user wants to add a control to this action, put a message
                  // at the bottom of the screen reminding them to give their input
                  string t1 = "Enter the input you wish to bind to " + text + ".";
                  string t2 = "Press Escape to cancel.";
                  float w1 = 0.5 - ( font.Width( t1.c_str(), 1, 6 ) / 2.0f );
                  float w2 = 0.5 - ( font.Width( t2.c_str(), 1, 6 ) / 2.0f );
                  font.Print( w1, 0.90, t1.c_str(), 1, 6, 0.0, 0.8, 0.0, 0.9 );
                  font.Print( w2, 0.925, t2.c_str(), 1, 6, 1.0, 0.0, 0.0, 0.9 );
            }
            else
            {
                  // draw this controlgrab's tip
                  if( tip != "" )
                  {
                        float w = 0.5 - ( font.Width( tip.c_str(), 1, 6 ) / 2.0f );
                        font.Print( w, 0.90, tip.c_str(), 1, 6, 0.7, 0.7, 0.7, 0.9 );
                  }

                  // draw selected icon's tip
                  if( selected_icon == 0 )
                  {
                        string t = "Add a new control";
                        float w = 0.5 - ( font.Width( t.c_str(), 1, 6 ) / 2.0f );
                        font.Print( w, 0.925, t.c_str(), 1, 6, 0.0, 0.8, 0.0, 0.9 );
                  }
                  else if( ( selected_icon > 0 ) && ( selected_icon <= local_controls.size() ) &&
                        ( local_controls[selected_icon-1].GetName() != "" ) )
                  {
                        string t = "Delete " + local_controls[selected_icon-1].GetName();
                        float w = 0.5 - ( font.Width( t.c_str(), 1, 6 ) / 2.0f );
                        font.Print( w, 0.925, t.c_str(), 1, 6, 0.8, 0.0, 0.0, 0.9 );
                  }
            }
      }
}

void ControlGrab::IncValuePress()
{
      Release();
      r_down = true;
}

void ControlGrab::IncValueRelease()
{
      if( r_down && ( selected_icon < local_controls.size() ) )
      {
            selected_icon++;
      }
      else if( selected_icon == 10000 )
      {
            selected_icon = 0;
      }
      Release();
}

void ControlGrab::DecValuePress()
{
      Release();
      l_down = true;
}

void ControlGrab::DecValueRelease()
{
      if( l_down && ( selected_icon > 0 ) && ( selected_icon <= local_controls.size() ) )
      {
            selected_icon--;
      }
      else if( selected_icon > local_controls.size() )
      {
            selected_icon = 0;
      }
      Release();
}

void ControlGrab::Press()
{
      pressed = true;
      pressed_icon = selected_icon;
}

void ControlGrab::Release()
{
      if( pressed && ( pressed_icon == selected_icon ) )
      {
            if( selected_icon == 0 )
            {
                  adding = true;
                  add_start = SDL_GetTicks();
            }
            else if( selected_icon <= local_controls.size() )
            {
                  local_controls.erase( local_controls.begin() + ( selected_icon - 1 ) );
            }
      }

      pressed = r_down = l_down = false;
}

void ControlGrab::GrabKey( SDLKey key )
{
      if( key != SDLK_ESCAPE )
      {
            string analog_str;
            string press_str;
            ControlSet cs;
            CONTROL ctrl_new;
            ctrl_new.SetType( "key" );
            ctrl_new.SetKeyCode( (int)key );
            analog_str = analog ? "(held)" : "(once)";
            ctrl_new.SetOneTime( !analog );
            ctrl_new.SetKeyPushDown( setting != "engage" );
            press_str = setting != "engage" ? "press" : "release";
            ctrl_new.SetName( setting );

            string ctrl_desc = "Key " + keyman.GetKeyName( (int)key ) + " " + press_str  + " " + analog_str;

            cs.SetControl( ctrl_new );
            cs.SetName( ctrl_desc );
            cs.SetTex( &key_tex );
            cs.SetTexX( &key_tex_x );
            local_controls.push_back( cs );
      }
      adding = false;
}

void ControlGrab::GrabMouseMovement( string direction )
{
      ControlSet cs;
      std::ostringstream ctrl_desc;
      CONTROL ctrl_new;
      ctrl_new.SetType( "mouse" );
      ctrl_new.SetName( setting );
      ctrl_new.SetMouseType( "motion" );
      ctrl_new.SetMouseDirection( direction );
      ctrl_desc << "Mouse move " << direction;
      cs.SetControl( ctrl_new );
      cs.SetName( ctrl_desc.str() );
      cs.SetTex( &mouse_move_tex );
      cs.SetTexX( &mouse_move_tex_x );
      local_controls.push_back( cs );
      adding = false;
}

void ControlGrab::GrabMouseButton( int button_idx )
{
      ControlSet cs;
      string button_str;
      string analog_str;
      string press_str;
      std::ostringstream ctrl_desc;
      CONTROL ctrl_new;
      ctrl_new.SetType( "mouse" );
      ctrl_new.SetName( setting );
      ctrl_new.SetMouseType( "button" );
      analog_str = analog ? "(held)" : "(once)";
      ctrl_new.SetOneTime( !analog );
      ctrl_new.SetMousePushDown( setting != "engage" );
      press_str = setting != "engage" ? "press" : "release";
      ctrl_new.SetMouseButton( button_idx );
      if( button_idx == 1 )
            button_str = "left click";
      else if( button_idx == 2 )
            button_str = "middle click";
      else if( button_idx == 3 )
            button_str = "right click";
      else if( button_idx == 4 )
            button_str = "scroll up";
      else if( button_idx == 5 )
            button_str = "scroll down";
      else if( button_idx == 6 )
            button_str = "scroll up";
      else if( button_idx == 7 )
            button_str = "scroll down";
      else
            button_str = button_idx;

      ctrl_desc << "Mouse button " << button_str << " " << press_str << " " << analog_str;
      cs.SetControl( ctrl_new );
      cs.SetName( ctrl_desc.str() );
      cs.SetTex( &mouse_btn_tex );
      cs.SetTexX( &mouse_btn_tex_x );
      local_controls.push_back( cs );
      adding = false;
}

void ControlGrab::GrabJoyButton( Uint8 joy_idx, Uint8 joy_btn )
{
      ControlSet cs;
      string analog_str;
      string press_str;
      CONTROL ctrl_new;
      ctrl_new.SetType( "joy" );
      ctrl_new.SetJoyType( "button" );
      ctrl_new.SetJoyNum( (int)joy_idx );
      analog_str = analog ? "(held)" : "(once)";
      ctrl_new.SetOneTime( !analog );
      ctrl_new.SetJoyPushDown( setting != "engage" );
      press_str = setting != "engage" ? "press" : "release";
      ctrl_new.SetJoyButton( (int)joy_btn );
      ctrl_new.SetName( setting );

      std::ostringstream ctrl_desc;
      int ji = (int)joy_idx;
      int jb = (int)joy_btn;
      ctrl_desc << "Joy" << ji << " Btn" << jb << " " << press_str << " " << analog_str;

      cs.SetControl( ctrl_new );
      cs.SetName( ctrl_desc.str() );
      cs.SetTex( &joy_btn_tex );
      cs.SetTexX( &joy_btn_tex_x );
      local_controls.push_back( cs );

      adding = false;
}

void ControlGrab::GrabJoyMove( Uint8 joy_idx, Uint8 joy_axis, bool joy_positive, float joy_value )
{
      ControlSet cs;
      CONTROL ctrl_new;
      string joy_type;
      std::ostringstream ctrl_desc;
      int ji = (int)joy_idx;
      int ja = (int)joy_axis;

      ctrl_new.SetType( "joy" );
      ctrl_new.SetJoyType( "axis" );
      ctrl_new.SetJoyNum( (int)joy_idx );
      ctrl_new.SetJoyAxis( (int)joy_axis );
      ctrl_new.SetName( setting );
      if( joy_positive )
      {
            joy_type = "(+)";
            ctrl_new.SetJoyAxisType( Positive );
      }
      else
      {
            joy_type = "(-)";
            ctrl_new.SetJoyAxisType( Negative );
      }

      ctrl_desc << "Joy" << ji << " Axis" << ja << " " << joy_type;

      cs.SetControl( ctrl_new );
      cs.SetName( ctrl_desc.str() );
      cs.SetTex( &joy_axis_tex );
      cs.SetTexX( &joy_axis_tex_x );
      local_controls.push_back( cs );

      adding = false;
}

bool ControlGrab::MouseOver( float x, float y )
{
      float min_x, min_y, max_x, max_y;
      float center_x = center.GetXPercent();
      float center_y = center.GetYPercent();
      float rel_width_half = rel_width / 2.0f;
      float rel_height_half = rel_height / 2.0f;
      min_x = center_x - rel_width_half;
      min_y = center_y - rel_height_half;
      max_x = min_x + spacing + ( (float)( local_controls.size() + 1 ) * 0.03f );
      max_y = center_y + rel_height_half;
      float icon_min_x, icon_max_x;

      if( ( x > min_x ) && ( x < max_x ) && ( y > min_y ) && ( y < max_y ) )
      {
            bool found = false;
            for( unsigned int i = 0; i <= local_controls.size(); i++ )
            {
                  icon_min_x = min_x + spacing - 0.0138888 + ( 0.03 * i );
                  icon_max_x = icon_min_x + 0.03;
                  if( ( x > icon_min_x ) && ( x < icon_max_x ) )
                  {
                        selected_icon = i;
                        found = true;
                        break;
                  }
            }
            if( !found ) selected_icon = 10000;
      }

      return ( x > min_x ) && ( x < max_x ) && ( y > min_y ) && ( y < max_y );
}

string ControlGrab::MousePress( float x, float y )
{
      string action = "";
      float min_x, min_y, max_x, max_y;
      float center_x = center.GetXPercent();
      float center_y = center.GetYPercent();
      float rel_width_half = rel_width / 2.0f;
      float rel_height_half = rel_height / 2.0f;
      min_x = center_x - rel_width_half;
      min_y = center_y - rel_height_half;
      max_x = min_x + spacing + ( (float)( local_controls.size() + 1 ) * 0.03f );
      max_y = center_y + rel_height_half;
      float icon_min_x, icon_max_x;

      if( ( x > min_x ) && ( x < max_x ) && ( y > min_y ) && ( y < max_y ) )
      {
            for( unsigned int i = 0; i <= local_controls.size(); i++ )
            {
                  icon_min_x = min_x + spacing - 0.0138888 + ( 0.03 * i );
                  icon_max_x = icon_min_x + 0.03;
                  if( ( x > icon_min_x ) && ( x < icon_max_x ) )
                  {
                        clicked_icon = i;
                        mbtn_down = true;
                        break;
                  }
            }
      }

      return action;
}

string ControlGrab::MouseRelease( float x, float y )
{
      string action = "";
      float min_x, min_y, max_x, max_y;
      float center_x = center.GetXPercent();
      float center_y = center.GetYPercent();
      float rel_width_half = rel_width / 2.0f;
      float rel_height_half = rel_height / 2.0f;
      min_x = center_x - rel_width_half;
      min_y = center_y - rel_height_half;
      max_x = min_x + spacing + ( (float)( local_controls.size() + 1 ) * 0.03f );
      max_y = center_y + rel_height_half;
      float icon_min_x, icon_max_x;

      if( ( x > min_x ) && ( x < max_x ) && ( y > min_y ) && ( y < max_y ) )
      {
            for( unsigned int i = 0; i <= local_controls.size(); i++ )
            {
                  icon_min_x = min_x + spacing - 0.0138888 + ( 0.03 * i );
                  icon_max_x = icon_min_x + 0.03;
                  if( mbtn_down && ( x > icon_min_x ) && ( x < icon_max_x ) && ( clicked_icon == i ) )
                  {
                        if( selected_icon == 0 )
                        {
                              adding = true;
                              add_start = SDL_GetTicks();
                        }
                        else if( selected_icon <= local_controls.size() )
                        {
                              local_controls.erase( local_controls.begin() + ( selected_icon - 1 ) );
                        }
                        mbtn_down = false;
                        break;
                  }
            }
      }
      mbtn_down = false;
      clicked_icon = 10000;

      return action;
}

Generated by  Doxygen 1.6.0   Back to index