Rectangle de Sélection - John COLIBRI. |
- résumé : classe permettant de placer, agrandir, déplacer un rectangle de sélection dans une tPaintBox
- mots clé : graphique - sélection - déplacer, redimensionner
- logiciel utilisé : Windows XP, Delphi 6.0
- matériel utilisé : Pentium 1.400Mhz, 256 M de mémoire, 140 Giga disque dur
- champ d'application : Delphi 1 à 2005 sur Windows
- niveau : développeur Delphi
- plan :
1 - Introduction
Pour le programme de correction de couleurs de bitmap ainsi que pour les classes de éditeur de lignes de
points et dessin de courbes de Bézier nous avions besoin de sélectionner une partie de l'écran. La CLASS Delphi présentée ici permet donc de dessiner, déplacer, changer la
taille d'un rectangle dessiné en inversion de couleur sur une tPaintBox
2 - Principe du dessin XOR 2.1 - Le dessin du rectangle
L'objectif est de sélectionner à l'aide de la souris une zone de l'écran. Il suffit pour cela de dessiner un rectangle, et de pouvoir tester si un point est dans le rectangle ou non.
La création du rectangle se fait par tirer-glisser de la souris: - lors de OnMouseDown le point de départ (supérieur gauche) du rectangle est mémorisé
- lors du déplacement, le point courant est utilisé pour définir le point
d'arrivée (inférieur droit) du rectangle. Un rectangle est alors dessiné en utilisant ces deux points
Pour ne pas modifier le dessin figurant sur la tPaintBox, le dessin se fait en
utilisant un crayon en mode pmNot qui inverse les couleurs, avec une brosse en style bsClear.
2.2 - Pour modifier la taille et la position du rectangle, nous captons aussi les mouvements de la souris:
- lors de l'enfoncement, nous testons la position de la souris:
- proche d'un coin du rectangle ou d'un bord
- à l'intérieur ou à l'extérieur du rectangle
- lors du déplacement de la souris, nous déplaçons les parties
correspondantes:
- pour un coin, nous donnons à ce coin le X et le Y de la souris
- pour un bord, nous modifions la position des deux points correspondants
- pour l'intérieur, nous déplaçons le rectangle
2.3 - Test de position Nous pouvons ensuite tester si un point (p_x, p_y) est dans le rectangle ou non. Le logiciel utilisateur du selecter décidera ce qu'il souhaite faire à ce point.
3 - Le programme Delphi Le type de sélection est défini par:
t_selection_type= (e_unknown_selection,
e_north_west_selection, e_north_east_selection,
e_south_east_selection, e_south_west_selection,
e_north_selection, e_east_selection, e_south_selection, e_west_selection,
e_inside_selection); | correspondant aux coins et bordures du rectangle:
La classe est définie par le type suivant:
c_rectangle_selecter= class(c_basic_object)
m_c_paintbox_ref: tPaintBox;
m_is_active: Boolean;
m_selection_type: t_selection_type;
m_shrink_if_outside_click: Boolean;
m_selection_distance_max: Integer;
m_x_1, m_y_1, m_x_2, m_y_2: Integer;
m_previous_x_1, m_previous_y_1, m_previous_x_2, m_previous_y_2: Integer;
m_mouse_x, m_mouse_y: Integer;
Constructor create_rectangle_selecter(p_name: String;
p_c_paintbox_ref: tPaintbox;
p_selection_distance_max: Integer);
function f_is_empty: Boolean;
procedure empty_selecter;
procedure draw_selecter;
function f_handled_mouse_down(
p_mouse_button: TMouseButton;
p_shift_state: TShiftState; p_x, p_y: Integer): Boolean;
function f_handled_mouse_move(
p_shift_state: TShiftState; p_x, p_y: Integer): Boolean;
function f_handled_mouse_up(
p_mouse_button: TMouseButton;
p_shift_state: TShiftState; p_x, p_y: Integer): Boolean;
function f_is_in_selecter(p_x, p_y: Integer): Boolean;
procedure move_point(var pv_x, pv_y: Double);
end; // c_rectangle_selecter |
Pour les attributs: - m_c_paintbox_ref est la référence vers la tPaintBox où sera dessiné le rectangle
- m_is_active permet de brancher / débrancher le rectangle
- m_selection_type indique où la souris a été cliquée
- m_shrink_if_outside_click permet de réduire le rectangle à 0 si la souris est cliquée en dehors du rectangle
- m_selection_distance_max définit la taille de la bordure
- m_x_1, m_y_1, m_x_2, m_y_2: les deux points qui définissent le rectangle
- m_previous_x_1, m_previous_y_1, m_previous_x_2, m_previous_y_2: permet de réaliser une homothetie des points à l'intérieur du rectangle
- m_mouse_x, m_mouse_y: mémorise la position de la souris
et pour les méthodes: - create_rectangle_selecter reçoit la tPaintbox et spécifie la taille de la bordure
- f_is_empty: indique si le rectangle est vide, et empty_selecter vide le rectangle
- draw_selecter dessine le rectangle en inversant les couleurs
- f_handled_mouse_down: retourne True si le sélecteur est actif, et dans ce cas, mémorise la position de la souris et calcule la valeur de cette
position (quel coin, quelle côté)
- f_handled_mouse_move: retourne True si le sélecteur est actif, et dans ce cas, déplace le coin, la bordure ou le rectangle complet
- f_handled_mouse_up: retourne True si le sélecteur est actif
- f_is_in_selecter: indique si un point est dans le rectangle (similaire à PointInRect)
- move_point: effectue une homothetie lorsque les bordures sont déplacées
Pour le programme utilisateur, il suffit: - d'ajouter u_c_rectangle_selecter aux USES
- de créer le sélecteur (par example dans tForm.OnCreate)
- de tester g_c_rectangle_selecter.f_is_in_selecter(mon_x, mon_y)
Voici un simple dessin du sélecteur:
Pour des exemples concrets d'utilisation, voyez les articles sur le programme de correction de couleurs de bitmap ou les
éditeur de lignes de points. Voici un exemple de translation de points d'une courbe de Bézier:
4 - Télécharger le code source Vous pouvez télécharger: Ce .ZIP qui comprend: - le .DPR, la forme principale, les formes annexes eventuelles
- les fichiers de paramètres (le schéma et le batch de création)
- dans chaque .ZIP, toutes les librairies nécessaires à chaque projet (chaque .ZIP est autonaume)
Ces .ZIP contiennent des chemins RELATIFS. Par conséquent: - créez un répertoire n'importe où sur votre machine
- placez le .ZIP dans ce répertoire
- dézippez et les sous-répertoires nécessaires seront créés
- compilez et exécutez
Ces .ZIP ne modifient pas votre PC (pas de changement de la Base de Registre,
de DLL ou autre). Pour supprimer le projet, effacez le répertoire.
Comme d'habitude: - nous vous remercions de nous signaler toute erreur, inexactitude ou
problème de téléchargement en envoyant un e-mail à jcolibri@jcolibri.com. Les corrections qui en résulteront pourront aider les prochains lecteurs
- tous vos commentaires, remarques, questions, critiques, suggestion d'article, ou mentions d'autres sources sur le même sujet seront de même les bienvenus à jcolibri@jcolibri.com.
- plus simplement, vous pouvez taper (anonymement ou en fournissant votre e-mail pour une réponse) vos commentaires ci-dessus et nous les envoyer en cliquant "envoyer" :
- et si vous avez apprécié cet article, faites connaître notre site, ajoutez un lien dans vos listes de liens ou citez-nous dans vos
blogs ou réponses sur les messageries. C'est très simple: plus nous aurons de visiteurs et de références Google, plus nous écrirons d'articles.
5 - L'auteur
John COLIBRI est passionné par le développement Delphi et les applications de Bases de Données. Il a écrit de nombreux livres et articles, et partage son temps entre le développement de projets (nouveaux projets, maintenance, audit, migration BDE, migration Xe_n, refactoring) pour ses clients, le
conseil (composants, architecture, test) et la
formation. Son site contient des articles
avec code source, ainsi que le programme et le calendrier des stages de formation Delphi, base de données, programmation objet, Services Web, Tcp/Ip et
UML qu'il anime personellement tous les mois, à Paris, en province ou sur site client. |