Fix the minimum screen size not enforced when resizing window (since r705) Fix the mouse cursor position when changing pixel size (since r705) In fileselector, the image preview now enforces "safe colors". (issue 116) git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@716 416bcca6-2ee7-4201-b75f-2eb2f807beb1
		
			
				
	
	
		
			2560 lines
		
	
	
		
			77 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2560 lines
		
	
	
		
			77 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
						|
 | 
						|
    Copyright 2007 Adrien Destugues
 | 
						|
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
						|
 | 
						|
    Grafx2 is free software; you can redistribute it and/or
 | 
						|
    modify it under the terms of the GNU General Public License
 | 
						|
    as published by the Free Software Foundation; version 2
 | 
						|
    of the License.
 | 
						|
 | 
						|
    Grafx2 is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU General Public License
 | 
						|
    along with Grafx2; if not, see <http://www.gnu.org/licenses/> or
 | 
						|
    write to the Free Software Foundation, Inc.,
 | 
						|
    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 | 
						|
*/
 | 
						|
//
 | 
						|
//  Ce fichier contient la gestion du moteur
 | 
						|
//
 | 
						|
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "const.h"
 | 
						|
#include "struct.h"
 | 
						|
#include "global.h"
 | 
						|
#include "graph.h"
 | 
						|
#include "misc.h"
 | 
						|
#include "special.h"
 | 
						|
#include "buttons.h"
 | 
						|
#include "operatio.h"
 | 
						|
#include "shade.h"
 | 
						|
#include "errors.h"
 | 
						|
#include "sdlscreen.h"
 | 
						|
#include "windows.h"
 | 
						|
#include "brush.h"
 | 
						|
#include "input.h"
 | 
						|
#include "engine.h"
 | 
						|
 | 
						|
 | 
						|
// we need this as global
 | 
						|
short Old_MX = -1;
 | 
						|
short Old_MY = -1;
 | 
						|
 | 
						|
//---------- Annuler les effets des modes de dessin (sauf la grille) ---------
 | 
						|
 | 
						|
// Variables mémorisants les anciens effets
 | 
						|
 | 
						|
byte Shade_mode_before_cancel;
 | 
						|
byte Quick_shade_mode_before_cancel;
 | 
						|
byte Stencil_mode_before_cancel;
 | 
						|
byte Sieve_mode_before_cancel;
 | 
						|
byte Colorize_mode_before_cancel;
 | 
						|
byte Smooth_mode_before_cancel;
 | 
						|
byte Tiling_mode_before_cancel;
 | 
						|
Func_effect Effect_function_before_cancel;
 | 
						|
 | 
						|
byte* Window_background[8];
 | 
						|
 | 
						|
