|
![ein Kapitel weiter](../weiter.gif)
Mit Curses ist es auch möglich die Maus miteinzubeziehen. Gemeint sind nicht die Funktionen der Headerdatei <gpm.h>. Diese möchte in einem späteren Kapitel besprechen. Der Vorteil der Mausroutinen von Curses ist das diese sowohl im Textmodus als auch im XTerm laufen. Folgende Struktur wurde dafür definiert....
typedef struct {
short ID; //Indentität,falls mehrere Mäuse angeschlossen sind
int x,y,z; //Koordinaten,z nicht benötigt
mmask_t bstate;//Bitmaske für Mausknöpfe
}MEVENT;
Der Datentyp mmask_t wurde folgendermaßen erzeugt:
typedef unsigned long mmask_t;
Damit Curses überhaupt eine Mauseingabe zur Kenntnis nimmt muss die Funktion....
mmask_t mousemask(mmask_t neuemaske, mmask_t *altemaske);
....aufgerufen werden. In der Variablen neuemaske definieren wir welche Mausereignisse bearbeitet werden. Folgende Mausereignisse sind in Curses definiert....
#define BUTTON1_RELEASED 000000000001L
#define BUTTON1_PRESSED 000000000002L
#define BUTTON1_CLICKED 000000000004L
#define BUTTON1_DOUBLE_CLICKED 000000000010L
#define BUTTON1_TRIPLE_CLICKED 000000000020L
#define BUTTON1_RESERVED_EVENT 000000000040L
#define BUTTON2_RELEASED 000000000100L
#define BUTTON2_PRESSED 000000000200L
#define BUTTON2_CLICKED 000000000400L
#define BUTTON2_DOUBLE_CLICKED 000000001000L
#define BUTTON2_TRIPLE_CLICKED 000000002000L
#define BUTTON2_RESERVED_EVENT 000000004000L
#define BUTTON3_RELEASED 000000010000L
#define BUTTON3_PRESSED 000000020000L
#define BUTTON3_CLICKED 000000040000L
#define BUTTON3_DOUBLE_CLICKED 000000100000L
#define BUTTON3_TRIPLE_CLICKED 000000200000L
#define BUTTON3_RESERVED_EVENT 000000400000L
#define BUTTON4_RELEASED 000001000000L
#define BUTTON4_PRESSED 000002000000L
#define BUTTON4_CLICKED 000004000000L
#define BUTTON4_DOUBLE_CLICKED 000010000000L
#define BUTTON4_TRIPLE_CLICKED 000020000000L
#define BUTTON4_RESERVED_EVENT 000040000000L
#define BUTTON_CTRL 000100000000L
#define BUTTON_SHIFT 000200000000L
#define BUTTON_ALT 000400000000L
#define ALL_MOUSE_EVENTS
#define REPORT_MOUSE_POSITION
Ich nehme mal an diese Funktionen sind selbsterklärend. Mit......
int maske=mousemask(BUTTON1_PRESSED,NULL);
....können wir die Routine BUTTON1_PRESSED, also die linke Maustaste gedrückt, bearbeiten. Nun wollen wir mit wgetch() die Mauseigenschaft abrufen....
chtype button;
button = wgetch(stdscr);
Wurde eine Mausaktivität registriert so gibt wgetch KEY_MOUSE zurück....
if(button==KEY_MOUSE)
{
{/*Mausaktivitäten*/
..................
Jetzt wollen wir die Mausaktivität auslesen. Dies geschieht mittels der Funktion...
int getmouse(MEVENT *event);
....in der Praxis.......
if(getmouse(&event) == OK)
{
/*Konnte Mausereignis lesen*/
......................
Der Rückgabewert von getmouse lautet OK bei erfolgreichen lesen. Ansonsten ERR. Auf einzelne Ereignisse greifen sie folgendermaßen zu.....
y-Koordinate = event.y;
x-Koordinate = event.x;
bitmaske = event.bstate;
ID = event.id;
z.B. Wir testen auf Doppelklick...
If(event.bstate == BUTTON1_DOUBLE_CLICK)
{
/*die linke Taste wurde Doppeltgeklickt*/
..............................
Um zu überprüfen wo und ob im zulässigen Fenster die Mauskoordinate (y,x) liegt, benötigen wir die Funktion...........
bool wenclose(WINDOW *win, int y, int x);
Der Rückgabewert dieser Funktion lautet falls das Ereignis im Fenster passierte TRUE ansonsten FALSE. Ein kleines Programmbeispiel soll dies Demonstrieren. Wir klicken in einem Bereich des Fensters stdscr und geben die Werte zurück an welcher Position genau wir im Fenster den linken Mausbutton betätigt haben....
/*Download:cur13.c*/
#include <curses.h>
#include <stdlib.h>
int main()
{
MEVENT pos;
int l_maus;
chtype button;
initscr();
noecho();
keypad(stdscr,TRUE);
l_maus=mousemask(BUTTON1_PRESSED,NULL);
while(1)
{
button=wgetch(stdscr);
if(button==KEY_MOUSE)
{
if(getmouse(&pos)==OK)
{
wenclose(stdscr,pos.y,pos.x);
mvwprintw(stdscr,1,0,"y = %2d x = %2d",pos.y,pos.x);
}
}
wrefresh(stdscr);
}
endwin();
return 0;
}
|
Dieses Beispiel wollen wir jetzt verändern und Überprüfen an welcher Stelle im Fenster stdscr die Maustaste gedrückt wurde (y,x) und an welcher Stelle die Maustaste im Fenster wieder losgelassen wurde......
/*Download:cur14.c*/
#include <curses.h>
#include <stdlib.h>
int main()
{
MEVENT pos;
int l_maus;
chtype button;
initscr();
noecho();
keypad(stdscr,TRUE);
l_maus=mousemask(BUTTON1_RELEASED|BUTTON1_PRESSED|BUTTON1_CLICKED,NULL);
while(1)
{
button=wgetch(stdscr);
clear();
if(button==KEY_MOUSE)
{
if(getmouse(&pos)==OK)
{/*linke Maustaste gedrückt bei..*/
if(pos.bstate==BUTTON1_PRESSED)
{
wenclose(stdscr,pos.y,pos.x);
mvwprintw(stdscr,1,0,
"linke Maustaste gedrückt bei y = %2d x = %2d",pos.y,pos.x);
}/*linke Maustaste losgelassen bei....*/
if(pos.bstate==BUTTON1_RELEASED)
{/*Reaktionszeit beim loslassen auf 1 Tausendstel Sekunde*/
mouseinterval(1);
wenclose(stdscr,pos.y,pos.x);
mvwprintw(stdscr,2,0,
"linke Maustaste losgelassen y = %2d x = %2d",pos.y,pos.x);
}
}
}
wrefresh(stdscr);
}
endwin();
return 0;
}
|
Wenn die Maustaste zu schnell oder zu langsam reagiert können sie (wie im Beispiel eben geschehen) die Funktion.........
int mouseinterval(int Tausendstelsekunde);
...benutzen. Jetzt wollen wir die Mausroutinen etwas praktischer Einsetzten. Wir erzeugen ein Fenster (WINDOW *fenster) und geben diese auf dem Bildschirm aus. Sie könne jetzt auf jedem beliebigen Bereich im stdscr mit der linken Maus drücken und das Fenster wird an diesem Punkt falls möglich versetzt. Als Ausganspunkt nehmen wir die linke obere Ecke. Weiterhin habe ich an der linken oberen Ecke den Buchstaben 'S' und an der rechten oberen Ecke den Buchstaben 'M' an die Fensterecken gesetzt. Mit 'S' für Schließen schließen wir das Fenster. Mit 'M' Maximieren wir das Fenster *fenster. Erneutes Klicken auf 'M' bewirkt wieder das Minimieren zur normalen Größe des Fensters............
/*Download:cur15.c*/
#include <curses.h>
#include <stdlib.h>
#define MAXSIZE 1
#define MINSIZE 0
int y_click,x_click;
int y_click2,x_click2;
int size=MINSIZE;
void where_clicked(WINDOW *win,WINDOW *win2,MEVENT pos)
{
getbegyx(win2,y_click2,x_click2); /*linke obere Ecke von win2*/
mouseinterval(1);
wenclose(win,pos.y,pos.x); /*wo in win wurde geklickt*/
y_click = pos.y;
x_click = pos.x;
/*wurde auf die linke obere Ecke von win2*/
if(y_click==y_click2 && x_click==x_click2)
{
endwin();
exit(0);
}
else if(y_click==y_click2 && x_click==x_click2+39 || x_click==x_click2+78)
{ //oder wurde auf der rechten oberen Ecke geklickt
touchwin(stdscr);
refresh();
if(size==MINSIZE)
{
delwin(win2);
size=MAXSIZE;
}
else if(size==MAXSIZE)
{
delwin(win2);
size=MINSIZE;
}
}
}
/*Verschieben des Fensters an Position der globalen Variablen*/
/* x_click und y_click die zuvor mit where_clicked() ermittelt wurden*/
void move_win_to(WINDOW *win)
{
touchwin(stdscr);
wrefresh(stdscr);
mvwin(win,y_click+1,x_click+1);
touchwin(win);
wrefresh(win);
}
WINDOW *create_new_window(WINDOW *neues_fenster, int zeilen,
int spalten, int hinterg, int vordergr, int begin_y, int begin_x)
{
neues_fenster=newwin(zeilen,spalten,begin_y,begin_x);
init_pair(1,hinterg,vorderg);
wattrset(neues_fenster,COLOR_PAIR(1));
box(neues_fenster,ACS_VLINE,ACS_HLINE);
return neues_fenster;
}
int main()
{
MEVENT pos;
int l_maus;
chtype button;
WINDOW *fenster,mfenster;
int y_alt,x_alt;
initscr();
if(has_colors()==TRUE)
start_color();
noecho();
keypad(stdscr,TRUE);
fenster=create_new_window(fenster,10,40,COLOR_RED,COLOR_BLUE,5,15);
init_pair(2,COLOR_BLACK,COLOR_YELLOW);
wattrset(fenster,COLOR_PAIR(2));
mvwaddch(fenster,0,0,'S');
mvwaddch(fenster,0,39,'M');
wattrset(fenster,COLOR_PAIR(0));
mvwprintw(fenster,2,10,"S=Fenster schliessen");
mvwprintw(fenster,6,10,"M=Fenster maximieren");
wrefresh(fenster);
l_maus=mousemask(BUTTON1_RELEASED|BUTTON1_PRESSED,NULL);
while(1)
{
button=wgetch(stdscr);
if(button==KEY_MOUSE)
{
if(getmouse(&pos)==OK)
{
where_clicked(stdscr,fenster,pos);
//move_win_to(fenster);
if(size==MAXSIZE)
{
fenster=create_new_window(fenster,24,79,COLOR_RED,COLOR_BLUE,0,0);
wattrset(fenster,COLOR_PAIR(2));
mvwaddch(fenster,0,0,'S');
mvwaddch(fenster,0,78,'M');
wattrset(fenster,COLOR_PAIR(0));
mvwprintw(fenster,10,30,"S=Fenster schliessen");
mvwprintw(fenster,14,30,"M=Fenster minimieren");
wrefresh(fenster);
}
else if(size==MINSIZE)
{
fenster=create_new_window(fenster,10,40,COLOR_RED,COLOR_BLUE,5,15);
init_pair(2,COLOR_BLACK,COLOR_YELLOW);
wattrset(fenster,COLOR_PAIR(2));
mvwaddch(fenster,0,0,'S');
mvwaddch(fenster,0,39,'M');
wattrset(fenster,COLOR_PAIR(0));
mvwprintw(fenster,2,10,"S=Fenster schliessen");
mvwprintw(fenster,6,10,"M=Fenster maximieren");
wrefresh(fenster);
move_win_to(fenster);
}
}
}
}
endwin();
return 0;
}
|
So siehts aus:
Auf diesem Grundwissen können sie eine Benutzeroberfläche bauen. Z.B.: Eine Daten- bank für die Textkonsole........
Zwei weitere Funktionen die es noch gibt, ich aber nicht durchnehmen will wären die Funktion....
int ungetmouse(MEVENT *event);
...und...
bool wmouse_trafo(WINDOW *win, int *Py, int *Px);
Für Informationen dazu lesen sie bitte die man-Page (man mouse).
![ein Kapitel weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|