Logo Search packages:      
Sourcecode: pymol version File versions  Download package

Control.c

/* 
A* -------------------------------------------------------------------
B* This file contains source code for the PyMOL computer program
C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific. 
D* -------------------------------------------------------------------
E* It is unlawful to modify or remove this copyright notice.
F* -------------------------------------------------------------------
G* Please see the accompanying LICENSE file for further information. 
H* -------------------------------------------------------------------
I* Additional authors of this source file include:
-* 
-* 
-*
Z* -------------------------------------------------------------------
*/
#include"os_predef.h"
#include"os_std.h"
#include"os_gl.h"

#include "main.h"
#include "Base.h"
#include "Control.h"
#include "Scene.h"
#include "Executive.h"
#include "Setting.h"
#include "P.h"
#include "Seq.h"
#include"Movie.h"
#include "Text.h"
#include "Util.h"

#define cControlBoxSize 17
#define cControlLeftMargin 8
#define cControlTopMargin 2
#define cControlSpacing 2
#define cControlInnerMargin 4
#define cControlSpread 6
#define cControlSize 160

#define cControlButtons 7

#define cControlMinWidth 5

struct _CControl {
  Block *Block;
  int Rocking;
  int DragFlag;
  int LastPos;
  int ExtraSpace;
  float ButtonColor[3];
  float ActiveColor[3];
  int Pressed,Active;
  int SaveWidth;
  double LastClickTime;
  int SkipRelease;
  int NButton;
};

int ControlRocking(PyMOLGlobals *G)
{
  register CControl *I=G->Control;
  return I->Rocking;
}

static void ControlReshape(Block *block,int width, int height)
{
  PyMOLGlobals *G=block->G;
  register CControl *I=G->Control;
  BlockReshape(block,width,height);

  I->ExtraSpace = ((block->rect.right-block->rect.left)-cControlSize);
  if(I->ExtraSpace<0)
    I->ExtraSpace=0;  
}

static int which_button(CControl *I,int x,int y)
{
  int result = -1;
  x -= I->Block->rect.left+cControlLeftMargin;
  y -= I->Block->rect.top-cControlTopMargin;
  if(x>=0) 
    if((y<=0)&&(y>(-cControlBoxSize))) {
      int control_width = I->Block->rect.right - (I->Block->rect.left+cControlLeftMargin);
      result = (I->NButton*x)/control_width;
    }
  return result;
}

static int ControlDrag(Block *block,int x,int y,int mod)
{
  int width;
  int delta;
  int gui_width;
  PyMOLGlobals *G=block->G;
  register CControl *I=G->Control;
  if(!I->SkipRelease) {
    delta = x-I->LastPos;
    if(I->DragFlag) {
      if(delta) {
        gui_width = (int)SettingGet(G,cSetting_internal_gui_width)-delta;
        if(gui_width<cControlMinWidth)
          gui_width = cControlMinWidth;
        delta = (int)SettingGet(G,cSetting_internal_gui_width)-gui_width;
        width = OrthoGetWidth(G)+delta;
        I->LastPos = x;
        I->SaveWidth = 0;
        SettingSet(G,cSetting_internal_gui_width,(float)gui_width);
        OrthoReshape(G,-1,-1,false);
      }
    } else {
      I->Active = which_button(I,x,y);
      if(I->Active!=I->Pressed)
        I->Active = -1;
      OrthoDirty(G);
    }
  }
  return(1);
}

