All pastes #1451516 Raw Edit

GUI Test by Pawn

public c v1 · immutable
#1451516 ·published 2009-06-08 05:20 UTC
rendered paste body
/* A	demo	GTK application in Pawn,	using gtk-server and the	"process control" * module	for Pawn.	This	example also illustrates	the use of (communicating) * finite	state machines. */#include <process>#include <string>#pragma tabsize 0enum	Btn{    Btn0,	   Btn1,	  Btn2,    Btn3,	   Btn4,	  Btn5,    Btn6,	   Btn7,	  Btn8,    Btn9,	   BtnDot,  BtnC,    BtnCE,   BtnPlus, BtnMin,    BtnMul,  BtnDiv,  BtnEqual,    BtnNone,}static entry;	  /*	GTK "entry" widget */static numberstring[40 char];static accum;static Btn:pending_op;adddigit(digit, bool:reset = false){    new command[80 char], charstr[2 char];    charstr{0}	= (0	<= digit <= 9)	? digit +	'0' : digit;    if(reset)numberstring[0] = EOS;    strcat(numberstring,	charstr);    strformat(command, _, true, "gtk_entry_set_text %d	%s",	entry, numberstring);    GTK(command);}displayresult(value){    new command[80 char];    valstr numberstring,	value, true;    strformat(command, _, true, "gtk_entry_set_text %d	%s",	entry, numberstring);    GTK(command);}resetentry(digit) <number:negated>{    adddigit('-', .reset	= true);    adddigit(digit);}resetentry(digit) <>{    adddigit(digit,	.reset = true);}event_0()	<number:zero, number:negated>{    resetentry(0);}event_0()	<number:int, number:frac>{    adddigit(0);}event_1_9(Btn:idx) <number:zero, number:negated>{    resetentry(_:(idx - Btn0));    state	number:int;}event_1_9(Btn:idx) <number:int, number:frac>{    adddigit(_:(idx	- Btn0));}event_dot() <number:zero, number:negated>{    resetentry(0);    adddigit('.');    state	number:frac;}event_dot() <number:int>{    adddigit('.');    state	number:frac;}event_dot() <number:frac>{    /*Do Something*/}event_minus() <number:zero, number:negated>{    state	number:negated;    resetentry(0);}event_minus() <>{    event_oper(BtnMin);	 /* forward to	the "calc" automaton */}/* helper	function for the calculator automaton */performoperation(){    /* get the	other operand,	perform the operation */    new val = strval(numberstring);    switch (pending_op){	   case BtnPlus:accum += val	   case BtnMin:accum -= val	   case BtnMul:accum *= val	   case BtnDiv:accum = (val == 0) ? 0 :	accum / val    }    displayresult(accum);}event_oper(Btn:idx)	<calc:idle>{    /* save operand	and operator */    accum	= strval(numberstring);    pending_op	= idx;    state	number:zero;    state	calc:pending;}event_oper(Btn:idx)	<calc:pending>{    performoperation();		  /*	do the pending	operation	*/    pending_op	= idx		  /*	save	the operator for the next operation */    state	number:zero    }event_equal() <calc:idle>{    /* ignore */}event_equal() <calc:pending>{    performoperation();		  /*	do the pending	operation	*/    state	calc:idle;			  /*	reset the	calculator */    state	number:zero;}event_C(){    state	calc:idle;    state	number:zero;    resetentry(0);}event_CE(){    state	number:zero;    resetentry(0);}main(){    if (!procexec("gtk-server	-stdin") && !procexec("gtk-server.exe -stdin"))fatal("unable to	launch gtk-server");    /* make a window */    GTK("gtk_init NULL NULL");    new win = GTK("gtk_window_new 0");    GTK("gtk_window_set_title	%d \"GUI Test in Pawn\"", win);    GTK("gtk_widget_set_usize	%d 200 200", win);    /* add a table (align the	other controls) */    new table = GTK("gtk_table_new	50 50 1");    GTK("gtk_container_add %d	%d",	win,	table);    /* the number entry */    entry	= GTK("gtk_entry_new");    GTK("gtk_table_attach_defaults	%d %d 1 49 1 9", table, entry);    /* the key	pad */    new buttons[Btn];    buttons[BtnDot]	= GTK("gtk_button_new_with_label .");    GTK("gtk_table_attach_defaults	%d %d 21 29 41	49",	table, buttons[BtnDot]);    buttons[Btn0] =	GTK("gtk_button_new_with_label 0");    GTK("gtk_table_attach_defaults	%d %d 1 19 41 49", table, buttons[Btn0]);    buttons[Btn1] =	GTK("gtk_button_new_with_label 1");    GTK("gtk_table_attach_defaults	%d %d 1 9	31 39", table,	buttons[Btn1]);    buttons[Btn2] =	GTK("gtk_button_new_with_label 2");    GTK("gtk_table_attach_defaults	%d %d 11 19 31	39",	table, buttons[Btn2]);    buttons[Btn3] =	GTK("gtk_button_new_with_label 3");    GTK("gtk_table_attach_defaults	%d %d 21 29 31	39",	table, buttons[Btn3]);    buttons[Btn4] =	GTK("gtk_button_new_with_label 4");    GTK("gtk_table_attach_defaults	%d %d 1 9	21 29", table,	buttons[Btn4]);    buttons[Btn5] =	GTK("gtk_button_new_with_label 5");    GTK("gtk_table_attach_defaults	%d %d 11 19 21	29",	table, buttons[Btn5]);    buttons[Btn6] =	GTK("gtk_button_new_with_label 6");    GTK("gtk_table_attach_defaults	%d %d 21 29 21	29",	table, buttons[Btn6]);    buttons[Btn7] =	GTK("gtk_button_new_with_label 7");    GTK("gtk_table_attach_defaults	%d %d 1 9	11 19", table,	buttons[Btn7]);    buttons[Btn8] =	GTK("gtk_button_new_with_label 8");    GTK("gtk_table_attach_defaults	%d %d 11 19 11	19",	table, buttons[Btn8]);    buttons[Btn9] =	GTK("gtk_button_new_with_label 9");    GTK("gtk_table_attach_defaults	%d %d 21 29 11	19",	table, buttons[Btn9]);    buttons[BtnC] =	GTK("gtk_button_new_with_label C");    GTK("gtk_table_attach_defaults	%d %d 31 39 11	19",	table, buttons[BtnC]);    buttons[BtnCE] = GTK("gtk_button_new_with_label CE");    GTK("gtk_table_attach_defaults	%d %d 41 49 11	19",	table, buttons[BtnCE]);    buttons[BtnPlus] = GTK("gtk_button_new_with_label +");    GTK("gtk_table_attach_defaults	%d %d 31 39 21	29",	table, buttons[BtnPlus]);    buttons[BtnMin]	= GTK("gtk_button_new_with_label -");    GTK("gtk_table_attach_defaults	%d %d 41 49 21	29",	table, buttons[BtnMin]);    buttons[BtnMul]	= GTK("gtk_button_new_with_label x");    GTK("gtk_table_attach_defaults	%d %d 31 39 31	39",	table, buttons[BtnMul]);    buttons[BtnDiv]	= GTK("gtk_button_new_with_label /");    GTK("gtk_table_attach_defaults	%d %d 41 49 31	39",	table, buttons[BtnDiv]);    buttons[BtnEqual] = GTK("gtk_button_new_with_label	=");    GTK("gtk_table_attach_defaults	%d %d 31 49 41	49",	table, buttons[BtnEqual]);    /* initialize automata */    state	number:zero;    state	calc:idle;    /* wait for events, and dispatch them */    GTK("gtk_widget_show_all %d", win);    resetentry(0);    new event;    new Btn:idx;    do{	   event = GTK("gtk_server_callback wait");	   /* find the	button matching the	event, generate the	event */	   for (idx = Btn0;	idx < BtnNone && buttons[idx]	!= event;	idx++)	   {}	   switch	(idx){		  	case Btn0:event_0		  	case Btn1 ..	Btn9:event_1_9 idx		  	case BtnDot:event_dot		  	case BtnMin:event_minus		  	case BtnPlus, BtnMul, BtnDiv:event_oper idx		  	case BtnEqual:event_equal		  	case BtnC:event_C		  	case BtnCE:event_CE		  }    }    while	(event !=	win);    /* direct call,	because we must not	wait	for a reply on	this	command */    procwrite("gtk_server_exit", true);}GTK(const	format[],	...){    new command[256	char];    switch (numargs()){	   case 1:strpack(command, format);	   case 2:strformat(command, _, true,	format, getarg(1));	   case 3:strformat(command, _, true,	format, getarg(1), getarg(2));	   case 4:strformat(command, _, true,	format, getarg(1), getarg(2),	getarg(3));	   case 5:strformat(command, _, true,	format, getarg(1), getarg(2),	getarg(3), getarg(4));    }    procwrite(command, true);    new reply[30];    procread(reply,	.striplf=true);    if (strcmp(reply, "ok") == 0)return	true;    return strval(reply);}fatal(const message[]){    printf("FATAL: %s\n", message);    exit;}