Управление панелью инструментов: автоматный подход
//=========================================================
// Модуль, реализующий управление тулбарами
// Версия, выполненная с применением автоматного подхода
//======
// Обработчик события нажатия кнопки мыши на панели
//
int toolbar_btn_press( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
toolbar_t *tb = tb_data(widget) ;
// Указатель на данные панели
PhEvent_t *event = cbinfo->event ;
// Произошедшее событие
PhPointerEvent_t *edata = PhGetData( event ) ;
// Дополнительная информация о событии
if( edata->buttons == Ph_BUTTON_MENU )
{
// Нажатая кнопка мыши - правая
// Вызвать управляющий автомат
A0( 10, tb, event ) ;
} ;
return( Pt_CONTINUE ) ;
} ;
//======
// Обработчик события отпускания кнопки мыши на панели
//
int toolbar_btn_release( PtWidget_t *widget,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
toolbar_t *tb = tb_data(widget) ;
// Указатель на данные тулбара
PhEvent_t *event = cbinfo->event ;
// Произошедшее событие
PhPointerEvent_t *edata = PhGetData( event ) ;
// Дополнительная информация о событии
if( event->subtype == Ph_EV_RELEASE_REAL
&& edata->buttons == Ph_BUTTON_MENU )
{
// Отпущенная кнопка мыши - правая
// Вызвать управляющий автомат
A0( 20, tb, event ) ;
} ;
return( Pt_CONTINUE ) ;
} ;
//======
// Обработчик события перемещения мыши с нажатой кнопкой
//
int toolbar_btn_move( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
toolbar_t *tb = tb_data(widget) ;
// Указатель на данные панели
PhEvent_t *event = cbinfo->event ;
// Произошедшее событие
PhPointerEvent_t *edata = PhGetData( event ) ;
// Дополнительная информация о событии
if( edata->buttons == Ph_BUTTON_MENU )
{
// Правая кнопка нажата
// Вызвать управляющий автомат
A0( 30, tb, event ) ;
} ;
return( Pt_CONTINUE ) ;
} ;
//======
// Обработчик события пересечения курсором мыши
// границы панели
int toolbar_boundary( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
toolbar_t *tb = tb_data(widget) ;
// Указатель на данные панели
PhEvent_t *event = cbinfo->event ;
// Произошедшее событие
if( event->subtype == Ph_EV_PTR_LEAVE )
{
// Курсор мыши вышел за границу панели
// Вызвать управляющий автомат
A0( 40, tb, event ) ;
} ;
return( Pt_CONTINUE ) ;
} ;
//======
// Функция, реализующая автомат управления панелью
//
void A0( int e, toolbar_t *tb, PhEvent_t *event )
{
int y_old = tb->y0 ;
#ifdef GRAPH_EVENTS_LOGGING
log_exec( "A0", y_old, e ) ;
#endif
switch( tb->y0 )
{
case 0:
if( e == 10 ) tb->y0 = 1 ;
break ;
case 1:
if( e == 20 ) { z30(tb) ; tb->y0 = 0 ; }
else
if( e == 30 ) tb->y0 = 2 ;
else
if( e == 40 ) tb->y0 = 0 ;
break ;
case 2:
if( e == 30 ) { z20(tb, event) ; }
else
if( e != 30 ) tb->y0 = 0 ;
break ;
default:
#ifdef GRAPH_ERRORS_LOGGING
log_write( LOG_GRAPH_ERROR,
"ОШИБКА В A0: неизвестное состояние!", 0 ) ;
#endif
break ;
} ;
// Если состояние не изменилось,
// завершить выполнение функции
if( y_old == tb->y0 ) goto A0_end ;
#ifdef GRAPH_TRANS_LOGGING
log_trans( "A0", y_old, tb->y0 ) ;
#endif
switch( tb->y0 )
{
case 1:
z10(tb, event) ; z40(tb) ;
break ;
case 2:
z20(tb, event) ;
break;
} ;
A0_end: ;
#ifdef GRAPH_ENDS_LOGGING
log_end( "A0", tb->y0, e ) ;
#endif
} ;
//======
// Запомнить координаты курсора мыши.
//
void z10( toolbar_t *tb, PhEvent_t *event )
{
PhRect_t *rect = NULL ; // Координаты курсора мыши
#ifdef ACTIONS_LOGGING
log_write( LOG_ACTION,
"z10. Запомнить координаты курсора мыши.", 0 ) ;
#endif
rect = PhGetRects( event ) ;
tb->drag_pos = rect->ul ;
} ;
//======
// Переместить панель
//
void z20( toolbar_t *tb, PhEvent_t *event )
{
PhRect_t *rect = NULL ; // Координаты курсора мыши.
#ifdef ACTIONS_LOGGING
log_write( LOG_ACTION, "z20. Переместить панель.", 0);
#endif
rect = PhGetRects( event ) ;
toolbar_move( tb, rect->ul.x - tb->drag_pos.x,
rect->ul.y - tb->drag_pos.y ) ;
} ;
//======
// Вызвать меню панели
//
void z30( toolbar_t *tb )
{
#ifdef ACTIONS_LOGGING
log_write( LOG_ACTION, "z30. Вызвать меню панели.", 0);
#endif
ApCreateModule( ABM_toolbar_menu, NULL, NULL ) ;
} ;
//======
// Поместить окно панели выше остальных.
//
void z40( toolbar_t *tb )
{
#ifdef ACTIONS_LOGGING
log_write( LOG_ACTION,
"z40. Поместить окно панели поверх остальных.", 0);
#endif
PtWindowToFront( tb->wgt ) ;
} ;