static int ControlRelease(Block *block,int button,int x,int y,int mod)
{
  PyMOLGlobals *G=block->G;
  register CControl *I=G->Control;  

  int sel = 0;

  I->LastPos =x;
  sel = which_button(I,x,y);
  if(!I->SkipRelease) {
  switch(sel) {
  case 0:
    SceneSetFrame(G,4,0);
    PLog(G,"cmd.rewind()",cPLog_pym);
    break;
  case 1:
    SceneSetFrame(G,5,-1);
    PLog(G,"cmd.back()",cPLog_pym);
    break;
  case 2:
    MoviePlay(G,cMovieStop);
    if(SettingGet(G,cSetting_sculpting)) SettingSet(G,cSetting_sculpting,0);
    if(I->Rocking) I->Rocking=false;
    ExecutiveDrawNow(G);
    OrthoDirty(G);
    PLog(G,"cmd.mstop()",cPLog_pym);
    break;
  case 3:
    if(!MoviePlaying(G)) {
      if(mod&cOrthoCTRL) {
        PLog(G,"cmd.rewind()",cPLog_pym);
        PLog(G,"cmd.mplay()",cPLog_pym);
        SceneSetFrame(G,4,0);       
        MoviePlay(G,cMoviePlay);
      } else {
        PLog(G,"cmd.mplay()",cPLog_pym);
        MoviePlay(G,cMoviePlay);
      }
    } else {
      MoviePlay(G,cMovieStop);
      ExecutiveDrawNow(G);
      OrthoDirty(G);
      PLog(G,"cmd.mstop()",cPLog_pym);
    }
    break;
  case 4:
    SceneSetFrame(G,5,1);
    PLog(G,"cmd.forward()",cPLog_pym);
    break;
  case 5:
    if(mod&cOrthoCTRL) {
      SceneSetFrame(G,3,0);
      PLog(G,"cmd.middle()",cPLog_pym);
    } else {
      SceneSetFrame(G,6,0);
      PLog(G,"cmd.ending()",cPLog_pym);
    }
    break;
  case 6:
    if(SettingGetGlobal_b(G,cSetting_seq_view)) {
      SettingSetGlobal_b(G,cSetting_seq_view,0);
      SeqChanged(G);
      PLog(G,"cmd.set('seq_view',0)",cPLog_pym);
    } else {
      SettingSetGlobal_b(G,cSetting_seq_view,1);
      SeqChanged(G);
      PLog(G,"cmd.set('seq_view',1)",cPLog_pym);        
    }
    OrthoDirty(G);
    break;
  case 7:
    I->Rocking=!I->Rocking;
    if(I->Rocking)
      PLog(G,"cmd.rock(1)",cPLog_pym);
    else
      PLog(G,"cmd.rock(0)",cPLog_pym);
    SceneRestartFrameTimer(G);
    OrthoDirty(G);
    break;
  case 8:
    PLog(G,"cmd.fullscreen()",cPLog_pym);
    ExecutiveFullScreen(G,-1);
    break;
  }
  OrthoDirty(G);
  OrthoUngrab(G);
  I->LastClickTime = UtilGetSeconds(G);
  I->DragFlag=false;
  I->Active = -1;
  I->Pressed = -1;
  }
  return(1);
}

Block *ControlGetBlock(PyMOLGlobals *G)
{
  register CControl *I=G->Control;
  {return(I->Block);}
}
/*========================================================================*/
int ControlIdling(PyMOLGlobals *G)
{
  register CControl *I=G->Control;
  return(MoviePlaying(G)||I->Rocking||SettingGet(G,cSetting_sculpting));
}
/*========================================================================*/
void ControlInterrupt(PyMOLGlobals *G)
{
  /*  register CControl *I=G->Control;*/
  MoviePlay(G,cMovieStop);
  ExecutiveDrawNow(G);
}
/*========================================================================*/
void ControlFree(PyMOLGlobals *G)
{
  register CControl *I=G->Control;
  OrthoFreeBlock(G,I->Block);
  FreeP(G->Control);
}
/*========================================================================*/
int ControlRock(PyMOLGlobals *G,int mode)
{
  register CControl *I=G->Control;
  switch(mode) {
  case -2: 
    break;
  case -1:
      I->Rocking=!I->Rocking;
      break;
  case 0:
      I->Rocking=false;
      break;
  case 1:
      I->Rocking=true;
      break;
  }
  if(mode!=-2) {
    SceneRestartFrameTimer(G);
    OrthoDirty(G);
  }
  return I->Rocking;
}

/*========================================================================*/
static int ControlClick(Block *block,int button,int x,int y,int mod)
{
  PyMOLGlobals *G=block->G;
  register CControl *I=G->Control;
  I->SkipRelease = false;
  if(x<(I->Block->rect.left + cControlLeftMargin)) {
    y -= I->Block->rect.top-cControlTopMargin;
    if((y<=0)&&(y>(-cControlBoxSize))) {
      double now = UtilGetSeconds(block->G);
      if((now-I->LastClickTime)<0.35) {
        if(I->SaveWidth) {
          SettingSet(G,cSetting_internal_gui_width,(float)I->SaveWidth);
          OrthoReshape(G,-1,-1,false);
          I->SaveWidth = 0;
        } else {
          I->SaveWidth = (int)SettingGet(G,cSetting_internal_gui_width);
          SettingSet(G,cSetting_internal_gui_width,(float)cControlMinWidth);
          OrthoReshape(G,-1,-1,false);
        }
        I->SkipRelease = true;
      } else {
        I->LastPos = x;
        OrthoGrab(G,block);
        I->DragFlag=true;
        I->LastClickTime = UtilGetSeconds(G);
      }
    }
  } else {
    I->Pressed = which_button(I,x,y);
    I->Active = I->Pressed;
    if(I->Pressed)
      OrthoGrab(G,block);
    OrthoDirty(G);
  }
  return(1);
}