void Cancel_effects(void)
 | 
						|
{
 | 
						|
  Shade_mode_before_cancel=Shade_mode;
 | 
						|
  Shade_mode=0;
 | 
						|
 | 
						|
  Quick_shade_mode_before_cancel=Quick_shade_mode;
 | 
						|
  Quick_shade_mode=0;
 | 
						|
 | 
						|
  Stencil_mode_before_cancel=Stencil_mode;
 | 
						|
  Stencil_mode=0;
 | 
						|
 | 
						|
  Sieve_mode_before_cancel=Sieve_mode;
 | 
						|
  Sieve_mode=0;
 | 
						|
 | 
						|
  Colorize_mode_before_cancel=Colorize_mode;
 | 
						|
  Colorize_mode=0;
 | 
						|
 | 
						|
  Smooth_mode_before_cancel=Smooth_mode;
 | 
						|
  Smooth_mode=0;
 | 
						|
 | 
						|
  Tiling_mode_before_cancel=Tiling_mode;
 | 
						|
  Tiling_mode=0;
 | 
						|
 | 
						|
  Effect_function_before_cancel=Effect_function;
 | 
						|
  Effect_function=No_effect;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//----------------- Restaurer les effets des modes de dessin -----------------
 | 
						|
void Restore_effects(void)
 | 
						|
{
 | 
						|
  Shade_mode      =Shade_mode_before_cancel;
 | 
						|
  Quick_shade_mode=Quick_shade_mode_before_cancel;
 | 
						|
  Stencil_mode    =Stencil_mode_before_cancel;
 | 
						|
  Sieve_mode      =Sieve_mode_before_cancel;
 | 
						|
  Colorize_mode   =Colorize_mode_before_cancel;
 | 
						|
  Smooth_mode     =Smooth_mode_before_cancel;
 | 
						|
  Tiling_mode     =Tiling_mode_before_cancel;
 | 
						|
  Effect_function  =Effect_function_before_cancel;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
char * Menu_tooltip[NB_BUTTONS]=
 | 
						|
{
 | 
						|
  "Paintbrush choice       ",
 | 
						|
  "Adjust picture / Effects",
 | 
						|
  "Freehand draw. / Toggle ",
 | 
						|
  "Splines / Toggle        ",
 | 
						|
  "Lines / Toggle          ",
 | 
						|
  "Spray / Menu            ",
 | 
						|
  "Floodfill / Replace col.",
 | 
						|
  "Polylines / Polyforms   ",
 | 
						|
  "Polyfill / Filled Pforms",
 | 
						|
  "Empty rectangles        ",
 | 
						|
  "Filled rectangles       ",
 | 
						|
  "Empty circles / ellipses",
 | 
						|
  "Filled circles / ellips.",
 | 
						|
  "Grad. rectangles        ",
 | 
						|
  "Gradation menu          ",
 | 
						|
  "Grad. spheres / ellipses",
 | 
						|
  "Brush grab. / Restore   ",
 | 
						|
  "Lasso / Restore brush   ",
 | 
						|
  "Brush effects           ",
 | 
						|
  "Drawing modes (effects) ",
 | 
						|
  "Text                    ",
 | 
						|
  "Magnify mode / Menu     ",
 | 
						|
  "Pipette / Invert colors ",
 | 
						|
  "Screen size / Safe. res.",
 | 
						|
  "Go / Copy to other page ",
 | 
						|
  "Save as / Save          ",
 | 
						|
  "Load / Re-load          ",
 | 
						|
  "Settings                ",
 | 
						|
  "Clear / with backcolor  ",
 | 
						|
  "Help / Statistics       ",
 | 
						|
  "Undo / Redo             ",
 | 
						|
  "Kill current page       ",
 | 
						|
  "Quit                    ",
 | 
						|
  "Palette editor          ",
 | 
						|
  "Scroll pal. bkwd / Fast ",
 | 
						|
  "Scroll pal. fwd / Fast  ",
 | 
						|
  "Color #"                 ,
 | 
						|
  "Hide tool bar           "
 | 
						|
};
 | 
						|
// Sauvegarde un bloc (généralement l'arrière-plan d'une fenêtre)
 | 
						|
void Save_background(byte **buffer, int x_pos, int y_pos, int width, int height)
 | 
						|
{
 | 
						|
  int index;
 | 
						|
  if(*buffer != NULL) DEBUG("WARNING : buffer already allocated !!!",0);
 | 
						|
  *buffer=(byte *) malloc(width*Menu_factor_X*height*Menu_factor_Y*Pixel_width);
 | 
						|
  for (index=0; index<(height*Menu_factor_Y); index++)
 | 
						|
    Read_line(x_pos,y_pos+index,width*Menu_factor_X,(*buffer)+((int)index*width*Menu_factor_X*Pixel_width));
 | 
						|
}
 | 
						|
// Restaure de ce que la fenêtre cachait
 | 
						|
void Restore_background(byte *buffer, int x_pos, int y_pos, int width, int height)
 | 
						|
{
 | 
						|
  int index;
 | 
						|
  for (index=0; index<height*Menu_factor_Y; index++)
 | 
						|
    Display_line_fast(x_pos,y_pos+index,width*Menu_factor_X,buffer+((int)index*width*Menu_factor_X*Pixel_width));
 | 
						|
  free(buffer);
 | 
						|
}
 | 
						|
// Ecrit un pixel dans un fond de fenêtre
 | 
						|
void Pixel_background(int x_pos, int y_pos, byte color)
 | 
						|
{
 | 
						|
  int x_repetition=Pixel_width;
 | 
						|
  while (x_repetition--)
 | 
						|
    (Window_background[0][x_pos*Pixel_width+x_repetition+y_pos*Window_width*Pixel_width*Menu_factor_X])=color;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
int Button_under_mouse(void)
 | 
						|
{
 | 
						|
  int btn_number;
 | 
						|
  short x_pos;
 | 
						|
  short y_pos;
 | 
						|
 | 
						|
  x_pos=(Mouse_X              )/Menu_factor_X;
 | 
						|
  y_pos=(Mouse_Y-Menu_Y)/Menu_factor_Y;
 | 
						|
 | 
						|
  for (btn_number=0;btn_number<NB_BUTTONS;btn_number++)
 | 
						|
  {
 | 
						|
    switch(Button[btn_number].Shape)
 | 
						|
    {
 | 
						|
      case BUTTON_SHAPE_NO_FRAME :
 | 
						|
      case BUTTON_SHAPE_RECTANGLE  :
 | 
						|
 | 
						|
        if ((x_pos>=Button[btn_number].X_offset) &&
 | 
						|
            (y_pos>=Button[btn_number].Y_offset) &&
 | 
						|
            (x_pos<=Button[btn_number].X_offset+Button[btn_number].Width) &&
 | 
						|
            (y_pos<=Button[btn_number].Y_offset+Button[btn_number].Height))
 | 
						|
          return btn_number;
 | 
						|
        break;
 | 
						|
 | 
						|
      case BUTTON_SHAPE_TRIANGLE_TOP_LEFT:
 | 
						|
        if ((x_pos>=Button[btn_number].X_offset) &&
 | 
						|
            (y_pos>=Button[btn_number].Y_offset) &&
 | 
						|
            (x_pos+y_pos-(short)Button[btn_number].Y_offset-(short)Button[btn_number].X_offset<=Button[btn_number].Width))
 | 
						|
          return btn_number;
 | 
						|
        break;
 | 
						|
 | 
						|
      case BUTTON_SHAPE_TRIANGLE_BOTTOM_RIGHT:
 | 
						|
        if ((x_pos<=Button[btn_number].X_offset+Button[btn_number].Width) &&
 | 
						|
            (y_pos<=Button[btn_number].Y_offset+Button[btn_number].Height) &&
 | 
						|
            (x_pos+y_pos-(short)Button[btn_number].Y_offset-(short)Button[btn_number].X_offset>=Button[btn_number].Width))
 | 
						|
          return btn_number;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void Draw_menu_button_frame(byte btn_number,byte pressed)
 | 
						|
{
 | 
						|
  byte color_top_left;
 | 
						|
  byte color_bottom_right;
 | 
						|
  byte color_diagonal;
 | 
						|
  word start_x;
 | 
						|
  word start_y;
 | 
						|
  word end_x;
 | 
						|
  word end_y;
 | 
						|
  word x_pos;
 | 
						|
  word y_pos;
 | 
						|
 | 
						|
  start_x=Button[btn_number].X_offset;
 | 
						|
  start_y=Button[btn_number].Y_offset;
 | 
						|
  end_x  =start_x+Button[btn_number].Width;
 | 
						|
  end_y  =start_y+Button[btn_number].Height;
 | 
						|
 | 
						|
  if (!pressed)
 | 
						|
  {
 | 
						|
    color_top_left=MC_White;
 | 
						|
    color_bottom_right=MC_Dark;
 | 
						|
    color_diagonal=MC_Light;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    color_top_left=MC_Dark;
 | 
						|
    color_bottom_right=MC_Black;
 | 
						|
    color_diagonal=MC_Dark;
 | 
						|
  }
 | 
						|
 | 
						|
  switch(Button[btn_number].Shape)
 | 
						|
  {
 | 
						|
    case BUTTON_SHAPE_NO_FRAME :
 | 
						|
      break;
 | 
						|
    case BUTTON_SHAPE_RECTANGLE  :
 | 
						|
      // On colorie le point haut droit
 | 
						|
      Pixel_in_menu(end_x,start_y,color_diagonal);
 | 
						|
      GFX_menu_block[start_y][end_x]=color_diagonal;
 | 
						|
      // On colorie le point bas gauche
 | 
						|
      Pixel_in_menu(start_x,end_y,color_diagonal);
 | 
						|
      GFX_menu_block[end_y][start_x]=color_diagonal;
 | 
						|
      // On colorie la partie haute
 | 
						|
      for (x_pos=start_x;x_pos<=end_x-1;x_pos++)
 | 
						|
      {
 | 
						|
        Pixel_in_menu(x_pos,start_y,color_top_left);
 | 
						|
        GFX_menu_block[start_y][x_pos]=color_top_left;
 | 
						|
      }
 | 
						|
      for (y_pos=start_y+1;y_pos<=end_y-1;y_pos++)
 | 
						|
      {
 | 
						|
        // On colorie la partie gauche
 | 
						|
        Pixel_in_menu(start_x,y_pos,color_top_left);
 | 
						|
        GFX_menu_block[y_pos][start_x]=color_top_left;
 | 
						|
        // On colorie la partie droite
 | 
						|
        Pixel_in_menu(end_x,y_pos,color_bottom_right);
 | 
						|
        GFX_menu_block[y_pos][end_x]=color_bottom_right;
 | 
						|
      }
 | 
						|
      // On colorie la partie basse
 | 
						|
      for (x_pos=start_x+1;x_pos<=end_x;x_pos++)
 | 
						|
      {
 | 
						|
        Pixel_in_menu(x_pos,end_y,color_bottom_right);
 | 
						|
        GFX_menu_block[end_y][x_pos]=color_bottom_right;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case BUTTON_SHAPE_TRIANGLE_TOP_LEFT:
 | 
						|
      // On colorie le point haut droit
 | 
						|
      Pixel_in_menu(end_x,start_y,color_diagonal);
 | 
						|
      GFX_menu_block[start_y][end_x]=color_diagonal;
 | 
						|
      // On colorie le point bas gauche
 | 
						|
      Pixel_in_menu(start_x,end_y,color_diagonal);
 | 
						|
      GFX_menu_block[end_y][start_x]=color_diagonal;
 | 
						|
      // On colorie le coin haut gauche
 | 
						|
      for (x_pos=0;x_pos<Button[btn_number].Width;x_pos++)
 | 
						|
      {
 | 
						|
        Pixel_in_menu(start_x+x_pos,start_y,color_top_left);
 | 
						|
        GFX_menu_block[start_y][start_x+x_pos]=color_top_left;
 | 
						|
        Pixel_in_menu(start_x,start_y+x_pos,color_top_left);
 | 
						|
        GFX_menu_block[start_y+x_pos][start_x]=color_top_left;
 | 
						|
      }
 | 
						|
      // On colorie la diagonale
 | 
						|
      for (x_pos=1;x_pos<Button[btn_number].Width;x_pos++)
 | 
						|
      {
 | 
						|
        Pixel_in_menu(start_x+x_pos,end_y-x_pos,color_bottom_right);
 | 
						|
        GFX_menu_block[end_y-x_pos][start_x+x_pos]=color_bottom_right;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case BUTTON_SHAPE_TRIANGLE_BOTTOM_RIGHT:
 | 
						|
      // On colorie le point haut droit
 | 
						|
      Pixel_in_menu(end_x,start_y,color_diagonal);
 | 
						|
      GFX_menu_block[start_y][end_x]=color_diagonal;
 | 
						|
      // On colorie le point bas gauche
 | 
						|
      Pixel_in_menu(start_x,end_y,color_diagonal);
 | 
						|
      GFX_menu_block[end_y][start_x]=color_diagonal;
 | 
						|
      // On colorie la diagonale
 | 
						|
      for (x_pos=1;x_pos<Button[btn_number].Width;x_pos++)
 | 
						|
      {
 | 
						|
        Pixel_in_menu(start_x+x_pos,end_y-x_pos,color_top_left);
 | 
						|
        GFX_menu_block[end_y-x_pos][start_x+x_pos]=color_top_left;
 | 
						|
      }
 | 
						|
      // On colorie le coin bas droite
 | 
						|
      for (x_pos=0;x_pos<Button[btn_number].Width;x_pos++)
 | 
						|
      {
 | 
						|
        Pixel_in_menu(end_x-x_pos,end_y,color_bottom_right);
 | 
						|
        GFX_menu_block[end_y][end_x-x_pos]=color_bottom_right;
 | 
						|
        Pixel_in_menu(end_x,end_y-x_pos,color_bottom_right);
 | 
						|
        GFX_menu_block[end_y-x_pos][end_x]=color_bottom_right;
 | 
						|
      }
 | 
						|
  }
 | 
						|
  if (Menu_is_visible)
 | 
						|
  {
 | 
						|
    Update_rect(
 | 
						|
      start_x*Menu_factor_X,
 | 
						|
      start_y*Menu_factor_Y + Menu_Y,
 | 
						|
      (end_x+1-start_x)*Menu_factor_X,
 | 
						|
      (end_y+1-start_y)*Menu_factor_Y);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//---------------------- Désenclenchement d'un bouton ------------------------
 | 
						|
void Unselect_bouton(int btn_number)
 | 
						|
{
 | 
						|
  if (Button[btn_number].Pressed)
 | 
						|
  {
 | 
						|
    // On affiche le cadre autour du bouton de façon à ce qu'il paraisse relâché
 | 
						|
    Draw_menu_button_frame(btn_number,BUTTON_RELEASED);
 | 
						|
    // On considère que le bouton est relâché
 | 
						|
    Button[btn_number].Pressed=BUTTON_RELEASED;
 | 
						|
    // On appelle le désenclenchement particulier au bouton:
 | 
						|
    Button[btn_number].Desenclencher();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//-Enclenchement d'un bouton (et désenclenchement de ceux de la même famille)-
 | 
						|
void Unselect_button(int btn_number,byte click)
 | 
						|
{
 | 
						|
  int family;
 | 
						|
  int b;
 | 
						|
  int icon;
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
 | 
						|
  // Certains boutons ont deux icones
 | 
						|
  icon=-1;
 | 
						|
  switch(btn_number)
 | 
						|
  {
 | 
						|
    case BUTTON_POLYGONS:
 | 
						|
    case BUTTON_POLYFILL:
 | 
						|
      icon=12;break;
 | 
						|
    case BUTTON_FLOODFILL:
 | 
						|
      icon=14;break;
 | 
						|
    case BUTTON_CIRCLES:
 | 
						|
    case BUTTON_FILLCIRC:
 | 
						|
      icon=10;break;
 | 
						|
    case BUTTON_SPHERES:
 | 
						|
      icon=16;break;
 | 
						|
  }
 | 
						|
  if (icon!=-1)
 | 
						|
    Display_sprite_in_menu(btn_number,icon+(click==RIGHT_SIDE));
 | 
						|
 | 
						|
  // On note déjà la famille du bouton (La "Famiglia" c'est sacré)
 | 
						|
  family=Button[btn_number].Famille;
 | 
						|
 | 
						|
  switch (family)
 | 
						|
  {
 | 
						|
    case FAMILY_TOOLBAR: // On ne fait rien (on préserve les interruptions)
 | 
						|
      break;
 | 
						|
 | 
						|
    case FAMILY_INTERRUPTION: // Petit cas spécial dans la famille "Interruption":
 | 
						|
      if ((btn_number!=BUTTON_MAGNIFIER) || (!Main_magnifier_mode))
 | 
						|
      // Pour chaque bouton:
 | 
						|
      for (b=0; b<NB_BUTTONS; b++)
 | 
						|
        // S'il est de la même famille
 | 
						|
        if (
 | 
						|
             (b!=btn_number) &&
 | 
						|
             (Button[b].Famille==FAMILY_INTERRUPTION) &&
 | 
						|
             (  (b!=BUTTON_MAGNIFIER) ||
 | 
						|
               ((b==BUTTON_MAGNIFIER) && (!Main_magnifier_mode)) )
 | 
						|
           )
 | 
						|
          // Alors on désenclenche le bouton
 | 
						|
          Unselect_bouton(b);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      // On désenclenche D'ABORD les interruptions
 | 
						|
      // Pour chaque bouton:
 | 
						|
      for (b=0; b<NB_BUTTONS; b++)
 | 
						|
        // S'il est de la famille interruption
 | 
						|
        if ( (b!=btn_number)
 | 
						|
          && (Button[b].Famille==FAMILY_INTERRUPTION)
 | 
						|
          // Et que ce n'est pas la loupe, ou alors qu'on n'est pas en mode loupe
 | 
						|
          && (!(Main_magnifier_mode && (b==BUTTON_MAGNIFIER))) )
 | 
						|
          // Alors on désenclenche le bouton
 | 
						|
          Unselect_bouton(b);
 | 
						|
      // Pour chaque bouton:
 | 
						|
      for (b=0; b<NB_BUTTONS; b++)
 | 
						|
        // S'il est de la même famille
 | 
						|
        if ( (b!=btn_number)
 | 
						|
          && (Button[b].Famille==family) )
 | 
						|
          // Alors on désenclenche le bouton
 | 
						|
          Unselect_bouton(b);
 | 
						|
  }
 | 
						|
 | 
						|
  // On affiche le cadre autour du bouton de façon à ce qu'il paraisse enfoncé
 | 
						|
  Draw_menu_button_frame(btn_number,BUTTON_PRESSED);
 | 
						|
 | 
						|
  Display_cursor();
 | 
						|
 | 
						|
  // On attend ensuite que l'utilisateur lâche son bouton:
 | 
						|
  Wait_end_of_click();
 | 
						|
 | 
						|
  // On considère que le bouton est enfoncé
 | 
						|
  Button[btn_number].Pressed=BUTTON_PRESSED;
 | 
						|
 | 
						|
  // Puis on se contente d'appeler l'action correspondant au bouton:
 | 
						|
  if (click==1)
 | 
						|
    Button[btn_number].Gauche();
 | 
						|
  else
 | 
						|
    Button[btn_number].Droite();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//--- Déplacer la barre de séparation entre la partie zoomée et la partie ----
 | 
						|
//------------------ non-zoomée lorsqu'on est en mode loupe ------------------
 | 
						|
void Move_separator(void)
 | 
						|
{
 | 
						|
  short old_main_separator_position=Main_separator_position;
 | 
						|
  short old_x_zoom=Main_X_zoom;
 | 
						|
  short offset=Main_X_zoom-Mouse_X;
 | 
						|
  byte  old_cursor_shape=Cursor_shape;
 | 
						|
  short old_mouse_x=-1;
 | 
						|
 | 
						|
  // Afficher la barre en XOR
 | 
						|
  Hide_cursor();
 | 
						|
  Windows_open=1;
 | 
						|
  Cursor_shape=CURSOR_SHAPE_HORIZONTAL;
 | 
						|
  Vertical_XOR_line(Main_separator_position,0,Menu_Y);
 | 
						|
  Vertical_XOR_line(Main_X_zoom-1,0,Menu_Y);
 | 
						|
  Display_cursor();
 | 
						|
  Update_rect(Main_separator_position,0,abs(Main_separator_position-Main_X_zoom)+1,Menu_Y);
 | 
						|
 | 
						|
  while (Mouse_K)
 | 
						|
  {
 | 
						|
    if (Mouse_X!=old_mouse_x)
 | 
						|
    {
 | 
						|
      old_mouse_x=Mouse_X;
 | 
						|
      Main_separator_proportion=(float)(Mouse_X+offset)/Screen_width;
 | 
						|
      Compute_separator_data();
 | 
						|
  
 | 
						|
      if (Main_X_zoom!=old_x_zoom)
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
  
 | 
						|
        // Effacer la barre en XOR
 | 
						|
        Vertical_XOR_line(old_main_separator_position,0,Menu_Y);
 | 
						|
        Vertical_XOR_line(old_x_zoom-1,0,Menu_Y);
 | 
						|
  
 | 
						|
        Update_rect(old_main_separator_position,0,abs(old_main_separator_position-old_x_zoom)+1,Menu_Y);
 | 
						|
  
 | 
						|
        old_main_separator_position=Main_separator_position;
 | 
						|
        old_x_zoom=Main_X_zoom;
 | 
						|
  
 | 
						|
        // Rafficher la barre en XOR
 | 
						|
        Vertical_XOR_line(Main_separator_position,0,Menu_Y);
 | 
						|
        Vertical_XOR_line(Main_X_zoom-1,0,Menu_Y);
 | 
						|
  
 | 
						|
        Update_rect(Main_separator_position,0,abs(Main_separator_position-Main_X_zoom)+1,Menu_Y);
 | 
						|
  
 | 
						|
        Display_cursor();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if(!Get_input())Wait_VBL();
 | 
						|
  }
 | 
						|
 | 
						|
  // Effacer la barre en XOR
 | 
						|
  Hide_cursor();
 | 
						|
  Vertical_XOR_line(Main_separator_position,0,Menu_Y);
 | 
						|
  Vertical_XOR_line(Main_X_zoom-1,0,Menu_Y);
 | 
						|
  Windows_open=0;
 | 
						|
  Cursor_shape=old_cursor_shape;
 | 
						|
  Compute_magnifier_data();
 | 
						|
  Position_screen_according_to_zoom();
 | 
						|
  Compute_limits();
 | 
						|
  Display_all_screen();
 | 
						|
  Display_cursor();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//======================= Gestion principale du moteur =======================
 | 
						|
void Main_handler(void)
 | 
						|
{
 | 
						|
  static byte temp_color;
 | 
						|
  int  button_index;           // Numéro de bouton de menu en cours
 | 
						|
  int  prev_button_number=0; // Numéro de bouton de menu sur lequel on était précédemment
 | 
						|
  byte blink;                   // L'opération demande un effacement du curseur
 | 
						|
  int  shortcut_button;           // Button à enclencher d'après la touche de raccourci enfoncée
 | 
						|
  byte clicked_button = 0;         // Côté du bouton à enclencher d'après la touche de raccourci enfoncée
 | 
						|
  int  key_index;           // index du tableau de touches spéciales correspondant à la touche enfoncée
 | 
						|
  char str[25];
 | 
						|
  byte temp;
 | 
						|
 | 
						|
  do
 | 
						|
  {
 | 
						|
    if(Get_input())
 | 
						|
    {
 | 
						|
    // Redimensionnement demandé
 | 
						|
    if (Resize_width || Resize_height)
 | 
						|
    {
 | 
						|
      Hide_cursor();
 | 
						|
      Init_mode_video(Resize_width, Resize_height, 0, Pixel_ratio);
 | 
						|
      // Remise à zero des variables indiquant le Redimensionnement demandé
 | 
						|
      Display_menu();
 | 
						|
      Display_all_screen();
 | 
						|
      Display_cursor();
 | 
						|
    }
 | 
						|
    
 | 
						|
    // Evenement de fermeture
 | 
						|
    if (Quit_is_required)
 | 
						|
    {
 | 
						|
      Quit_is_required=0;
 | 
						|
      Button_Quit();
 | 
						|
    }
 | 
						|
    
 | 
						|
    // Gestion des touches
 | 
						|
    if (Key)
 | 
						|
    {
 | 
						|
      for (key_index=0;(key_index<NB_SPECIAL_SHORTCUTS) && !Is_shortcut(Key,key_index);key_index++);
 | 
						|
 | 
						|
      // Gestion des touches spéciales:
 | 
						|
      if (key_index>SPECIAL_CLICK_RIGHT)
 | 
						|
      switch(key_index)
 | 
						|
      {
 | 
						|
        case SPECIAL_SCROLL_UP : // Scroll up
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(0,-(Main_magnifier_height>>2));
 | 
						|
          else
 | 
						|
            Scroll_screen(0,-(Screen_height>>3));
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_DOWN : // Scroll down
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(0,(Main_magnifier_height>>2));
 | 
						|
          else
 | 
						|
            Scroll_screen(0,(Screen_height>>3));
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_LEFT : // Scroll left
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(-(Main_magnifier_width>>2),0);
 | 
						|
          else
 | 
						|
            Scroll_screen(-(Screen_width>>3),0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_RIGHT : // Scroll right
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier((Main_magnifier_width>>2),0);
 | 
						|
          else
 | 
						|
            Scroll_screen((Screen_width>>3),0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_UP_FAST : // Scroll up faster
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(0,-(Main_magnifier_height>>1));
 | 
						|
          else
 | 
						|
            Scroll_screen(0,-(Screen_height>>2));
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_DOWN_FAST : // Scroll down faster
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(0,(Main_magnifier_height>>1));
 | 
						|
          else
 | 
						|
            Scroll_screen(0,(Screen_height>>2));
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_LEFT_FAST : // Scroll left faster
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(-(Main_magnifier_width>>1),0);
 | 
						|
          else
 | 
						|
            Scroll_screen(-(Screen_width>>2),0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_RIGHT_FAST : // Scroll right faster
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier((Main_magnifier_width>>1),0);
 | 
						|
          else
 | 
						|
            Scroll_screen((Screen_width>>2),0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_UP_SLOW : // Scroll up slower
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(0,-1);
 | 
						|
          else
 | 
						|
            Scroll_screen(0,-1);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_DOWN_SLOW : // Scroll down slower
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(0,1);
 | 
						|
          else
 | 
						|
            Scroll_screen(0,1);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_LEFT_SLOW : // Scroll left slower
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(-1,0);
 | 
						|
          else
 | 
						|
            Scroll_screen(-1,0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SCROLL_RIGHT_SLOW : // Scroll right slower
 | 
						|
          if (Main_magnifier_mode)
 | 
						|
            Scroll_magnifier(1,0);
 | 
						|
          else
 | 
						|
            Scroll_screen(1,0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_NEXT_FORECOLOR : // Next foreground color
 | 
						|
          Special_next_forecolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_PREVIOUS_FORECOLOR : // Previous foreground color
 | 
						|
          Special_previous_forecolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_NEXT_BACKCOLOR : // Next background color
 | 
						|
          Special_next_backcolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_PREVIOUS_BACKCOLOR : // Previous background color
 | 
						|
          Special_previous_backcolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SMALLER_PAINTBRUSH: // Rétrécir le pinceau
 | 
						|
          Smaller_paintbrush();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_BIGGER_PAINTBRUSH: // Grossir le pinceau
 | 
						|
          Bigger_paintbrush();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_NEXT_USER_FORECOLOR : // Next user-defined foreground color
 | 
						|
          Message_not_implemented(); // !!! TEMPORAIRE !!!
 | 
						|
          //Special_Next_user_forecolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_PREVIOUS_USER_FORECOLOR : // Previous user-defined foreground color
 | 
						|
          Message_not_implemented(); // !!! TEMPORAIRE !!!
 | 
						|
          //Special_Previous_user_forecolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_NEXT_USER_BACKCOLOR : // Next user-defined background color
 | 
						|
          Message_not_implemented(); // !!! TEMPORAIRE !!!
 | 
						|
          //Special_Next_user_backcolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_PREVIOUS_USER_BACKCOLOR : // Previous user-defined background color
 | 
						|
          Message_not_implemented(); // !!! TEMPORAIRE !!!
 | 
						|
          //Special_Previous_user_backcolor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SHOW_HIDE_CURSOR : // Show / Hide cursor
 | 
						|
          Hide_cursor();
 | 
						|
          Cursor_hidden=!Cursor_hidden;
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_DOT_PAINTBRUSH : // Paintbrush = "."
 | 
						|
          Hide_cursor();
 | 
						|
          Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND;
 | 
						|
          Set_paintbrush_size(1,1);
 | 
						|
          Change_paintbrush_shape(PAINTBRUSH_SHAPE_ROUND);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_CONTINUOUS_DRAW : // Continuous freehand drawing
 | 
						|
          Unselect_button(BUTTON_DRAW,LEFT_SIDE);
 | 
						|
          // ATTENTION CE TRUC EST MOCHE ET VA MERDER SI ON SE MET A UTILISER DES BOUTONS POPUPS
 | 
						|
          while (Current_operation!=OPERATION_CONTINUOUS_DRAW)
 | 
						|
            Unselect_button(BUTTON_DRAW,RIGHT_SIDE);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_FLIP_X : // Flip X
 | 
						|
          Hide_cursor();
 | 
						|
          Flip_X_lowlevel();
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_FLIP_Y : // Flip Y
 | 
						|
          Hide_cursor();
 | 
						|
          Flip_Y_lowlevel();
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_ROTATE_90 : // 90° brush rotation
 | 
						|
          Hide_cursor();
 | 
						|
          Rotate_90_deg();
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_ROTATE_180 : // 180° brush rotation
 | 
						|
          Hide_cursor();
 | 
						|
          if (Brush_height&1)
 | 
						|
          {
 | 
						|
            // Brush de hauteur impaire
 | 
						|
            Flip_X_lowlevel();
 | 
						|
            Flip_Y_lowlevel();
 | 
						|
          }
 | 
						|
          else
 | 
						|
            Rotate_180_deg_lowlevel();
 | 
						|
          Brush_offset_X=(Brush_width>>1);
 | 
						|
          Brush_offset_Y=(Brush_height>>1);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_STRETCH : // Stretch brush
 | 
						|
          Hide_cursor();
 | 
						|
          Start_operation_stack(OPERATION_STRETCH_BRUSH);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_DISTORT : // Distort brush
 | 
						|
          Message_not_implemented(); // !!! TEMPORAIRE !!!
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_ROTATE_ANY_ANGLE : // Rotate brush by any angle
 | 
						|
          Hide_cursor();
 | 
						|
          Start_operation_stack(OPERATION_ROTATE_BRUSH);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_OUTLINE : // Outline brush
 | 
						|
          Hide_cursor();
 | 
						|
          Outline_brush();
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_NIBBLE : // Nibble brush
 | 
						|
          Hide_cursor();
 | 
						|
          Nibble_brush();
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_GET_BRUSH_COLORS : // Get colors from brush
 | 
						|
          Get_colors_from_brush();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_RECOLORIZE_BRUSH : // Recolorize brush
 | 
						|
          Hide_cursor();
 | 
						|
          Remap_brush();
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_LOAD_BRUSH :
 | 
						|
          Load_picture(0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SAVE_BRUSH :
 | 
						|
          Save_picture(0);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_ZOOM_IN : // Zoom in
 | 
						|
          Zoom(+1);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_ZOOM_OUT : // Zoom out
 | 
						|
          Zoom(-1);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_CENTER_ATTACHMENT : // Center brush attachment
 | 
						|
          Hide_cursor();
 | 
						|
          Brush_offset_X=(Brush_width>>1);
 | 
						|
          Brush_offset_Y=(Brush_height>>1);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_TOP_LEFT_ATTACHMENT : // Top-left brush attachment
 | 
						|
          Hide_cursor();
 | 
						|
          Brush_offset_X=0;
 | 
						|
          Brush_offset_Y=0;
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_TOP_RIGHT_ATTACHMENT : // Top-right brush attachment
 | 
						|
          Hide_cursor();
 | 
						|
          Brush_offset_X=(Brush_width-1);
 | 
						|
          Brush_offset_Y=0;
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_BOTTOM_LEFT_ATTACHMENT : // Bottom-left brush attachment
 | 
						|
          Hide_cursor();
 | 
						|
          Brush_offset_X=0;
 | 
						|
          Brush_offset_Y=(Brush_height-1);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_BOTTOM_RIGHT_ATTACHMENT : // Bottom right brush attachment
 | 
						|
          Hide_cursor();
 | 
						|
          Brush_offset_X=(Brush_width-1);
 | 
						|
          Brush_offset_Y=(Brush_height-1);
 | 
						|
          Display_cursor();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_EXCLUDE_COLORS_MENU : // Exclude colors menu
 | 
						|
          Menu_tag_colors("Tag colors to exclude",Exclude_color,&temp,1, NULL);
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_INVERT_SIEVE :
 | 
						|
          Invert_trame();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SHADE_MODE :
 | 
						|
          Button_Shade_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SHADE_MENU :
 | 
						|
          Button_Shade_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_QUICK_SHADE_MODE :
 | 
						|
          Button_Quick_shade_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_QUICK_SHADE_MENU :
 | 
						|
          Button_Quick_shade_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_STENCIL_MODE :
 | 
						|
          Button_Stencil_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_STENCIL_MENU :
 | 
						|
          Button_Stencil_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_MASK_MODE :
 | 
						|
          Button_Mask_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_MASK_MENU :
 | 
						|
          Button_Mask_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_GRID_MODE :
 | 
						|
          Button_Snap_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_GRID_MENU :
 | 
						|
          Button_Grid_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SIEVE_MODE :
 | 
						|
          Button_Trame_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SIEVE_MENU :
 | 
						|
          Button_Trame_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_COLORIZE_MODE :
 | 
						|
          Button_Colorize_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_COLORIZE_MENU :
 | 
						|
          Button_Colorize_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SMOOTH_MODE :
 | 
						|
          Button_Smooth_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SMOOTH_MENU :
 | 
						|
          Button_Smooth_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_SMEAR_MODE :
 | 
						|
          Button_Smear_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_TILING_MODE :
 | 
						|
          Button_Tiling_mode();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        case SPECIAL_TILING_MENU :
 | 
						|
          Button_Tiling_menu();
 | 
						|
          Key=0;
 | 
						|
          break;
 | 
						|
        default   : // Gestion des touches de raccourci de bouton:
 | 
						|
          // Pour chaque bouton
 | 
						|
          shortcut_button=-1;
 | 
						|
          for (button_index=0;button_index<NB_BUTTONS;button_index++)
 | 
						|
          {
 | 
						|
            if (Is_shortcut(Key,0x100+button_index))
 | 
						|
            {
 | 
						|
              shortcut_button=button_index;
 | 
						|
              clicked_button  =LEFT_SIDE;
 | 
						|
              button_index=NB_BUTTONS;
 | 
						|
            }
 | 
						|
            else if (Is_shortcut(Key,0x200+button_index))
 | 
						|
            {
 | 
						|
              shortcut_button=button_index;
 | 
						|
              clicked_button  =RIGHT_SIDE;
 | 
						|
              button_index=NB_BUTTONS;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          // Après avoir scruté les boutons, si la recherche a été fructueuse,
 | 
						|
          // on lance le bouton.
 | 
						|
          if (shortcut_button!=-1)
 | 
						|
          {
 | 
						|
            Unselect_button(shortcut_button,clicked_button);
 | 
						|
            prev_button_number=-1;
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
      // Si on a modifié un effet, il faut rafficher le bouton des effets en
 | 
						|
      // conséquence.
 | 
						|
      if ((key_index>=SPECIAL_SHADE_MODE)
 | 
						|
       && (key_index<=SPECIAL_TILING_MENU))
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        Draw_menu_button_frame(BUTTON_EFFECTS,
 | 
						|
          (Shade_mode||Quick_shade_mode||Colorize_mode||Smooth_mode||Tiling_mode||Smear_mode||Stencil_mode||Mask_mode||Sieve_mode||Snap_mode));
 | 
						|
        Display_cursor();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    }
 | 
						|
    else Wait_VBL(); // S'il n'y a pas d'évènement, on ne gère pas tout ça et on attend un peu. La partie en dessous doit être exécutée quand
 | 
						|
                     // même pour les trucs asynchrones, par exemple le spray.
 | 
						|
 | 
						|
    // Gestion de la souris
 | 
						|
 | 
						|
    Cursor_in_menu=(Mouse_Y>=Menu_Y) ||
 | 
						|
                      ( (Main_magnifier_mode) && (Mouse_X>=Main_separator_position) &&
 | 
						|
                        (Mouse_X<Main_X_zoom) );
 | 
						|
 | 
						|
    if (Cursor_in_menu)
 | 
						|
    {
 | 
						|
      // Le curseur se trouve dans le menu
 | 
						|
 | 
						|
      // On cherche sur quel bouton du menu se trouve la souris:
 | 
						|
      button_index=Button_under_mouse();
 | 
						|
 | 
						|
      // Si le curseur vient de changer de zone
 | 
						|
 | 
						|
      if ( (button_index!=prev_button_number)
 | 
						|
        || (!Cursor_in_menu_previous)
 | 
						|
        || (prev_button_number==BUTTON_CHOOSE_COL) )
 | 
						|
      {
 | 
						|
        // Si le curseur n'est pas sur un bouton
 | 
						|
        if (button_index==-1)
 | 
						|
        {
 | 
						|
          if (Menu_is_visible)
 | 
						|
          {
 | 
						|
            // On nettoie les coordonnées
 | 
						|
            Hide_cursor();
 | 
						|
            Block(18*Menu_factor_X,Menu_status_Y,192*Menu_factor_X,Menu_factor_Y<<3,MC_Light);
 | 
						|
            Update_rect(18*Menu_factor_X,Menu_status_Y,192*Menu_factor_X,Menu_factor_Y<<3);
 | 
						|
            Display_cursor();
 | 
						|
          }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          if ( (prev_button_number!=BUTTON_CHOOSE_COL)
 | 
						|
            || (temp_color!=First_color_in_palette)
 | 
						|
            || (Old_MX!=Mouse_X) || (Old_MY!=Mouse_Y) )
 | 
						|
          {
 | 
						|
            // Le curseur est sur un nouveau bouton
 | 
						|
            if (button_index!=BUTTON_CHOOSE_COL)
 | 
						|
            {
 | 
						|
              Hide_cursor();
 | 
						|
              Print_in_menu(Menu_tooltip[button_index],0);
 | 
						|
              Display_cursor();
 | 
						|
            }
 | 
						|
            else
 | 
						|
            { // Le curseur est-il sur une couleur de la palette?
 | 
						|
              int color;
 | 
						|
              if ((color=Pick_color_in_palette())!=-1)
 | 
						|
              {
 | 
						|
                Hide_cursor();
 | 
						|
                strcpy(str,Menu_tooltip[button_index]);
 | 
						|
                sprintf(str+strlen(str),"%d (%d,%d,%d)",color,Main_palette[color].R,Main_palette[color].G,Main_palette[color].B);
 | 
						|
                for (temp=strlen(str); temp<24; temp++)
 | 
						|
                  str[temp]=' ';
 | 
						|
                str[24]=0;
 | 
						|
                Print_in_menu(str,0);
 | 
						|
                Display_cursor();
 | 
						|
              }
 | 
						|
              else
 | 
						|
              {
 | 
						|
                if ( (Old_MX!=Mouse_X) || (Old_MY!=Mouse_Y) )
 | 
						|
                {
 | 
						|
                  Hide_cursor();
 | 
						|
                  Block(18*Menu_factor_X,Menu_status_Y,192*Menu_factor_X,Menu_factor_Y<<3,MC_Light);
 | 
						|
                  Update_rect(18*Menu_factor_X,Menu_status_Y,192*Menu_factor_X,8*Menu_factor_Y);
 | 
						|
                  Display_cursor();
 | 
						|
                }
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      prev_button_number=button_index;
 | 
						|
 | 
						|
      // Gestion des clicks
 | 
						|
      if (Mouse_K)
 | 
						|
      {
 | 
						|
        if (Mouse_Y>=Menu_Y)
 | 
						|
        {
 | 
						|
          if (button_index>=0)
 | 
						|
          {
 | 
						|
            Unselect_button(button_index,Mouse_K);
 | 
						|
            prev_button_number=-1;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        else
 | 
						|
          if (Main_magnifier_mode) Move_separator();
 | 
						|
      }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    // we need to refresh that one as we may come from a sub window
 | 
						|
    Cursor_in_menu=(Mouse_Y>=Menu_Y) ||
 | 
						|
                      ( (Main_magnifier_mode) && (Mouse_X>=Main_separator_position) &&
 | 
						|
                        (Mouse_X<Main_X_zoom) );
 | 
						|
 | 
						|
 | 
						|
    // Le curseur se trouve dans l'image
 | 
						|
    if ( (!Cursor_in_menu) && (Menu_is_visible) && (Old_MY != Mouse_Y || Old_MX != Mouse_X || Key || Mouse_K)) // On ne met les coordonnées à jour que si l'utilisateur a fait un truc
 | 
						|
    {
 | 
						|
       if ( (Current_operation!=OPERATION_COLORPICK) && (Current_operation!=OPERATION_REPLACE) )
 | 
						|
       {
 | 
						|
          if(Cursor_in_menu_previous)
 | 
						|
          {
 | 
						|
             Print_in_menu("X:       Y:             ",0);
 | 
						|
          }
 | 
						|
       }
 | 
						|
       else
 | 
						|
       {
 | 
						|
          if(Cursor_in_menu_previous)
 | 
						|
          {
 | 
						|
             Print_in_menu("X:       Y:       (    )",0);
 | 
						|
          }
 | 
						|
       }
 | 
						|
       Cursor_in_menu_previous = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    if(Cursor_in_menu)
 | 
						|
    {
 | 
						|
        Cursor_in_menu_previous = 1;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      blink=Operation[Current_operation][Mouse_K_unique][Operation_stack_size].Hide_cursor;
 | 
						|
 
 | 
						|
      if (blink) Hide_cursor();
 | 
						|
 
 | 
						|
      Operation[Current_operation][Mouse_K_unique][Operation_stack_size].Action();
 | 
						|
 | 
						|
      if (blink) Display_cursor();
 | 
						|
    }
 | 
						|
    Old_MX=Mouse_X;
 | 
						|
    Old_MY=Mouse_Y;
 | 
						|
  }
 | 
						|
  while (!Quitting);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//////////////////////////////////////////////////////////////////////////////
 | 
						|
//      différentes fonctions d'affichage utilisées dans les fenêtres       //
 | 
						|
//////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
//----------------------- Tracer une fenêtre d'options -----------------------
 | 
						|
 | 
						|
void Open_window(word width,word height, char * title)
 | 
						|
// Lors de l'appel à cette procédure, la souris doit être affichée.
 | 
						|
// En sortie de cette procedure, la souris est effacée.
 | 
						|
{
 | 
						|
  //word i,j;
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
 | 
						|
  Windows_open++;
 | 
						|
 | 
						|
  Window_width=width;
 | 
						|
  Window_height=height;
 | 
						|
 | 
						|
  // Positionnement de la fenêtre
 | 
						|
  Window_pos_X=(Screen_width-(width*Menu_factor_X))>>1;
 | 
						|
 | 
						|
  Window_pos_Y=(Screen_height-(height*Menu_factor_Y))>>1;
 | 
						|
 | 
						|
  // Sauvegarde de ce que la fenêtre remplace
 | 
						|
  Save_background(&(Window_background[Windows_open-1]), Window_pos_X, Window_pos_Y, width, height);
 | 
						|
 | 
						|
  // Fenêtre grise
 | 
						|
  Block(Window_pos_X+(Menu_factor_X<<1),Window_pos_Y+(Menu_factor_Y<<1),(width-4)*Menu_factor_X,(height-4)*Menu_factor_Y,MC_Light);
 | 
						|
 | 
						|
  // -- Frame de la fenêtre ----- --- -- -  -
 | 
						|
 | 
						|
  // Frame noir puis en relief
 | 
						|
  Window_display_frame_mono(0,0,width,height,MC_Black);
 | 
						|
  Window_display_frame_out(1,1,width-2,height-2);
 | 
						|
 | 
						|
  // Barre sous le titre
 | 
						|
  Block(Window_pos_X+(Menu_factor_X<<3),Window_pos_Y+(11*Menu_factor_Y),(width-16)*Menu_factor_X,Menu_factor_Y,MC_Dark);
 | 
						|
  Block(Window_pos_X+(Menu_factor_X<<3),Window_pos_Y+(12*Menu_factor_Y),(width-16)*Menu_factor_X,Menu_factor_Y,MC_White);
 | 
						|
 | 
						|
  Print_in_window((width-(strlen(title)<<3))>>1,3,title,MC_Black,MC_Light);
 | 
						|
 | 
						|
  if (Windows_open == 1)
 | 
						|
  {
 | 
						|
    Menu_is_visible_before_window=Menu_is_visible;
 | 
						|
    Menu_is_visible=0;
 | 
						|
    Menu_Y_before_window=Menu_Y;
 | 
						|
    Menu_Y=Screen_height;
 | 
						|
    Cursor_shape_before_window=Cursor_shape;
 | 
						|
    Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
    Paintbrush_hidden_before_window=Paintbrush_hidden;
 | 
						|
    Paintbrush_hidden=1;
 | 
						|
  }
 | 
						|
 | 
						|
  // Initialisation des listes de boutons de la fenêtre
 | 
						|
  Window_normal_button_list  =NULL;
 | 
						|
  Window_palette_button_list =NULL;
 | 
						|
  Window_scroller_button_list=NULL;
 | 
						|
  Window_special_button_list =NULL;
 | 
						|
  Window_dropdown_button_list=NULL;
 | 
						|
  Window_nb_buttons            =0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
//----------------------- Fermer une fenêtre d'options -----------------------
 | 
						|
 | 
						|
void Close_window(void)
 | 
						|
// Lors de l'appel à cette procedure, la souris doit être affichée.
 | 
						|
// En sortie de cette procedure, la souris est effacée.
 | 
						|
{
 | 
						|
  T_Normal_button   * temp1;
 | 
						|
  T_Palette_button  * temp2;
 | 
						|
  T_Scroller_button * temp3;
 | 
						|
  T_Special_button  * temp4;
 | 
						|
  T_Dropdown_button * temp5;
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
 | 
						|
  while (Window_normal_button_list)
 | 
						|
  {
 | 
						|
    temp1=Window_normal_button_list->Next;
 | 
						|
    free(Window_normal_button_list);
 | 
						|
    Window_normal_button_list=temp1;
 | 
						|
  }
 | 
						|
  while (Window_palette_button_list)
 | 
						|
  {
 | 
						|
    temp2=Window_palette_button_list->Next;
 | 
						|
    free(Window_palette_button_list);
 | 
						|
    Window_palette_button_list=temp2;
 | 
						|
  }
 | 
						|
  while (Window_scroller_button_list)
 | 
						|
  {
 | 
						|
    temp3=Window_scroller_button_list->Next;
 | 
						|
    free(Window_scroller_button_list);
 | 
						|
    Window_scroller_button_list=temp3;
 | 
						|
  }
 | 
						|
  while (Window_special_button_list)
 | 
						|
  {
 | 
						|
    temp4=Window_special_button_list->Next;
 | 
						|
    free(Window_special_button_list);
 | 
						|
    Window_special_button_list=temp4;
 | 
						|
  }
 | 
						|
  while (Window_dropdown_button_list)
 | 
						|
  {
 | 
						|
    temp5=Window_dropdown_button_list->Next;
 | 
						|
    Window_dropdown_clear_items(Window_dropdown_button_list);
 | 
						|
    free(Window_dropdown_button_list);
 | 
						|
    Window_dropdown_button_list=temp5;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Windows_open != 1)
 | 
						|
  {
 | 
						|
    // Restore de ce que la fenêtre cachait
 | 
						|
    Restore_background(Window_background[Windows_open-1], Window_pos_X, Window_pos_Y, Window_width, Window_height);
 | 
						|
    Window_background[Windows_open-1]=NULL;
 | 
						|
    Update_rect(Window_pos_X,Window_pos_Y,Window_width*Menu_factor_X,Window_height*Menu_factor_Y);
 | 
						|
    Windows_open--;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    free(Window_background[Windows_open-1]);
 | 
						|
    Window_background[Windows_open-1]=NULL;
 | 
						|
    Windows_open--;
 | 
						|
  
 | 
						|
    Paintbrush_hidden=Paintbrush_hidden_before_window;
 | 
						|
  
 | 
						|
    Compute_paintbrush_coordinates();
 | 
						|
  
 | 
						|
    Menu_Y=Menu_Y_before_window;
 | 
						|
    Menu_is_visible=Menu_is_visible_before_window;
 | 
						|
    Cursor_shape=Cursor_shape_before_window;
 | 
						|
    
 | 
						|
    Display_all_screen();
 | 
						|
    Display_menu();
 | 
						|
  }
 | 
						|
 | 
						|
  Key=0;
 | 
						|
  Mouse_K=0;
 | 
						|
  
 | 
						|
  Old_MX = -1;
 | 
						|
  Old_MY = -1;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//---------------- Dessiner un bouton normal dans une fenêtre ----------------
 | 
						|
 | 
						|
void Window_draw_normal_bouton(word x_pos,word y_pos,word width,word height,
 | 
						|
                                    char * title,byte undersc_letter,byte clickable)
 | 
						|
{
 | 
						|
  byte title_color;
 | 
						|
  word text_x_pos,text_y_pos;
 | 
						|
 | 
						|
  if (clickable)
 | 
						|
  {
 | 
						|
    Window_display_frame_out(x_pos,y_pos,width,height);
 | 
						|
    Window_display_frame_generic(x_pos-1,y_pos-1,width+2,height+2,MC_Black,MC_Black,MC_Dark,MC_Dark,MC_Dark);
 | 
						|
    title_color=MC_Black;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    Window_display_frame_out(x_pos,y_pos,width,height);
 | 
						|
    Window_display_frame_mono(x_pos-1,y_pos-1,width+2,height+2,MC_Light);
 | 
						|
    title_color=MC_Dark;
 | 
						|
  }
 | 
						|
 | 
						|
  text_x_pos=x_pos+( (width-(strlen(title)<<3)+1) >>1 );
 | 
						|
  text_y_pos=y_pos+((height-7)>>1);
 | 
						|
  Print_in_window(text_x_pos,text_y_pos,title,title_color,MC_Light);
 | 
						|
 | 
						|
  if (undersc_letter)
 | 
						|
    Block(Window_pos_X+((text_x_pos+((undersc_letter-1)<<3))*Menu_factor_X),
 | 
						|
          Window_pos_Y+((text_y_pos+8)*Menu_factor_Y),
 | 
						|
          Menu_factor_X<<3,Menu_factor_Y,MC_Dark);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// -- Button normal enfoncé dans la fenêtre --
 | 
						|
void Window_select_normal_button(word x_pos,word y_pos,word width,word height)
 | 
						|
{
 | 
						|
  Window_display_frame_generic(x_pos,y_pos,width,height,MC_Dark,MC_Black,MC_Dark,MC_Dark,MC_Black);
 | 
						|
  Update_rect(Window_pos_X+x_pos*Menu_factor_X, Window_pos_Y+y_pos*Menu_factor_Y, width*Menu_factor_X, height*Menu_factor_Y);
 | 
						|
}
 | 
						|
 | 
						|
// -- Button normal désenfoncé dans la fenêtre --
 | 
						|
void Window_unselect_normal_button(word x_pos,word y_pos,word width,word height)
 | 
						|
{
 | 
						|
  Window_display_frame_out(x_pos,y_pos,width,height);
 | 
						|
  Update_rect(Window_pos_X+x_pos*Menu_factor_X, Window_pos_Y+y_pos*Menu_factor_Y, width*Menu_factor_X, height*Menu_factor_Y);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//--------------- Dessiner un bouton palette dans une fenêtre ----------------
 | 
						|
void Window_draw_palette_bouton(word x_pos,word y_pos)
 | 
						|
{
 | 
						|
  word color;
 | 
						|
 | 
						|
  for (color=0; color<=255; color++)
 | 
						|
    Block( Window_pos_X+((((color >> 4)*10)+x_pos+6)*Menu_factor_X),Window_pos_Y+((((color & 15)*5)+y_pos+3)*Menu_factor_Y),Menu_factor_X*5,Menu_factor_Y*5,color);
 | 
						|
 | 
						|
  Window_display_frame(x_pos,y_pos,164,86);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// -------------------- Effacer les TAGs sur les palette ---------------------
 | 
						|
// Cette fonct° ne sert plus que lorsqu'on efface les tags dans le menu Spray.
 | 
						|
void Window_clear_tags(void)
 | 
						|
{
 | 
						|
  word origin_x;
 | 
						|
  word origin_y;
 | 
						|
  word x_pos;
 | 
						|
  word window_x_pos;
 | 
						|
  //word window_y_pos;
 | 
						|
 | 
						|
  origin_x=Window_pos_X+(Window_palette_button_list->Pos_X+3)*Menu_factor_X;
 | 
						|
  origin_y=Window_pos_Y+(Window_palette_button_list->Pos_Y+3)*Menu_factor_Y;
 | 
						|
  for (x_pos=0,window_x_pos=origin_x;x_pos<16;x_pos++,window_x_pos+=(Menu_factor_X*10))
 | 
						|
    Block(window_x_pos,origin_y,Menu_factor_X*3,Menu_factor_Y*80,MC_Light);
 | 
						|
  Update_rect(origin_x,origin_y,ToWinL(160),ToWinH(80));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// ---- Tracer les TAGs sur les palettes du menu Palette ou du menu Shade ----
 | 
						|
void Tag_color_range(byte start,byte end)
 | 
						|
{
 | 
						|
  word origin_x;
 | 
						|
  word origin_y;
 | 
						|
  //word x_pos;
 | 
						|
  word y_pos;
 | 
						|
  //word window_x_pos;
 | 
						|
  word window_y_pos;
 | 
						|
  word index;
 | 
						|
 | 
						|
  // On efface les anciens TAGs
 | 
						|
  for (index=0;index<=start;index++)
 | 
						|
    Block(Window_pos_X+(Window_palette_button_list->Pos_X+3+((index>>4)*10))*Menu_factor_X,
 | 
						|
          Window_pos_Y+(Window_palette_button_list->Pos_Y+3+((index&15)* 5))*Menu_factor_Y,
 | 
						|
          Menu_factor_X*3,Menu_factor_Y*5,MC_Light);
 | 
						|
 | 
						|
  for (index=end;index<256;index++)
 | 
						|
    Block(Window_pos_X+(Window_palette_button_list->Pos_X+3+((index>>4)*10))*Menu_factor_X,
 | 
						|
          Window_pos_Y+(Window_palette_button_list->Pos_Y+3+((index&15)* 5))*Menu_factor_Y,
 | 
						|
          Menu_factor_X*3,Menu_factor_Y*5,MC_Light);
 | 
						|
 | 
						|
  // On affiche le 1er TAG
 | 
						|
  origin_x=(Window_palette_button_list->Pos_X+3)+(start>>4)*10;
 | 
						|
  origin_y=(Window_palette_button_list->Pos_Y+3)+(start&15)* 5;
 | 
						|
  for (y_pos=0,window_y_pos=origin_y  ;y_pos<5;y_pos++,window_y_pos++)
 | 
						|
    Pixel_in_window(origin_x  ,window_y_pos,MC_Black);
 | 
						|
  for (y_pos=0,window_y_pos=origin_y+1;y_pos<3;y_pos++,window_y_pos++)
 | 
						|
    Pixel_in_window(origin_x+1,window_y_pos,MC_Black);
 | 
						|
  Pixel_in_window(origin_x+2,origin_y+2,MC_Black);
 | 
						|
 | 
						|
  if (start!=end)
 | 
						|
  {
 | 
						|
    // On complète le 1er TAG
 | 
						|
    Pixel_in_window(origin_x+1,origin_y+4,MC_Black);
 | 
						|
 | 
						|
    // On affiche le 2ème TAG
 | 
						|
    origin_x=(Window_palette_button_list->Pos_X+3)+(end>>4)*10;
 | 
						|
    origin_y=(Window_palette_button_list->Pos_Y+3)+(end&15)* 5;
 | 
						|
    for (y_pos=0,window_y_pos=origin_y; y_pos<5; y_pos++,window_y_pos++)
 | 
						|
      Pixel_in_window(origin_x  ,window_y_pos,MC_Black);
 | 
						|
    for (y_pos=0,window_y_pos=origin_y; y_pos<4; y_pos++,window_y_pos++)
 | 
						|
      Pixel_in_window(origin_x+1,window_y_pos,MC_Black);
 | 
						|
    Pixel_in_window(origin_x+2,origin_y+2,MC_Black);
 | 
						|
 | 
						|
    // On TAG toutes les couleurs intermédiaires
 | 
						|
    for (index=start+1;index<end;index++)
 | 
						|
    {
 | 
						|
      Block(Window_pos_X+(Window_palette_button_list->Pos_X+3+((index>>4)*10))*Menu_factor_X,
 | 
						|
            Window_pos_Y+(Window_palette_button_list->Pos_Y+3+((index&15)* 5))*Menu_factor_Y,
 | 
						|
            Menu_factor_X*2,Menu_factor_Y*5,MC_Black);
 | 
						|
      // On efface l'éventuelle pointe d'une ancienne extrémité de l'intervalle
 | 
						|
      Pixel_in_window(Window_palette_button_list->Pos_X+5+((index>>4)*10),
 | 
						|
                         Window_palette_button_list->Pos_Y+5+((index&15)* 5),
 | 
						|
                         MC_Light);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  Update_rect(ToWinX(Window_palette_button_list->Pos_X+3),ToWinY(Window_palette_button_list->Pos_Y+3),ToWinL(12*16),ToWinH(5*16));
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//------------------ Dessiner un scroller dans une fenêtre -------------------
 | 
						|
 | 
						|
void Compute_slider_cursor_height(T_Scroller_button * button)
 | 
						|
{
 | 
						|
  if (button->Nb_elements>button->Nb_visibles)
 | 
						|
  {
 | 
						|
    button->Cursor_height=(button->Nb_visibles*(button->Height-24))/button->Nb_elements;
 | 
						|
    if (!(button->Cursor_height))
 | 
						|
      button->Cursor_height=1;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    button->Cursor_height=button->Height-24;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void Window_draw_slider(T_Scroller_button * button)
 | 
						|
{
 | 
						|
  word slider_position;
 | 
						|
 | 
						|
  slider_position=button->Pos_Y+12;
 | 
						|
 | 
						|
  Block(Window_pos_X+(button->Pos_X*Menu_factor_X),
 | 
						|
        Window_pos_Y+(slider_position*Menu_factor_Y),
 | 
						|
        11*Menu_factor_X,(button->Height-24)*Menu_factor_Y,MC_Black/*MC_Dark*/);
 | 
						|
 | 
						|
  if (button->Nb_elements>button->Nb_visibles)
 | 
						|
    slider_position+=Round_div(button->Position*(button->Height-24-button->Cursor_height),button->Nb_elements-button->Nb_visibles);
 | 
						|
 | 
						|
  Block(Window_pos_X+(button->Pos_X*Menu_factor_X),
 | 
						|
        Window_pos_Y+(slider_position*Menu_factor_Y),
 | 
						|
        11*Menu_factor_X,button->Cursor_height*Menu_factor_Y,MC_Dark/*MC_White*/);
 | 
						|
 | 
						|
  Update_rect(Window_pos_X+(button->Pos_X*Menu_factor_X),
 | 
						|
        Window_pos_Y+button->Pos_Y*Menu_factor_Y,
 | 
						|
        11*Menu_factor_X,(button->Height)*Menu_factor_Y);
 | 
						|
}
 | 
						|
 | 
						|
void Window_draw_scroller_bouton(T_Scroller_button * button)
 | 
						|
{
 | 
						|
  Window_display_frame_generic(button->Pos_X-1,button->Pos_Y-1,13,button->Height+2,MC_Black,MC_Black,MC_Dark,MC_Dark,MC_Dark);
 | 
						|
  Window_display_frame_mono(button->Pos_X-1,button->Pos_Y+11,13,button->Height-22,MC_Black);
 | 
						|
  Window_display_frame_out(button->Pos_X,button->Pos_Y,11,11);
 | 
						|
  Window_display_frame_out(button->Pos_X,button->Pos_Y+button->Height-11,11,11);
 | 
						|
  Print_in_window(button->Pos_X+2,button->Pos_Y+2,"\030",MC_Black,MC_Light);
 | 
						|
  Print_in_window(button->Pos_X+2,button->Pos_Y+button->Height-9,"\031",MC_Black,MC_Light);
 | 
						|
  Window_draw_slider(button);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//--------------- Dessiner une zone de saisie dans une fenêtre ---------------
 | 
						|
 | 
						|
void Window_draw_input_bouton(word x_pos,word y_pos,word width_in_characters)
 | 
						|
{
 | 
						|
  Window_display_frame_in(x_pos,y_pos,(width_in_characters<<3)+3,11);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//------------ Modifier le contenu (caption) d'une zone de saisie ------------
 | 
						|
 | 
						|
void Window_input_content(T_Special_button * button, char * content)
 | 
						|
{
 | 
						|
  Print_in_window_limited(button->Pos_X+2,button->Pos_Y+2,content,button->Width/8,MC_Black,MC_Light);
 | 
						|
}
 | 
						|
 | 
						|
//------------ Effacer le contenu (caption) d'une zone de saisie ------------
 | 
						|
 | 
						|
void Window_clear_input_button(T_Special_button * button)
 | 
						|
{
 | 
						|
  Block((button->Pos_X+2)*Menu_factor_X+Window_pos_X,(button->Pos_Y+2)*Menu_factor_Y+Window_pos_Y,(button->Width/8)*8*Menu_factor_X,8*Menu_factor_Y,MC_Light);
 | 
						|
  Update_rect((button->Pos_X+2)*Menu_factor_X+Window_pos_X,(button->Pos_Y+2)*Menu_factor_Y+Window_pos_Y,button->Width/8*8*Menu_factor_X,8*Menu_factor_Y);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//------ Rajout d'un bouton à la liste de ceux présents dans la fenêtre ------
 | 
						|
 | 
						|
T_Normal_button * Window_set_normal_button(word x_pos, word y_pos,
 | 
						|
                                   word width, word height,
 | 
						|
                                   char * title, byte undersc_letter,
 | 
						|
                                   byte clickable, word shortcut)
 | 
						|
{
 | 
						|
  T_Normal_button * temp=NULL;
 | 
						|
 | 
						|
  Window_nb_buttons++;
 | 
						|
 | 
						|
  if (clickable)
 | 
						|
  {
 | 
						|
    temp=(T_Normal_button *)malloc(sizeof(T_Normal_button));
 | 
						|
    temp->Number   =Window_nb_buttons;
 | 
						|
    temp->Pos_X    =x_pos;
 | 
						|
    temp->Pos_Y    =y_pos;
 | 
						|
    temp->Width  =width;
 | 
						|
    temp->Height  =height;
 | 
						|
    temp->Shortcut=shortcut;
 | 
						|
    temp->Repeatable=0;
 | 
						|
 | 
						|
    temp->Next=Window_normal_button_list;
 | 
						|
    Window_normal_button_list=temp;
 | 
						|
  }
 | 
						|
 | 
						|
  Window_draw_normal_bouton(x_pos,y_pos,width,height,title,undersc_letter,clickable);
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
//------ Rajout d'un bouton à la liste de ceux présents dans la fenêtre ------
 | 
						|
 | 
						|
T_Normal_button * Window_set_repeatable_button(word x_pos, word y_pos,
 | 
						|
                                   word width, word height,
 | 
						|
                                   char * title, byte undersc_letter,
 | 
						|
                                   byte clickable, word shortcut)
 | 
						|
{
 | 
						|
  T_Normal_button * temp=NULL;
 | 
						|
 | 
						|
  Window_nb_buttons++;
 | 
						|
 | 
						|
  if (clickable)
 | 
						|
  {
 | 
						|
    temp=(T_Normal_button *)malloc(sizeof(T_Normal_button));
 | 
						|
    temp->Number   =Window_nb_buttons;
 | 
						|
    temp->Pos_X    =x_pos;
 | 
						|
    temp->Pos_Y    =y_pos;
 | 
						|
    temp->Width  =width;
 | 
						|
    temp->Height  =height;
 | 
						|
    temp->Shortcut=shortcut;
 | 
						|
    temp->Repeatable=1;
 | 
						|
 | 
						|
    temp->Next=Window_normal_button_list;
 | 
						|
    Window_normal_button_list=temp;
 | 
						|
  }
 | 
						|
 | 
						|
  Window_draw_normal_bouton(x_pos,y_pos,width,height,title,undersc_letter,clickable);
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
T_Palette_button * Window_set_palette_button(word x_pos, word y_pos)
 | 
						|
{
 | 
						|
  T_Palette_button * temp;
 | 
						|
 | 
						|
  temp=(T_Palette_button *)malloc(sizeof(T_Palette_button));
 | 
						|
  temp->Number   =++Window_nb_buttons;
 | 
						|
  temp->Pos_X    =x_pos;
 | 
						|
  temp->Pos_Y    =y_pos;
 | 
						|
 | 
						|
  temp->Next=Window_palette_button_list;
 | 
						|
  Window_palette_button_list=temp;
 | 
						|
 | 
						|
  Window_draw_palette_bouton(x_pos,y_pos);
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
T_Scroller_button * Window_set_scroller_button(word x_pos, word y_pos,
 | 
						|
                                     word height,
 | 
						|
                                     word nb_elements,
 | 
						|
                                     word nb_elements_visible,
 | 
						|
                                     word initial_position)
 | 
						|
{
 | 
						|
  T_Scroller_button * temp;
 | 
						|
 | 
						|
  temp=(T_Scroller_button *)malloc(sizeof(T_Scroller_button));
 | 
						|
  temp->Number        =++Window_nb_buttons;
 | 
						|
  temp->Pos_X         =x_pos;
 | 
						|
  temp->Pos_Y         =y_pos;
 | 
						|
  temp->Height       =height;
 | 
						|
  temp->Nb_elements   =nb_elements;
 | 
						|
  temp->Nb_visibles   =nb_elements_visible;
 | 
						|
  temp->Position      =initial_position;
 | 
						|
  Compute_slider_cursor_height(temp);
 | 
						|
 | 
						|
  temp->Next=Window_scroller_button_list;
 | 
						|
  Window_scroller_button_list=temp;
 | 
						|
 | 
						|
  Window_draw_scroller_bouton(temp);
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
T_Special_button * Window_set_special_button(word x_pos,word y_pos,word width,word height)
 | 
						|
{
 | 
						|
  T_Special_button * temp;
 | 
						|
 | 
						|
  temp=(T_Special_button *)malloc(sizeof(T_Special_button));
 | 
						|
  temp->Number   =++Window_nb_buttons;
 | 
						|
  temp->Pos_X    =x_pos;
 | 
						|
  temp->Pos_Y    =y_pos;
 | 
						|
  temp->Width  =width;
 | 
						|
  temp->Height  =height;
 | 
						|
 | 
						|
  temp->Next=Window_special_button_list;
 | 
						|
  Window_special_button_list=temp;
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
T_Special_button * Window_set_input_button(word x_pos,word y_pos,word width_in_characters)
 | 
						|
{
 | 
						|
  T_Special_button *temp;
 | 
						|
  temp=Window_set_special_button(x_pos,y_pos,(width_in_characters<<3)+3,11);
 | 
						|
  Window_draw_input_bouton(x_pos,y_pos,width_in_characters);
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
T_Dropdown_button * Window_set_dropdown_button(word x_pos,word y_pos,word width,word height,word dropdown_width,const char *label,byte display_choice,byte display_centered,byte display_arrow,byte active_button)
 | 
						|
{
 | 
						|
  T_Dropdown_button *temp;
 | 
						|
  
 | 
						|
  temp=(T_Dropdown_button *)malloc(sizeof(T_Dropdown_button));
 | 
						|
  temp->Number       =++Window_nb_buttons;
 | 
						|
  temp->Pos_X        =x_pos;
 | 
						|
  temp->Pos_Y        =y_pos;
 | 
						|
  temp->Width      =width;
 | 
						|
  temp->Height      =height;
 | 
						|
  temp->Display_choice =display_choice;
 | 
						|
  temp->First_item=NULL;
 | 
						|
  temp->Dropdown_width=dropdown_width?dropdown_width:width;
 | 
						|
  temp->Display_centered=display_centered;
 | 
						|
  temp->Display_arrow=display_arrow;
 | 
						|
  temp->Active_button=active_button;
 | 
						|
 | 
						|
  temp->Next=Window_dropdown_button_list;
 | 
						|
  Window_dropdown_button_list=temp;
 | 
						|
  Window_draw_normal_bouton(x_pos,y_pos,width,height,"",-1,1);
 | 
						|
  if (label && label[0])
 | 
						|
    Print_in_window(temp->Pos_X+2,temp->Pos_Y+(temp->Height-7)/2,label,MC_Black,MC_Light);
 | 
						|
  if (display_arrow)
 | 
						|
    Window_display_icon_sprite(temp->Pos_X+temp->Width-10,temp->Pos_Y+(temp->Height-7)/2,6);
 | 
						|
  
 | 
						|
  return temp;
 | 
						|
}
 | 
						|
 | 
						|
// Ajoute un choix à une dropdown. Le libellé est seulement référencé,
 | 
						|
// il doit pointer sur une zone qui doit être encore valide à la fermeture 
 | 
						|
// de la fenêtre (comprise).
 | 
						|
void Window_dropdown_add_item(T_Dropdown_button * dropdown, word btn_number, const char *label)
 | 
						|
{
 | 
						|
  T_Dropdown_choice *temp;
 | 
						|
  T_Dropdown_choice *last;
 | 
						|
  
 | 
						|
  temp=(T_Dropdown_choice *)malloc(sizeof(T_Dropdown_choice));
 | 
						|
  temp->Number =btn_number;
 | 
						|
  temp->Label=label;
 | 
						|
  temp->Next=NULL;
 | 
						|
 | 
						|
  last=dropdown->First_item;
 | 
						|
  if (last)
 | 
						|
  {
 | 
						|
    // On cherche le dernier élément
 | 
						|
    for (;last->Next;last=last->Next)
 | 
						|
      ;
 | 
						|
    last->Next=temp;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    dropdown->First_item=temp;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// ------------- Suppression de tous les choix d'une dropdown ---------
 | 
						|
void Window_dropdown_clear_items(T_Dropdown_button * dropdown)
 | 
						|
{
 | 
						|
  T_Dropdown_choice * next_choice;
 | 
						|
    while (dropdown->First_item)
 | 
						|
    {
 | 
						|
      next_choice=dropdown->First_item->Next;
 | 
						|
      free(dropdown->First_item);
 | 
						|
      dropdown->First_item=next_choice;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//----------------------- Ouverture d'un pop-up -----------------------
 | 
						|
 | 
						|
void Open_popup(word x_pos, word y_pos, word width,word height)
 | 
						|
// Lors de l'appel à cette procédure, la souris doit être affichée.
 | 
						|
// En sortie de cette procedure, la souris est effacée.
 | 
						|
 | 
						|
// Note : les pop-ups sont gérés comme s'ils étaient des sous-fenêtres, ils ont donc leur propre boucle d'évènements et tout, on peut ajouter des widgets dedans, ...
 | 
						|
// Les différences sont surtout graphiques :
 | 
						|
    // -Possibilité de préciser la position XY
 | 
						|
    // -Pas de titre
 | 
						|
    // -Pas de cadre en relief mais seulement un plat, et il est blanc au lieu de noir.
 | 
						|
{
 | 
						|
  Windows_open++;
 | 
						|
 | 
						|
  Window_width=width;
 | 
						|
  Window_height=height;
 | 
						|
  Window_pos_X=x_pos;
 | 
						|
  Window_pos_Y=y_pos;
 | 
						|
 | 
						|
  // Sauvegarde de ce que la fenêtre remplace
 | 
						|
  Save_background(&(Window_background[Windows_open-1]), Window_pos_X, Window_pos_Y, width, height);
 | 
						|
 | 
						|
/*
 | 
						|
  // Fenêtre grise
 | 
						|
  Block(Window_pos_X+1*Menu_factor_X,
 | 
						|
        Window_pos_Y+1*Menu_factor_Y,
 | 
						|
        (width-2)*Menu_factor_X,(height-2)*Menu_factor_Y,MC_Light);
 | 
						|
 | 
						|
  // Frame noir puis en relief
 | 
						|
  Window_display_frame_mono(0,0,width,height,MC_White);
 | 
						|
*/
 | 
						|
  if (Windows_open == 1)
 | 
						|
  {
 | 
						|
    Menu_is_visible_before_window=Menu_is_visible;
 | 
						|
    Menu_is_visible=0;
 | 
						|
    Menu_Y_before_window=Menu_Y;
 | 
						|
    Menu_Y=Screen_height;
 | 
						|
    Cursor_shape_before_window=Cursor_shape;
 | 
						|
    Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
    Paintbrush_hidden_before_window=Paintbrush_hidden;
 | 
						|
    Paintbrush_hidden=1;
 | 
						|
  }
 | 
						|
 | 
						|
  // Initialisation des listes de boutons de la fenêtre
 | 
						|
  Window_normal_button_list  =NULL;
 | 
						|
  Window_palette_button_list =NULL;
 | 
						|
  Window_scroller_button_list=NULL;
 | 
						|
  Window_special_button_list =NULL;
 | 
						|
  Window_dropdown_button_list =NULL;
 | 
						|
  Window_nb_buttons            =0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
//----------------------- Fermer une fenêtre d'options -----------------------
 | 
						|
 | 
						|
void Close_popup(void)
 | 
						|
// Lors de l'appel à cette procedure, la souris doit être affichée.
 | 
						|
// En sortie de cette procedure, la souris est effacée.
 | 
						|
{
 | 
						|
  T_Normal_button   * temp1;
 | 
						|
  T_Palette_button  * temp2;
 | 
						|
  T_Scroller_button * temp3;
 | 
						|
  T_Special_button  * temp4;
 | 
						|
  T_Dropdown_button  * temp5;
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
 | 
						|
  while (Window_normal_button_list)
 | 
						|
  {
 | 
						|
    temp1=Window_normal_button_list->Next;
 | 
						|
    free(Window_normal_button_list);
 | 
						|
    Window_normal_button_list=temp1;
 | 
						|
  }
 | 
						|
  while (Window_palette_button_list)
 | 
						|
  {
 | 
						|
    temp2=Window_palette_button_list->Next;
 | 
						|
    free(Window_palette_button_list);
 | 
						|
    Window_palette_button_list=temp2;
 | 
						|
  }
 | 
						|
  while (Window_scroller_button_list)
 | 
						|
  {
 | 
						|
    temp3=Window_scroller_button_list->Next;
 | 
						|
    free(Window_scroller_button_list);
 | 
						|
    Window_scroller_button_list=temp3;
 | 
						|
  }
 | 
						|
  while (Window_special_button_list)
 | 
						|
  {
 | 
						|
    temp4=Window_special_button_list->Next;
 | 
						|
    free(Window_special_button_list);
 | 
						|
    Window_special_button_list=temp4;
 | 
						|
  }
 | 
						|
  while (Window_dropdown_button_list)
 | 
						|
  {
 | 
						|
    Window_dropdown_clear_items(Window_dropdown_button_list);
 | 
						|
    temp5=Window_dropdown_button_list->Next;
 | 
						|
    free(Window_dropdown_button_list);
 | 
						|
    Window_dropdown_button_list=temp5;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Windows_open != 1)
 | 
						|
  {
 | 
						|
    // Restore de ce que la fenêtre cachait
 | 
						|
    Restore_background(Window_background[Windows_open-1], Window_pos_X, Window_pos_Y, Window_width, Window_height);
 | 
						|
    Window_background[Windows_open-1]=NULL;
 | 
						|
    Update_rect(Window_pos_X,Window_pos_Y,Window_width*Menu_factor_X,Window_height*Menu_factor_Y);
 | 
						|
    Windows_open--;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    free(Window_background[Windows_open-1]);
 | 
						|
    Windows_open--;
 | 
						|
  
 | 
						|
    Paintbrush_hidden=Paintbrush_hidden_before_window;
 | 
						|
  
 | 
						|
    Compute_paintbrush_coordinates();
 | 
						|
  
 | 
						|
    Menu_Y=Menu_Y_before_window;
 | 
						|
    Menu_is_visible=Menu_is_visible_before_window;
 | 
						|
    Cursor_shape=Cursor_shape_before_window;
 | 
						|
    
 | 
						|
    Display_all_screen();
 | 
						|
    Display_menu();
 | 
						|
  }
 | 
						|
 | 
						|
  Key=0;
 | 
						|
  Mouse_K=0;
 | 
						|
  
 | 
						|
  Old_MX = -1;
 | 
						|
  Old_MY = -1;
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
//////////////////////////////////////////////////////////////////////////////
 | 
						|
//                                                                          //
 | 
						|
//       Mini-MOTEUR utilisé dans les fenêtres (menus des boutons...)       //
 | 
						|
//                                                                          //
 | 
						|
//////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
 | 
						|
// -- Indique si on a cliqué dans une zone définie par deux points extremes --
 | 
						|
byte Window_click_in_rectangle(short start_x,short start_y,short end_x,short end_y)
 | 
						|
{
 | 
						|
  short x_pos,y_pos;
 | 
						|
 | 
						|
  x_pos=((short)Mouse_X-Window_pos_X)/Menu_factor_X;
 | 
						|
  y_pos=((short)Mouse_Y-Window_pos_Y)/Menu_factor_Y;
 | 
						|
 | 
						|
  return ((x_pos>=start_x) &&
 | 
						|
          (y_pos>=start_y) &&
 | 
						|
          (x_pos<=end_x)   &&
 | 
						|
          (y_pos<=end_y));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// --- Attend que l'on clique dans la palette pour renvoyer la couleur choisie
 | 
						|
// ou bien renvoie -1 si on a annulé l'action pas click-droit ou Escape ------
 | 
						|
short Wait_click_in_palette(T_Palette_button * button)
 | 
						|
{
 | 
						|
  short start_x=button->Pos_X+5;
 | 
						|
  short start_y=button->Pos_Y+3;
 | 
						|
  short end_x  =button->Pos_X+160;
 | 
						|
  short end_y  =button->Pos_Y+82;
 | 
						|
  byte  selected_color;
 | 
						|
  byte  old_hide_cursor;
 | 
						|
  byte  old_main_magnifier_mode;
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
  old_hide_cursor=Cursor_hidden;
 | 
						|
  old_main_magnifier_mode=Main_magnifier_mode;
 | 
						|
  Main_magnifier_mode=0;
 | 
						|
  Cursor_hidden=0;
 | 
						|
  Cursor_shape=CURSOR_SHAPE_TARGET;
 | 
						|
  Display_cursor();
 | 
						|
 | 
						|
  for (;;)
 | 
						|
  {
 | 
						|
    while(!Get_input())Wait_VBL();
 | 
						|
 | 
						|
    if (Mouse_K==LEFT_SIDE)
 | 
						|
    {
 | 
						|
      if (Window_click_in_rectangle(start_x,start_y,end_x,end_y))
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        selected_color=(((Mouse_X-Window_pos_X)/Menu_factor_X)-(button->Pos_X+2)) / 10 * 16 +
 | 
						|
        (((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-(button->Pos_Y+3)) / 5;
 | 
						|
        Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
        Cursor_hidden=old_hide_cursor;
 | 
						|
        Main_magnifier_mode=old_main_magnifier_mode;
 | 
						|
        Display_cursor();
 | 
						|
        return selected_color;
 | 
						|
      }
 | 
						|
      if ((Mouse_X<Window_pos_X) || (Mouse_Y<Window_pos_Y) ||
 | 
						|
          (Mouse_X>=Window_pos_X+(Window_width*Menu_factor_X)) ||
 | 
						|
          (Mouse_Y>=Window_pos_Y+(Window_height*Menu_factor_Y)) )
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        selected_color=Read_pixel(Mouse_X,Mouse_Y);
 | 
						|
        Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
        Cursor_hidden=old_hide_cursor;
 | 
						|
        Main_magnifier_mode=old_main_magnifier_mode;
 | 
						|
        Display_cursor();
 | 
						|
        return selected_color;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((Mouse_K==RIGHT_SIDE) || (Key==KEY_ESC))
 | 
						|
    {
 | 
						|
      Hide_cursor();
 | 
						|
      Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
      Cursor_hidden=old_hide_cursor;
 | 
						|
      Main_magnifier_mode=old_main_magnifier_mode;
 | 
						|
      Display_cursor();
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// -------------- Récupération d'une couleur derrière un menu ----------------
 | 
						|
void Get_color_behind_window(byte * color, byte * click)
 | 
						|
{
 | 
						|
  short width=Window_width*Menu_factor_X;
 | 
						|
  short height=Window_height*Menu_factor_Y;
 | 
						|
  short old_x=-1;
 | 
						|
  short old_y=-1;
 | 
						|
  short index;
 | 
						|
  short a,b,c,d; // Variables temporaires et multitâches...
 | 
						|
  byte * buffer;
 | 
						|
  char str[25];
 | 
						|
  byte cursor_was_hidden;
 | 
						|
 | 
						|
 | 
						|
  if ((buffer=(byte *) malloc(width*height)))
 | 
						|
  {
 | 
						|
    Hide_cursor();
 | 
						|
 | 
						|
    cursor_was_hidden=Cursor_hidden;
 | 
						|
    Cursor_hidden=0;
 | 
						|
 | 
						|
    for (index=0; index<height; index++)
 | 
						|
      Read_line(Window_pos_X,Window_pos_Y+index,width,buffer+((int)index*width*Pixel_width));
 | 
						|
    a=Menu_Y;
 | 
						|
    Menu_Y=Menu_Y_before_window;
 | 
						|
    b=Menu_is_visible;
 | 
						|
    Menu_is_visible=Menu_is_visible_before_window;
 | 
						|
    Display_all_screen();
 | 
						|
    Display_menu();
 | 
						|
    Menu_Y=a;
 | 
						|
    Menu_is_visible=b;
 | 
						|
 | 
						|
    Cursor_shape=CURSOR_SHAPE_COLORPICKER;
 | 
						|
    b=Paintbrush_hidden;
 | 
						|
    Paintbrush_hidden=1;
 | 
						|
    c=-1; // color pointée: au début aucune, comme ça on initialise tout
 | 
						|
    if (Menu_is_visible_before_window)
 | 
						|
      Print_in_menu(Menu_tooltip[BUTTON_CHOOSE_COL],0);
 | 
						|
 | 
						|
    Display_cursor();
 | 
						|
 | 
						|
    do
 | 
						|
    {
 | 
						|
      if(!Get_input())Wait_VBL();
 | 
						|
 | 
						|
      if ((Mouse_X!=old_x) || (Mouse_Y!=old_y))
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        a=Read_pixel(Mouse_X,Mouse_Y);
 | 
						|
        if (a!=c)
 | 
						|
        {
 | 
						|
          c=a; // Mise à jour de la couleur pointée
 | 
						|
          if (Menu_is_visible_before_window)
 | 
						|
          {
 | 
						|
            sprintf(str,"%d",a);
 | 
						|
            d=strlen(str);
 | 
						|
            strcat(str,"   (");
 | 
						|
            sprintf(str+strlen(str),"%d",Main_palette[a].R);
 | 
						|
            strcat(str,",");
 | 
						|
            sprintf(str+strlen(str),"%d",Main_palette[a].G);
 | 
						|
            strcat(str,",");
 | 
						|
            sprintf(str+strlen(str),"%d",Main_palette[a].B);
 | 
						|
            strcat(str,")");
 | 
						|
            a=24-d;
 | 
						|
            for (index=strlen(str); index<a; index++)
 | 
						|
              str[index]=' ';
 | 
						|
            str[a]=0;
 | 
						|
            Print_in_menu(str,strlen(Menu_tooltip[BUTTON_CHOOSE_COL]));
 | 
						|
 | 
						|
            Print_general((26+((d+strlen(Menu_tooltip[BUTTON_CHOOSE_COL]))<<3))*Menu_factor_X,
 | 
						|
                          Menu_status_Y," ",0,c);
 | 
						|
          }
 | 
						|
        }
 | 
						|
        Display_cursor();
 | 
						|
      }
 | 
						|
 | 
						|
      old_x=Mouse_X;
 | 
						|
      old_y=Mouse_Y;
 | 
						|
    } while (!(Mouse_K || (Key==KEY_ESC)));
 | 
						|
 | 
						|
    if (Mouse_K)
 | 
						|
    {
 | 
						|
      Hide_cursor();
 | 
						|
      *click=Mouse_K;
 | 
						|
      *color=Read_pixel(Mouse_X,Mouse_Y);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      *click=0;
 | 
						|
      Hide_cursor();
 | 
						|
    }
 | 
						|
 | 
						|
    for (index=0; index<height; index++)
 | 
						|
      Display_line(Window_pos_X,Window_pos_Y+index,width,buffer+((int)index*width));
 | 
						|
    Update_rect(Window_pos_X, Window_pos_Y, Window_width*Menu_factor_X, Window_height*Menu_factor_Y);
 | 
						|
    Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
    Paintbrush_hidden=b;
 | 
						|
    Cursor_hidden=cursor_was_hidden;
 | 
						|
    Display_cursor();
 | 
						|
 | 
						|
    free(buffer);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    Error(0);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// ------------ Opération de déplacement de la fenêtre à l'écran -------------
 | 
						|
void Move_window(short dx, short dy)
 | 
						|
{
 | 
						|
  short new_x=Mouse_X-dx;
 | 
						|
  short new_y=Mouse_Y-dy;
 | 
						|
  short old_x;
 | 
						|
  short old_y;
 | 
						|
  short width=Window_width*Menu_factor_X;
 | 
						|
  short height=Window_height*Menu_factor_Y;
 | 
						|
  short a;
 | 
						|
  byte  b;
 | 
						|
  byte  *buffer=NULL;
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
 | 
						|
  Horizontal_XOR_line(new_x,new_y,width);
 | 
						|
  Vertical_XOR_line(new_x,new_y+1,height-2);
 | 
						|
  Vertical_XOR_line(new_x+width-1,new_y+1,height-2);
 | 
						|
  Horizontal_XOR_line(new_x,new_y+height-1,width);
 | 
						|
  Update_rect(new_x,new_y,width,height);
 | 
						|
  Cursor_shape=CURSOR_SHAPE_MULTIDIRECTIONNAL;
 | 
						|
  Display_cursor();
 | 
						|
 | 
						|
  while (Mouse_K)
 | 
						|
  {
 | 
						|
    old_x=new_x;
 | 
						|
    old_y=new_y;
 | 
						|
 | 
						|
    while(!Get_input() && new_x==Mouse_X-dx && new_y==Mouse_Y-dy) Wait_VBL();
 | 
						|
 | 
						|
    new_x=Mouse_X-dx;
 | 
						|
 | 
						|
    if (new_x<0)
 | 
						|
    {
 | 
						|
      new_x=0;
 | 
						|
      dx = Mouse_X;
 | 
						|
    }
 | 
						|
    if (new_x>Screen_width-width)
 | 
						|
    {
 | 
						|
      new_x=Screen_width-width;
 | 
						|
      dx = Mouse_X - new_x;
 | 
						|
    }
 | 
						|
 | 
						|
    new_y=Mouse_Y-dy;
 | 
						|
 | 
						|
    if (new_y<0)
 | 
						|
    {
 | 
						|
      new_y=0;
 | 
						|
      dy = Mouse_Y;
 | 
						|
    }
 | 
						|
    if (new_y>Screen_height-height)
 | 
						|
    {
 | 
						|
      new_y=Screen_height-height;
 | 
						|
      dy = Mouse_Y - new_y;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((new_x!=old_x) || (new_y!=old_y))
 | 
						|
    {
 | 
						|
      Hide_cursor();
 | 
						|
 | 
						|
      Horizontal_XOR_line(old_x,old_y,width);
 | 
						|
      Vertical_XOR_line(old_x,old_y+1,height-2);
 | 
						|
      Vertical_XOR_line(old_x+width-1,old_y+1,height-2);
 | 
						|
      Horizontal_XOR_line(old_x,old_y+height-1,width);
 | 
						|
 | 
						|
      Horizontal_XOR_line(new_x,new_y,width);
 | 
						|
      Vertical_XOR_line(new_x,new_y+1,height-2);
 | 
						|
      Vertical_XOR_line(new_x+width-1,new_y+1,height-2);
 | 
						|
      Horizontal_XOR_line(new_x,new_y+height-1,width);
 | 
						|
 | 
						|
      Display_cursor();
 | 
						|
      Update_rect(old_x,old_y,width,height);
 | 
						|
      Update_rect(new_x,new_y,width,height);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Hide_cursor();
 | 
						|
  Horizontal_XOR_line(new_x,new_y,width);
 | 
						|
  Vertical_XOR_line(new_x,new_y+1,height-2);
 | 
						|
  Vertical_XOR_line(new_x+width-1,new_y+1,height-2);
 | 
						|
  Horizontal_XOR_line(new_x,new_y+height-1,width);
 | 
						|
 | 
						|
  if ((new_x!=Window_pos_X)
 | 
						|
   || (new_y!=Window_pos_Y))
 | 
						|
  {
 | 
						|
    a=Menu_Y;
 | 
						|
    Menu_Y=Menu_Y_before_window;
 | 
						|
    b=Menu_is_visible;
 | 
						|
    Menu_is_visible=Menu_is_visible_before_window;
 | 
						|
    //Display_all_screen();
 | 
						|
    //Display_menu();
 | 
						|
    Menu_Y=a;
 | 
						|
    Menu_is_visible=b;
 | 
						|
 | 
						|
    // Sauvegarde du contenu actuel de la fenêtre
 | 
						|
    Save_background(&buffer, Window_pos_X, Window_pos_Y, Window_width, Window_height);
 | 
						|
    
 | 
						|
    // Restore de ce que la fenêtre cachait
 | 
						|
    Restore_background(Window_background[Windows_open-1], Window_pos_X, Window_pos_Y, Window_width, Window_height);
 | 
						|
    Window_background[Windows_open-1] = NULL;
 | 
						|
 | 
						|
    // Sauvegarde de ce que la fenêtre remplace
 | 
						|
    Save_background(&(Window_background[Windows_open-1]), new_x, new_y, Window_width, Window_height);
 | 
						|
 | 
						|
    // Raffichage de la fenêtre
 | 
						|
    Restore_background(buffer, new_x, new_y, Window_width, Window_height);
 | 
						|
    buffer = NULL;
 | 
						|
 | 
						|
    // Mise à jour du rectangle englobant
 | 
						|
    Update_rect(
 | 
						|
      (new_x>Window_pos_X)?Window_pos_X:new_x,
 | 
						|
      (new_y>Window_pos_Y)?Window_pos_Y:new_y,
 | 
						|
      ((new_x>Window_pos_X)?(new_x-Window_pos_X):(Window_pos_X-new_x)) + Window_width*Menu_factor_X,
 | 
						|
      ((new_y>Window_pos_Y)?(new_y-Window_pos_Y):(Window_pos_Y-new_y)) + Window_height*Menu_factor_Y);
 | 
						|
    Window_pos_X=new_x;
 | 
						|
    Window_pos_Y=new_y;
 | 
						|
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    // Update pour effacer le rectangle XOR
 | 
						|
    Update_rect(Window_pos_X, Window_pos_Y, Window_width*Menu_factor_X, Window_height*Menu_factor_Y);
 | 
						|
  }    
 | 
						|
  Cursor_shape=CURSOR_SHAPE_ARROW;
 | 
						|
  Display_cursor();
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// Gestion des dropdown
 | 
						|
short Window_dropdown_on_click(T_Dropdown_button *Button)
 | 
						|
{
 | 
						|
  short nb_choices;
 | 
						|
  short choice_index;
 | 
						|
  short selected_index;
 | 
						|
  short old_selected_index;
 | 
						|
  short box_height;
 | 
						|
  T_Dropdown_choice *item;
 | 
						|
  // Taille de l'ombre portée (en plus des dimensions normales)
 | 
						|
  #define SHADOW_RIGHT 3
 | 
						|
  #define SHADOW_BOTTOM 4
 | 
						|
 | 
						|
  
 | 
						|
  // Comptage des items pour calculer la taille
 | 
						|
  nb_choices=0;
 | 
						|
  for (item=Button->First_item; item!=NULL; item=item->Next)
 | 
						|
  {
 | 
						|
    nb_choices++;
 | 
						|
  }
 | 
						|
  box_height=3+nb_choices*8+1;
 | 
						|
  
 | 
						|
  Hide_cursor();
 | 
						|
  Window_select_normal_button(Button->Pos_X,Button->Pos_Y,Button->Width,Button->Height);
 | 
						|
  Open_popup(
 | 
						|
    Window_pos_X+(Button->Pos_X)*Menu_factor_X,
 | 
						|
    Window_pos_Y+(Button->Pos_Y+Button->Height)*Menu_factor_Y,
 | 
						|
    Button->Dropdown_width+SHADOW_RIGHT,
 | 
						|
    box_height+SHADOW_BOTTOM);
 | 
						|
 | 
						|
  // Dessin de la boite
 | 
						|
 | 
						|
  // Bord gauche
 | 
						|
  Block(Window_pos_X,Window_pos_Y,Menu_factor_X,box_height*Menu_factor_Y,MC_Black);
 | 
						|
  // Frame fonce et blanc
 | 
						|
  Window_display_frame_out(1,0,Button->Dropdown_width-1,box_height);
 | 
						|
  // Ombre portée
 | 
						|
  if (SHADOW_BOTTOM)
 | 
						|
  {
 | 
						|
    Block(Window_pos_X+SHADOW_RIGHT*Menu_factor_X,
 | 
						|
        Window_pos_Y+box_height*Menu_factor_Y,
 | 
						|
        Button->Dropdown_width*Menu_factor_X,
 | 
						|
        SHADOW_BOTTOM*Menu_factor_Y,
 | 
						|
        MC_Black);
 | 
						|
    Block(Window_pos_X,
 | 
						|
        Window_pos_Y+box_height*Menu_factor_Y,
 | 
						|
        SHADOW_RIGHT*Menu_factor_X,
 | 
						|
        Menu_factor_Y,
 | 
						|
        MC_Black);
 | 
						|
  }
 | 
						|
  if (SHADOW_RIGHT)
 | 
						|
  {
 | 
						|
    Block(Window_pos_X+Button->Dropdown_width*Menu_factor_X,
 | 
						|
        Window_pos_Y+SHADOW_BOTTOM*Menu_factor_Y,
 | 
						|
        SHADOW_RIGHT*Menu_factor_X,
 | 
						|
        (box_height-SHADOW_BOTTOM)*Menu_factor_Y,
 | 
						|
        MC_Black);
 | 
						|
    Block(Window_pos_X+Button->Dropdown_width*Menu_factor_X,
 | 
						|
        Window_pos_Y,
 | 
						|
        Menu_factor_X,
 | 
						|
        SHADOW_BOTTOM*Menu_factor_Y,
 | 
						|
        MC_Black);
 | 
						|
  }
 | 
						|
 | 
						|
  selected_index=-1;
 | 
						|
  while (1)
 | 
						|
  {
 | 
						|
    old_selected_index = selected_index;
 | 
						|
    // Fenêtre grise
 | 
						|
    Block(Window_pos_X+2*Menu_factor_X,
 | 
						|
        Window_pos_Y+1*Menu_factor_Y,
 | 
						|
        (Button->Dropdown_width-3)*Menu_factor_X,(box_height-2)*Menu_factor_Y,MC_Light);
 | 
						|
    // Affichage des items
 | 
						|
    for(item=Button->First_item,choice_index=0; item!=NULL; item=item->Next,choice_index++)
 | 
						|
    {
 | 
						|
      byte color_1;
 | 
						|
      byte color_2;
 | 
						|
      if (choice_index==selected_index)
 | 
						|
      {
 | 
						|
        color_1=MC_White;
 | 
						|
        color_2=MC_Dark;
 | 
						|
        Block(Window_pos_X+3*Menu_factor_X,
 | 
						|
        Window_pos_Y+((2+choice_index*8)*Menu_factor_Y),
 | 
						|
        (Button->Dropdown_width-5)*Menu_factor_X,(8)*Menu_factor_Y,MC_Dark);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        color_1=MC_Black;
 | 
						|
        color_2=MC_Light;
 | 
						|
      }
 | 
						|
      Print_in_window(3,2+choice_index*8,item->Label,color_1,color_2);
 | 
						|
    }
 | 
						|
    Update_rect(Window_pos_X,Window_pos_Y,Window_width*Menu_factor_X,Window_height*Menu_factor_Y);
 | 
						|
    Display_cursor();
 | 
						|
 | 
						|
    do 
 | 
						|
    {
 | 
						|
      // Attente
 | 
						|
      if(!Get_input())
 | 
						|
        Wait_VBL();
 | 
						|
      // Mise à jour du survol
 | 
						|
      selected_index=Window_click_in_rectangle(2,2,Button->Dropdown_width-2,box_height-1)?
 | 
						|
        (((Mouse_Y-Window_pos_Y)/Menu_factor_Y-2)>>3) : -1;
 | 
						|
 | 
						|
    } while (Mouse_K && selected_index==old_selected_index);
 | 
						|
    
 | 
						|
    if (!Mouse_K)
 | 
						|
      break;
 | 
						|
    Hide_cursor();
 | 
						|
  }
 | 
						|
 | 
						|
  Close_popup();  
 | 
						|
 | 
						|
 | 
						|
  Window_unselect_normal_button(Button->Pos_X,Button->Pos_Y,Button->Width,Button->Height);
 | 
						|
  Display_cursor();
 | 
						|
 | 
						|
  if (selected_index>=0 && selected_index<nb_choices)
 | 
						|
  {
 | 
						|
    for(item=Button->First_item; selected_index; item=item->Next,selected_index--)
 | 
						|
      ;
 | 
						|
    Window_attribute2=item->Number;
 | 
						|
    if (Button->Display_choice)
 | 
						|
    {
 | 
						|
      // Mettre à jour automatiquement le libellé de la dropdown
 | 
						|
      Print_in_window(Button->Pos_X+2,Button->Pos_Y+(Button->Height-7)/2,item->Label,MC_Black,MC_Light);
 | 
						|
    }
 | 
						|
    return Button->Number;
 | 
						|
  }
 | 
						|
  Window_attribute2=-1;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
// --- Fonction de clic sur un bouton a peu près ordinaire:
 | 
						|
// Attend que l'on relache le bouton, et renvoie le numero du bouton si on
 | 
						|
// est resté dessus, 0 si on a annulé en sortant du bouton.
 | 
						|
short Window_normal_button_onclick(word x_pos, word y_pos, word width, word height, short btn_number)
 | 
						|
{
 | 
						|
  while(1)
 | 
						|
  {
 | 
						|
    Hide_cursor();
 | 
						|
    Window_select_normal_button(x_pos,y_pos,width,height);
 | 
						|
    Display_cursor();
 | 
						|
    while (Window_click_in_rectangle(x_pos,y_pos,x_pos+width-1,y_pos+height-1))
 | 
						|
    {
 | 
						|
      if(!Get_input())
 | 
						|
        Wait_VBL();
 | 
						|
      if (!Mouse_K)
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        Window_unselect_normal_button(x_pos,y_pos,width,height);
 | 
						|
        Display_cursor();
 | 
						|
        return btn_number;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    Hide_cursor();
 | 
						|
    Window_unselect_normal_button(x_pos,y_pos,width,height);
 | 
						|
    Display_cursor();
 | 
						|
    while (!(Window_click_in_rectangle(x_pos,y_pos,x_pos+width-1,y_pos+height-1)))
 | 
						|
    {
 | 
						|
      if(!Get_input())
 | 
						|
        Wait_VBL();
 | 
						|
      if (!Mouse_K)
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// --- Renvoie le numéro du bouton clicke (-1:hors de la fenêtre, 0:aucun) ---
 | 
						|
short Window_get_clicked_button(void)
 | 
						|
{
 | 
						|
  T_Normal_button   * temp1;
 | 
						|
  T_Palette_button  * temp2;
 | 
						|
  T_Scroller_button * temp3;
 | 
						|
  T_Special_button  * temp4;
 | 
						|
  T_Dropdown_button * temp5;
 | 
						|
 | 
						|
  long max_slider_height;
 | 
						|
 | 
						|
  Window_attribute1=Mouse_K;
 | 
						|
 | 
						|
  // Test du click sur les boutons normaux
 | 
						|
  for (temp1=Window_normal_button_list; temp1; temp1=temp1->Next)
 | 
						|
  {
 | 
						|
    if (Window_click_in_rectangle(temp1->Pos_X,temp1->Pos_Y,temp1->Pos_X+temp1->Width-1,temp1->Pos_Y+temp1->Height-1))
 | 
						|
    {
 | 
						|
      if (temp1->Repeatable)
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        Window_select_normal_button(temp1->Pos_X,temp1->Pos_Y,temp1->Width,temp1->Height);
 | 
						|
        Display_cursor();
 | 
						|
        Slider_timer((Mouse_K==1)? Config.Delay_left_click_on_slider : Config.Delay_right_click_on_slider);
 | 
						|
        Hide_cursor();
 | 
						|
        Window_unselect_normal_button(temp1->Pos_X,temp1->Pos_Y,temp1->Width,temp1->Height);
 | 
						|
        Display_cursor();        
 | 
						|
        return temp1->Number;
 | 
						|
      }
 | 
						|
      return Window_normal_button_onclick(temp1->Pos_X,temp1->Pos_Y,temp1->Width,temp1->Height,temp1->Number);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Test du click sur les zones "palette"
 | 
						|
  for (temp2=Window_palette_button_list; temp2; temp2=temp2->Next)
 | 
						|
  {
 | 
						|
    if (Window_click_in_rectangle(temp2->Pos_X+5,temp2->Pos_Y+3,temp2->Pos_X+160,temp2->Pos_Y+82))
 | 
						|
    {
 | 
						|
      // On stocke dans Attribut2 le numero de couleur cliqué
 | 
						|
      Window_attribute2 = (((Mouse_X-Window_pos_X)/Menu_factor_X)-(temp2->Pos_X+2)) / 10 * 16 +
 | 
						|
        (((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-(temp2->Pos_Y+3)) / 5;
 | 
						|
        return temp2->Number;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Test du click sur les barres de défilement
 | 
						|
  for (temp3=Window_scroller_button_list; temp3; temp3=temp3->Next)
 | 
						|
  {
 | 
						|
    if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-1))
 | 
						|
    {
 | 
						|
      // Button flèche Haut
 | 
						|
      if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y,temp3->Pos_X+10,temp3->Pos_Y+10))
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        Window_select_normal_button(temp3->Pos_X,temp3->Pos_Y,11,11);
 | 
						|
 | 
						|
        if (temp3->Position)
 | 
						|
        {
 | 
						|
          temp3->Position--;
 | 
						|
          Window_attribute1=1;
 | 
						|
          Window_attribute2=temp3->Position;
 | 
						|
          Window_draw_slider(temp3);
 | 
						|
        }
 | 
						|
        else
 | 
						|
          Window_attribute1=0;
 | 
						|
        
 | 
						|
        Display_cursor();
 | 
						|
 | 
						|
        Slider_timer((Mouse_K==1)? Config.Delay_left_click_on_slider : Config.Delay_right_click_on_slider);
 | 
						|
 | 
						|
        Hide_cursor();
 | 
						|
        Window_unselect_normal_button(temp3->Pos_X,temp3->Pos_Y,11,11);
 | 
						|
        Display_cursor();
 | 
						|
      }
 | 
						|
      else
 | 
						|
      // Button flèche Bas
 | 
						|
      if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y+temp3->Height-11,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-1))
 | 
						|
      {
 | 
						|
        Hide_cursor();
 | 
						|
        Window_select_normal_button(temp3->Pos_X,temp3->Pos_Y+temp3->Height-11,11,11);
 | 
						|
 | 
						|
        if (temp3->Position+temp3->Nb_visibles<temp3->Nb_elements)
 | 
						|
        {
 | 
						|
          temp3->Position++;
 | 
						|
          Window_attribute1=2;
 | 
						|
          Window_attribute2=temp3->Position;
 | 
						|
          Window_draw_slider(temp3);
 | 
						|
        }
 | 
						|
        else
 | 
						|
          Window_attribute1=0;
 | 
						|
 | 
						|
        Display_cursor();
 | 
						|
 | 
						|
        Slider_timer((Mouse_K==1)? Config.Delay_left_click_on_slider : Config.Delay_right_click_on_slider);
 | 
						|
 | 
						|
        Hide_cursor();
 | 
						|
        Window_unselect_normal_button(temp3->Pos_X,temp3->Pos_Y+temp3->Height-11,11,11);
 | 
						|
        Display_cursor();
 | 
						|
      }
 | 
						|
      else
 | 
						|
      // Jauge
 | 
						|
      if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y+12,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-13))
 | 
						|
      {
 | 
						|
        if (temp3->Nb_elements>temp3->Nb_visibles)
 | 
						|
        {
 | 
						|
          // S'il y a la place de faire scroller le curseur:
 | 
						|
 | 
						|
          max_slider_height=(temp3->Height-24);
 | 
						|
 | 
						|
          // Window_attribute2 reçoit la position dans la jauge correspondant au click
 | 
						|
          Window_attribute2 =(Mouse_Y-Window_pos_Y) / Menu_factor_Y;
 | 
						|
          Window_attribute2-=(temp3->Pos_Y+12+((temp3->Cursor_height-1)>>1));
 | 
						|
          Window_attribute2*=(temp3->Nb_elements-temp3->Nb_visibles);
 | 
						|
 | 
						|
          if (Window_attribute2<0)
 | 
						|
            Window_attribute2=0;
 | 
						|
          else
 | 
						|
          {
 | 
						|
            Window_attribute2 =Round_div(Window_attribute2,max_slider_height-temp3->Cursor_height);
 | 
						|
            if (Window_attribute2+temp3->Nb_visibles>temp3->Nb_elements)
 | 
						|
              Window_attribute2=temp3->Nb_elements-temp3->Nb_visibles;
 | 
						|
          }
 | 
						|
 | 
						|
          // Si le curseur de la jauge bouge:
 | 
						|
 | 
						|
          if (temp3->Position!=Window_attribute2)
 | 
						|
          {
 | 
						|
            temp3->Position=Window_attribute2;
 | 
						|
            Window_attribute1=3;
 | 
						|
            Hide_cursor();
 | 
						|
            Window_draw_slider(temp3);
 | 
						|
            Display_cursor();
 | 
						|
          }
 | 
						|
          else
 | 
						|
            // Si le curseur de la jauge ne bouge pas:
 | 
						|
            Window_attribute1=0;
 | 
						|
        }
 | 
						|
        else
 | 
						|
          // S'il n'y a pas la place de bouger le curseur de la jauge:
 | 
						|
          Window_attribute1=0;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        // Le click se situe dans la zone de la jauge mais n'est sur aucune
 | 
						|
        // des 3 parties importantes de la jauge
 | 
						|
        Window_attribute1=0;
 | 
						|
 | 
						|
      return (Window_attribute1)? temp3->Number : 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Test du click sur une zone spéciale
 | 
						|
  for (temp4=Window_special_button_list; temp4; temp4=temp4->Next)
 | 
						|
  {
 | 
						|
    if (Window_click_in_rectangle(temp4->Pos_X,temp4->Pos_Y,temp4->Pos_X+temp4->Width-1,temp4->Pos_Y+temp4->Height-1))
 | 
						|
      return temp4->Number;
 | 
						|
  }
 | 
						|
 | 
						|
  // Test du click sur une dropdown
 | 
						|
  for (temp5=Window_dropdown_button_list; temp5; temp5=temp5->Next)
 | 
						|
  {
 | 
						|
    if (Window_click_in_rectangle(temp5->Pos_X,temp5->Pos_Y,temp5->Pos_X+temp5->Width-1,temp5->Pos_Y+temp5->Height-1))
 | 
						|
    {
 | 
						|
      if (Mouse_K & temp5->Active_button)
 | 
						|
        return Window_dropdown_on_click(temp5);
 | 
						|
      else
 | 
						|
      {
 | 
						|
        Window_attribute2=-1;
 | 
						|
        return Window_normal_button_onclick(temp5->Pos_X,temp5->Pos_Y,temp5->Width,temp5->Height,temp5->Number);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
short Window_get_button_shortcut(void)
 | 
						|
{
 | 
						|
  T_Normal_button * temp;
 | 
						|
 | 
						|
  if (Key & MOD_SHIFT)
 | 
						|
    Window_attribute1=RIGHT_SIDE;
 | 
						|
  else
 | 
						|
    Window_attribute1=LEFT_SIDE;
 | 
						|
 | 
						|
  // On fait une première recherche
 | 
						|
  temp=Window_normal_button_list;
 | 
						|
  while (temp!=NULL)
 | 
						|
  {
 | 
						|
    if (temp->Shortcut==Key)
 | 
						|
    {
 | 
						|
      Hide_cursor();
 | 
						|
      Window_select_normal_button(temp->Pos_X,temp->Pos_Y,temp->Width,temp->Height);
 | 
						|
      Display_cursor();
 | 
						|
      
 | 
						|
      Slider_timer(Config.Delay_right_click_on_slider);
 | 
						|
      
 | 
						|
      Hide_cursor();
 | 
						|
      Window_unselect_normal_button(temp->Pos_X,temp->Pos_Y,temp->Width,temp->Height);
 | 
						|
      Display_cursor();
 | 
						|
 | 
						|
      return temp->Number;
 | 
						|
    }
 | 
						|
    temp=temp->Next;
 | 
						|
  }
 | 
						|
 | 
						|
  // Si la recherche n'a pas été fructueuse ET que l'utilisateur appuyait sur
 | 
						|
  // <Shift>, on regarde si un bouton ne pourrait pas réagir comme si <Shift>
 | 
						|
  // n'était pas appuyé.
 | 
						|
  if (Window_attribute1==RIGHT_SIDE)
 | 
						|
  {
 | 
						|
    temp=Window_normal_button_list;
 | 
						|
    while (temp!=NULL)
 | 
						|
    {
 | 
						|
      if (temp->Shortcut==(Key&0x0FFF))
 | 
						|
        return temp->Number;
 | 
						|
      temp=temp->Next;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
short Window_clicked_button(void)
 | 
						|
{
 | 
						|
  short Button;
 | 
						|
 | 
						|
  if(!Get_input())Wait_VBL();
 | 
						|
 | 
						|
  // Gestion des clicks
 | 
						|
  if (Mouse_K)
 | 
						|
  {
 | 
						|
    if ((Mouse_X<Window_pos_X) || (Mouse_Y<Window_pos_Y)
 | 
						|
     || (Mouse_X>=Window_pos_X+(Window_width*Menu_factor_X))
 | 
						|
     || (Mouse_Y>=Window_pos_Y+(Window_height*Menu_factor_Y)))
 | 
						|
      return -1;
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (Mouse_Y < Window_pos_Y+(12*Menu_factor_Y))
 | 
						|
        Move_window(Mouse_X-Window_pos_X,Mouse_Y-Window_pos_Y);
 | 
						|
      else
 | 
						|
        return Window_get_clicked_button();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Gestion des touches
 | 
						|
  if (Key)
 | 
						|
  {
 | 
						|
    Button=Window_get_button_shortcut();
 | 
						|
    if (Button)
 | 
						|
    {
 | 
						|
      Key=0;
 | 
						|
      return Button;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Fonction qui sert à remapper les parties sauvegardées derriere les
 | 
						|
// fenetres ouvertes. C'est utilisé par exemple par la fenetre de palette
 | 
						|
// Qui remappe des couleurs, afin de propager les changements.
 | 
						|
void Remap_window_backgrounds(byte * conversion_table, int Min_Y, int Max_Y)
 | 
						|
{
 | 
						|
  int window_index; 
 | 
						|
        byte* EDI;
 | 
						|
        int dx,cx;
 | 
						|
 | 
						|
  for (window_index=0; window_index<Windows_open; window_index++)
 | 
						|
  {
 | 
						|
    EDI = Window_background[window_index];
 | 
						|
  
 | 
						|
        // Pour chaque ligne
 | 
						|
        for(dx=0; dx<Window_stack_height[window_index]*Menu_factor_Y;dx++)
 | 
						|
        {
 | 
						|
          if (dx+Window_stack_pos_Y[window_index]>Max_Y)
 | 
						|
            return;
 | 
						|
          if (dx+Window_stack_pos_Y[window_index]<Min_Y)
 | 
						|
          {
 | 
						|
            EDI += Window_stack_width[window_index]*Menu_factor_X*Pixel_width;
 | 
						|
          }
 | 
						|
          else
 | 
						|
                // Pour chaque pixel
 | 
						|
                for(cx=Window_stack_width[window_index]*Menu_factor_X*Pixel_width;cx>0;cx--)
 | 
						|
                {
 | 
						|
                        *EDI = conversion_table[*EDI];
 | 
						|
                        EDI ++;
 | 
						|
                }
 | 
						|
        }
 | 
						|
  }
 | 
						|
}
 |