static void draw_button(int x2,int y2, int w, int h, float *light, float *dark, float *inside)
{
  glColor3fv(light);
  glBegin(GL_POLYGON);
  glVertex2i(x2,y2);
  glVertex2i(x2,y2+h);
  glVertex2i(x2+w,y2+h);
  glVertex2i(x2+w,y2);
  glEnd();
  
  glColor3fv(dark);
  glBegin(GL_POLYGON);
  glVertex2i(x2+1,y2);
  glVertex2i(x2+1,y2+h-1);
  glVertex2i(x2+w,y2+h-1);
  glVertex2i(x2+w,y2);
  glEnd();
  
  glColor3fv(inside);
  glBegin(GL_POLYGON);
  glVertex2i(x2+1,y2+1);
  glVertex2i(x2+1,y2+h-1);
  glVertex2i(x2+w-1,y2+h-1);
  glVertex2i(x2+w-1,y2+1);
  glEnd();

}
/*========================================================================*/
static void ControlDraw(Block *block)
{
  PyMOLGlobals *G=block->G;
  register CControl *I=G->Control;
  int x,y;
  int nButton = I->NButton;
  int but_num;
  float lightEdge[3] = { 0.65F, 0.65F, 0.65F};
  float darkEdge[3] = {0.3F, 0.3F, 0.3F};
  float pushed[3] = {0.8F,0.8F,0.8F};

  if(G->HaveGUI && G->ValidContext ) {

    int control_width = I->Block->rect.right - (I->Block->rect.left+cControlLeftMargin);

    glColor3fv(I->Block->BackColor);
    BlockFill(I->Block);
    glColor3fv(I->Block->TextColor);

    {
      int top,left,bottom,right;
      
      left = I->Block->rect.left+1;
      bottom = I->Block->rect.bottom+1;
      top = I->Block->rect.top - (cControlTopMargin-1);
      right=left+5;
      
      glColor3f(0.8F,0.8F,0.8F);
      glBegin(GL_POLYGON);
      glVertex2i(right,top);
      glVertex2i(right,bottom);
      glVertex2i(left,bottom);
      glVertex2i(left,top);
      glEnd();
      
      glColor3f(0.3F,0.3F,0.3F);
      glBegin(GL_POLYGON);
      glVertex2i(right,top-1);
      glVertex2i(right,bottom);
      glVertex2i(left+1,bottom);
      glVertex2i(left+1,top-1);
      glEnd();

      glColor3fv(I->ButtonColor);
      
      glBegin(GL_POLYGON);
      glVertex2i(right-1,top-1);
      glVertex2i(right-1,bottom+1);
      glVertex2i(left+1,bottom+1);
      glVertex2i(left+1,top-1);
      glEnd();
    }

    y = I->Block->rect.top-cControlTopMargin;
    
    for(but_num=0;but_num<nButton;but_num++) {
      int but_width;
      int but_left;
      int but_bottom;
      int but_height;

      but_left = I->Block->rect.left + cControlLeftMargin + (but_num*control_width)/nButton;
      but_width = (((but_num+1)*control_width/nButton) - 
                   ((but_num)*control_width/nButton)) - 1;
      
      but_bottom = y-(cControlBoxSize-1);
      but_height = cControlBoxSize;
      

      if( ( but_num==I->Active ) ) {
        draw_button(but_left,but_bottom,
                    but_width, but_height, lightEdge,darkEdge,pushed);
      } else if(((but_num==6)&&((int)SettingGet(G,cSetting_seq_view))) ||
                ((but_num==3)&&(MoviePlaying(G))) ||
                ((but_num==7)&&(I->Rocking))||
                ((but_num==8)&&(SettingGetGlobal_b(G,cSetting_full_screen)))) {
        draw_button(but_left,but_bottom,
                    but_width, but_height, lightEdge,darkEdge,I->ActiveColor);
      } else {
        draw_button(but_left,but_bottom,
                    but_width, but_height, lightEdge,darkEdge,I->ButtonColor);
      }

      if(control_width>100) {
      x = but_left + (but_width-cControlBoxSize)/2;

      glColor3fv(I->Block->TextColor);
      switch(but_num) {
      case 0:
        glBegin(GL_TRIANGLES);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,y-cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-(cControlBoxSize-1)+cControlInnerMargin);
        glVertex2i(x+cControlInnerMargin,y-(cControlBoxSize/2));  
        glEnd();
        glBegin(GL_LINES);
        glVertex2i(x+cControlInnerMargin,y-cControlInnerMargin);
        glVertex2i(x+cControlInnerMargin,y-(cControlBoxSize-1)+cControlInnerMargin);
        glEnd();
        break;
        
      case 1:

        glBegin(GL_POLYGON);
        glVertex2i(x+cControlBoxSize/2+2,
                   y-(cControlBoxSize/2));  
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-cControlInnerMargin);
        glVertex2i(x+cControlInnerMargin,
                   y-(cControlBoxSize/2));  
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-(cControlBoxSize-1)+cControlInnerMargin);
        glEnd();
        break;
      case 2:
        glBegin(GL_POLYGON);
        glVertex2i(x+cControlInnerMargin,y-cControlInnerMargin);
        glVertex2i(x+cControlInnerMargin,y-(cControlBoxSize-1)+cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-(cControlBoxSize-1)+cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,y-cControlInnerMargin);
        glEnd();
        break;

      case 3:
        glBegin(GL_TRIANGLES);
        glVertex2i(x+cControlInnerMargin,y-cControlInnerMargin+1);
        glVertex2i(x+cControlInnerMargin,y-(cControlBoxSize-1)+cControlInnerMargin-1);
        glVertex2i(x+(cControlBoxSize)-cControlInnerMargin,
                   y-(cControlBoxSize/2));  
        glEnd();
        break;
      case 4:
        glBegin(GL_POLYGON);
        glVertex2i(x+cControlBoxSize/2-2,
                   y-(cControlBoxSize/2));  
        glVertex2i(x+cControlInnerMargin,y-cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-(cControlBoxSize/2));  
        glVertex2i(x+cControlInnerMargin,y-(cControlBoxSize-1)+cControlInnerMargin);
        glEnd();

        break;
      case 5:
        glBegin(GL_TRIANGLES);
        glVertex2i(x+cControlInnerMargin,y-cControlInnerMargin);
        glVertex2i(x+cControlInnerMargin,y-(cControlBoxSize-1)+cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-(cControlBoxSize/2));  
        glEnd();
        glBegin(GL_LINES);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,y-cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize-1)-cControlInnerMargin,
                   y-(cControlBoxSize-1)+cControlInnerMargin);
        glEnd();
        break;
      case 6:
        TextDrawStrAt(G,"S",x+cControlInnerMargin,
                    y-cControlBoxSize+cControlInnerMargin+1);
        break;
      case 7:
        /*
        TextDrawStrAt(G,"R",x+cControlInnerMargin,
        y-cControlBoxSize+cControlInnerMargin+1);*/
                    glBegin(GL_POLYGON);
        glVertex2i(x+(cControlBoxSize/2)+cControlSpread,
                   y-cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize/2),
                   y-(cControlBoxSize)+cControlInnerMargin);
        glVertex2i(x+(cControlBoxSize/2)-cControlSpread,
                   y-cControlInnerMargin);
                   glEnd();
        break;
      case 8:
        TextDrawStrAt(G,"F",x+cControlInnerMargin,
                    y-cControlBoxSize+cControlInnerMargin+1);
        break;
      }
    }
    }
  }
}



/*========================================================================*/
int ControlInit(PyMOLGlobals *G)
{
  register CControl *I=NULL;

  if( (I=(G->Control=Calloc(CControl,1)))) {

    I->Block = OrthoNewBlock(G,NULL);
    I->Block->fClick = ControlClick;
    I->Block->fDraw    = ControlDraw;
    I->Block->fDrag = ControlDrag;
    I->Block->fRelease = ControlRelease;
    I->Block->fReshape = ControlReshape;
    I->Block->active = true;
    I->Block->TextColor[0]=1.0;
    I->Block->TextColor[1]=0.75;
    I->Block->TextColor[2]=0.75;
    I->ButtonColor[0]=0.5F;
    I->ButtonColor[1]=0.5F;
    I->ButtonColor[2]=0.5F;
    I->ActiveColor[0]=0.65F;
    I->ActiveColor[1]=0.65F;
    I->ActiveColor[2]=0.65F;
    I->Pressed = -1;
    I->Active = -1;
    OrthoAttach(G,I->Block,cOrthoTool);
    I->SaveWidth = 0;
    I->Rocking=false;
    I->LastClickTime = UtilGetSeconds(G);
    I->NButton=9;
    return 1;
  } else 
    return 0;

}

Generated by  Doxygen 1.6.0   Back to index