finalcut/src/fdialog.cpp

1591 lines
34 KiB
C++
Raw Normal View History

// File: fdialog.cpp
// Provides: class FDialog
2015-05-23 13:35:12 +02:00
#include "fapp.h"
#include "fdialog.h"
#include "fstatusbar.h"
//----------------------------------------------------------------------
// class FDialog
//----------------------------------------------------------------------
// constructor and destructor
//----------------------------------------------------------------------
FDialog::FDialog (FWidget* parent)
2015-09-22 04:18:20 +02:00
: FWindow(parent)
, tb_text()
, result_code(FDialog::Reject)
, zoom_button_pressed(false)
, zoom_button_active(false)
, titlebar_click_pos()
, resize_click_pos()
, save_geometry()
2016-06-12 23:06:58 +02:00
, dialog_menu()
, dgl_menuitem()
, move_size_item()
, zoom_item()
, close_item()
, tooltip()
2015-05-23 13:35:12 +02:00
{
2015-09-22 04:18:20 +02:00
init();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
FDialog::FDialog (const FString& txt, FWidget* parent)
: FWindow(parent)
, tb_text(txt)
, result_code(FDialog::Reject)
, zoom_button_pressed(false)
, zoom_button_active(false)
, titlebar_click_pos()
, resize_click_pos()
, save_geometry()
2016-06-12 23:06:58 +02:00
, dialog_menu()
, dgl_menuitem()
, move_size_item()
, zoom_item()
, close_item()
, tooltip(0)
2015-05-23 13:35:12 +02:00
{
2015-09-22 04:18:20 +02:00
init();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FDialog::~FDialog() // destructor
{
2016-07-28 01:04:27 +02:00
FApplication* fapp = static_cast<FApplication*>(getRootWidget());
bool is_quit = fapp->isQuit();
delete dialog_menu;
dgl_menuitem = 0;
2015-05-23 13:35:12 +02:00
delete accelerator_list;
accelerator_list = 0;
2016-07-28 01:04:27 +02:00
if ( ! is_quit )
switchToPrevWindow();
2015-05-23 13:35:12 +02:00
delWindow(this);
delDialog(this);
2015-05-23 13:35:12 +02:00
2016-07-28 01:04:27 +02:00
if ( ! is_quit )
2015-05-23 13:35:12 +02:00
{
const FRect& t_geometry = getTermGeometryWithShadow();
restoreVTerm (t_geometry);
2015-05-23 13:35:12 +02:00
}
if ( vwin != 0 )
{
if ( vwin->changes != 0 )
delete[] vwin->changes;
2015-05-23 13:35:12 +02:00
if ( vwin->text != 0 )
delete[] vwin->text;
2015-05-23 13:35:12 +02:00
delete vwin;
}
2015-05-23 13:35:12 +02:00
if ( isModal() )
unsetModal();
}
// private methods of FDialog
//----------------------------------------------------------------------
void FDialog::init()
{
FWidget* old_focus;
setTopPadding(2);
setLeftPadding(1);
setBottomPadding(1);
setRightPadding(1);
ignorePadding();
setDialogWidget();
// initialize geometry values
setGeometry (1, 1, 10, 10, false);
setMinimumSize (15, 4);
2015-05-23 13:35:12 +02:00
createArea (vwin);
addDialog(this);
2015-05-23 13:35:12 +02:00
addWindow(this);
alwaysOnTop();
2015-05-23 13:35:12 +02:00
setActiveWindow(this);
setTransparentShadow();
2015-05-23 13:35:12 +02:00
setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg);
2015-05-23 13:35:12 +02:00
if ( hasFocus() )
2016-01-24 14:53:09 +01:00
flags |= fc::focus;
2015-05-23 13:35:12 +02:00
if ( isEnabled() )
2016-01-24 14:53:09 +01:00
flags |= fc::active;
2015-05-23 13:35:12 +02:00
old_focus = FWidget::getFocusWidget();
2015-05-23 13:35:12 +02:00
if ( old_focus )
{
setFocus();
2015-05-23 13:35:12 +02:00
old_focus->redraw();
}
2016-06-12 23:06:58 +02:00
accelerator_list = new Accelerators();
// Add the dialog menu
2016-06-12 23:06:58 +02:00
dialog_menu = new FMenu ("-", this);
dialog_menu->move (getX(), getY()+1);
2016-06-12 23:06:58 +02:00
dgl_menuitem = dialog_menu->getItem();
2016-06-12 23:06:58 +02:00
if ( dgl_menuitem )
{
dgl_menuitem->ignorePadding();
dgl_menuitem->unsetFocusable();
}
move_size_item = new FMenuItem (dialog_menu);
move_size_item->setText ("&Move/Size");
move_size_item->setStatusbarMessage ("Move or change the size of the window");
move_size_item->addCallback
(
"clicked",
_METHOD_CALLBACK (this, &FDialog::cb_move)
);
zoom_item = new FMenuItem (dialog_menu);
setZoomItem();
zoom_item->setDisable();
zoom_item->addCallback
(
"clicked",
_METHOD_CALLBACK (this, &FDialog::cb_zoom)
);
close_item = new FMenuItem ("&Close", dialog_menu);
close_item->setStatusbarMessage ("Close this window");
2016-06-12 23:06:58 +02:00
close_item->addCallback
(
"clicked",
_METHOD_CALLBACK (this, &FDialog::cb_close)
);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::drawBorder()
{
int x1 = 1;
int x2 = 1 + getWidth() - 1;
int y1 = 2;
int y2 = 1 + getHeight() - 1;
2015-05-23 13:35:12 +02:00
if ( (getMoveSizeWidget() || ! resize_click_pos.isNull()) && ! isZoomed() )
setColor (wc.dialog_resize_fg, getBackgroundColor());
else
setColor();
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
{
for (int y=y1; y <= y2; y++)
{
printPos (x1, y);
2015-05-23 13:35:12 +02:00
// border left ⎸
print (fc::NF_border_line_left);
printPos (x2, y);
2015-05-23 13:35:12 +02:00
// border right⎹
print (fc::NF_rev_border_line_right);
}
printPos (x1, y2);
// lower left corner border ⎣
print (fc::NF_border_corner_lower_left);
for (int x=1; x < getWidth()-1; x++) // low line _
print (fc::NF_border_line_bottom);
printPos (x2, y2);
// lower right corner border ⎦
print (fc::NF_rev_border_corner_lower_right);
2015-05-23 13:35:12 +02:00
}
else
{
FWidget::drawBorder(x1, y1, x2, y2);
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
void FDialog::drawTitleBar()
{
int i,x,length, zoom_btn;
const int menu_btn = 3;
2015-05-23 13:35:12 +02:00
// draw the title button
printPos (1, 1);
if ( dialog_menu && dialog_menu->isVisible() )
setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg);
else
setColor (wc.titlebar_button_fg, wc.titlebar_button_bg);
if ( isMonochron() )
2015-10-11 21:56:16 +02:00
{
if ( isActiveWindow() )
setReverse(false);
else
setReverse(true);
}
2015-10-23 23:57:00 +02:00
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
{
print (fc::NF_rev_menu_button1);
print (fc::NF_rev_menu_button2);
print (fc::NF_rev_menu_button3);
}
else if ( isMonochron() )
2016-06-12 23:06:58 +02:00
{
print ('[');
2016-06-12 23:06:58 +02:00
if ( dgl_menuitem )
print (dgl_menuitem->getText());
else
print ('-');
2016-06-12 23:06:58 +02:00
print (']');
}
2015-05-23 13:35:12 +02:00
else
2016-06-12 23:06:58 +02:00
{
print (' ');
2016-06-12 23:06:58 +02:00
if ( dgl_menuitem )
print (dgl_menuitem->getText());
else
print ('-');
2016-06-12 23:06:58 +02:00
print (' ');
}
2015-05-23 13:35:12 +02:00
// fill with spaces (left of the title)
2015-10-23 23:57:00 +02:00
if ( getMaxColor() < 16 )
setBold();
if ( isActiveWindow() || (dialog_menu && dialog_menu->isVisible()) )
2015-05-23 13:35:12 +02:00
setColor (wc.titlebar_active_fg, wc.titlebar_active_bg);
else
setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg);
if ( ! isResizeable() )
zoom_btn = 0;
else if ( isNewFont() )
zoom_btn = 2;
else
zoom_btn = 3;
length = int(tb_text.getLength());
i = getWidth() - length - menu_btn - zoom_btn;
2015-05-23 13:35:12 +02:00
i = int(i/2);
for (x=1; x <= i; x++)
print (' ');
// the title bar text
2015-12-08 21:05:00 +01:00
if ( tb_text )
{
if ( length <= getWidth() - menu_btn - zoom_btn )
print (tb_text);
else
{
print (tb_text.left(getWidth() - menu_btn - zoom_btn - 2));
print ("..");
}
}
2015-05-23 13:35:12 +02:00
// fill the rest of the bar
for (; x+1+length < getWidth()-zoom_btn-1; x++)
2015-05-23 13:35:12 +02:00
print (' ');
2015-10-23 23:57:00 +02:00
if ( getMaxColor() < 16 )
unsetBold();
// draw the zoom/unzoom button
if ( isResizeable() )
{
if ( zoom_button_pressed )
setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg);
else
setColor (wc.titlebar_button_fg, wc.titlebar_button_bg);
if ( isZoomed() )
{
if ( isNewFont() )
{
print (fc::NF_rev_down_pointing_triangle1);
print (fc::NF_rev_down_pointing_triangle2);
}
else
{
if ( isMonochron() )
{
print ('[');
print (fc::BlackDownPointingTriangle); // ▼
print (']');
}
else
{
print (' ');
if ( isCygwinTerminal() )
print ('v');
else
print (fc::BlackDownPointingTriangle); // ▼
print (' ');
}
}
}
else // is not zoomed
{
if ( isNewFont() )
{
print (fc::NF_rev_up_pointing_triangle1);
print (fc::NF_rev_up_pointing_triangle2);
}
else
{
if ( isMonochron() )
{
print ('[');
print (fc::BlackUpPointingTriangle); // ▲
print (']');
}
else
{
print (' ');
if ( isCygwinTerminal() )
print ('^');
else
print (fc::BlackUpPointingTriangle); // ▲
print (' ');
}
}
}
}
2015-05-23 13:35:12 +02:00
if ( isMonochron() )
setReverse(false);
/* print the number of window in stack */
//printPos (getWidth()-2, 1);
2015-05-23 13:35:12 +02:00
//printf ("(%d)", getWindowLayer(this));
}
2016-06-13 22:44:15 +02:00
//----------------------------------------------------------------------
void FDialog::leaveMenu()
{
dialog_menu->unselectItem();
dialog_menu->hide();
activateWindow();
raiseWindow();
if ( getWindowFocusWidget() )
getWindowFocusWidget()->setFocus();
2016-06-13 22:44:15 +02:00
redraw();
2016-06-13 22:44:15 +02:00
if ( statusBar() )
statusBar()->drawMessage();
2016-06-13 22:44:15 +02:00
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
void FDialog::openMenu()
{
// open the titlebar menu
if ( ! dialog_menu )
return;
if ( dialog_menu->isVisible() )
{
leaveMenu();
drawTitleBar();
}
else
{
setOpenMenu(dialog_menu);
dialog_menu->move (getX(), getY()+1);
dialog_menu->setVisible();
drawTitleBar();
dialog_menu->show();
dialog_menu->raiseWindow(dialog_menu);
dialog_menu->redraw();
}
}
//----------------------------------------------------------------------
void FDialog::selectFirstMenuItem()
{
// focus to the first enabled menu item
FMenuItem* first_item;
dialog_menu->selectFirstItem();
first_item = dialog_menu->getSelectedItem();
if ( first_item )
first_item->setFocus();
dialog_menu->redraw();
if ( statusBar() )
statusBar()->drawMessage();
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
void FDialog::setZoomItem()
{
if ( isZoomed() )
{
zoom_item->setText ("&Unzoom");
zoom_item->setStatusbarMessage ("Restore the window size");
move_size_item->setDisable();
}
else
{
zoom_item->setText ("&Zoom");
zoom_item->setStatusbarMessage ("Enlarge the window to the entire desktop");
move_size_item->setEnable();
}
}
//----------------------------------------------------------------------
void FDialog::cb_move (FWidget*, void*)
{
if ( isZoomed() )
return;
setMoveSizeWidget(this);
save_geometry = getGeometry();
redraw();
tooltip = new FToolTip(this);
if ( isResizeable() )
{
tooltip->setText ( " Arrow keys: Move\n"
"Meta + Arrow keys: Resize\n"
" Enter: Done\n"
" Esc: Cancel" );
}
else
{
tooltip->setText ( "Arrow keys: Move\n"
" Enter: Done\n"
" Esc: Cancel" );
}
tooltip->show();
}
//----------------------------------------------------------------------
void FDialog::cb_zoom (FWidget*, void*)
{
dialog_menu->unselectItem();
dialog_menu->hide();
setClickedWidget(0);
drawTitleBar();
zoomWindow();
setZoomItem();
}
2016-06-12 23:06:58 +02:00
//----------------------------------------------------------------------
void FDialog::cb_close (FWidget*, void*)
{
dialog_menu->unselectItem();
dialog_menu->hide();
setClickedWidget(0);
drawTitleBar();
close();
}
//----------------------------------------------------------------------
void FDialog::addDialog (FWidget* obj)
{
// add the dialog object obj to the dialog list
if ( dialog_list )
dialog_list->push_back(obj);
}
//----------------------------------------------------------------------
void FDialog::delDialog (FWidget* obj)
{
// delete the dialog object obj from the dialog list
if ( ! dialog_list || dialog_list->empty() )
return;
widgetList::iterator iter;
iter = dialog_list->begin();
while ( iter != dialog_list->end() )
{
if ( (*iter) == obj )
{
dialog_list->erase(iter);
return;
}
++iter;
}
}
2016-06-12 23:06:58 +02:00
2015-05-23 13:35:12 +02:00
// protected methods of FDialog
//----------------------------------------------------------------------
void FDialog::done(int result)
{
hide();
result_code = result;
}
//----------------------------------------------------------------------
void FDialog::drawDialogShadow()
{
if ( isMonochron() && (flags & fc::trans_shadow) == 0 )
return;
2015-05-23 13:35:12 +02:00
drawShadow();
printPos (1, 1+getHeight());
setTransparent();
print(' ');
unsetTransparent();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::draw()
{
if ( tooltip && ! getMoveSizeWidget() )
{
if ( tooltip )
delete tooltip;
tooltip = 0;
}
updateVTerm(false);
2015-05-23 13:35:12 +02:00
// fill the background
setColor();
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
setReverse(true);
clearArea();
2015-05-23 13:35:12 +02:00
drawBorder();
drawTitleBar();
if ( (flags & fc::shadow) != 0 )
2015-05-23 13:35:12 +02:00
drawDialogShadow();
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
setReverse(false);
updateVTerm(true);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::onShow (FShowEvent*)
2015-09-22 04:18:20 +02:00
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
void FDialog::onHide (FHideEvent*)
2015-09-22 04:18:20 +02:00
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FDialog::onClose (FCloseEvent* ev)
2015-05-23 13:35:12 +02:00
{
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
result_code = FDialog::Reject;
}
// public methods of FDialog
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FDialog::onKeyPress (FKeyEvent* ev)
2015-05-23 13:35:12 +02:00
{
if ( ! isEnabled() )
return;
// cancel resize by mouse
if ( ! resize_click_pos.isNull() )
{
resize_click_pos.setPoint (0,0);
drawBorder();
updateTerminal();
}
if ( ev->key() == fc::Fckey_caret ) // Ctrl+^ (Ctrl+6)
{
ev->accept();
// open the titlebar menu
openMenu();
// focus to the first enabled item
selectFirstMenuItem();
}
if ( getMoveSizeWidget() )
{
switch ( ev->key() )
{
case fc::Fkey_up:
move (getX(), getY() - 1);
redraw();
ev->accept();
break;
case fc::Fkey_down:
move (getX(), getY() + 1);
redraw();
ev->accept();
break;
case fc::Fkey_left:
move (getX() - 1, getY());
redraw();
ev->accept();
break;
case fc::Fkey_right:
move (getX() + 1, getY());
redraw();
ev->accept();
break;
case fc::Fmkey_up:
if ( isResizeable() )
{
setSize (getWidth(), getHeight() - 1);
ev->accept();
}
break;
case fc::Fmkey_down:
if ( isResizeable() && getHeight() + getY() <= getMaxHeight() )
{
setSize (getWidth(), getHeight() + 1);
ev->accept();
}
break;
case fc::Fmkey_left:
if ( isResizeable() )
{
setSize (getWidth() - 1, getHeight());
ev->accept();
}
break;
case fc::Fmkey_right:
if ( isResizeable() && getWidth() + getX() <= getMaxWidth() )
{
setSize (getWidth() + 1, getHeight());
ev->accept();
}
break;
case fc::Fkey_return:
case fc::Fkey_enter:
setMoveSizeWidget(0);
if ( tooltip )
delete tooltip;
tooltip = 0;
redraw();
ev->accept();
break;
case fc::Fkey_escape:
case fc::Fkey_escape_mintty:
setMoveSizeWidget(0);
if ( tooltip )
delete tooltip;
tooltip = 0;
move (save_geometry.getPos());
if ( isResizeable() )
setSize (save_geometry.getWidth(), save_geometry.getHeight());
redraw();
ev->accept();
return;
default:
break;
}
}
if ( this == getMainWidget() )
2015-05-23 13:35:12 +02:00
return;
2015-09-20 05:44:50 +02:00
if ( ev->key() == fc::Fkey_escape
|| ev->key() == fc::Fkey_escape_mintty )
2015-05-23 13:35:12 +02:00
{
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
if ( isModal() )
done (FDialog::Reject);
else
close();
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FDialog::onMouseDown (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
2015-09-20 05:44:50 +02:00
int mouse_x = ev->getX();
int mouse_y = ev->getY();
int zoom_btn;;
if ( ! isResizeable() )
zoom_btn = 0;
else if ( isNewFont() )
zoom_btn = 2;
else
zoom_btn = 3;
if ( zoom_button_pressed || zoom_button_active )
{
zoom_button_pressed = false;
zoom_button_active = false;
drawTitleBar();
}
2015-05-23 13:35:12 +02:00
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::LeftButton )
2015-05-23 13:35:12 +02:00
{
bool has_raised;
2015-05-23 13:35:12 +02:00
// click on titlebar or window: raise + activate
if ( mouse_x >= 4 && mouse_x <= getWidth()-zoom_btn && mouse_y == 1 )
titlebar_click_pos.setPoint (ev->getTermX(), ev->getTermY());
2015-05-23 13:35:12 +02:00
else
titlebar_click_pos.setPoint (0,0);
2015-05-23 13:35:12 +02:00
has_raised = raiseWindow();
2015-05-23 13:35:12 +02:00
if ( ! isActiveWindow() )
2016-07-25 23:50:57 +02:00
activateDialog();
2015-05-23 13:35:12 +02:00
if ( has_raised )
redraw();
2016-06-12 23:06:58 +02:00
// click on titlebar menu button
if ( mouse_x < 4 && mouse_y == 1 )
openMenu();
else if ( mouse_x > getWidth()-zoom_btn && mouse_y == 1 )
{
zoom_button_pressed = true;
zoom_button_active = true;
drawTitleBar();
}
// click on the lower right resize corner
if ( isResizeable()
&& ( (mouse_x == getWidth() && mouse_y == getHeight())
|| (mouse_x == getWidth()-1 && mouse_y == getHeight())
|| (mouse_x == getWidth() && mouse_y == getHeight()-1) ) )
{
resize_click_pos = ev->getTermPos();
FPoint lower_right_pos = getTermGeometry().getLowerRightPos();
if ( ev->getTermPos() != lower_right_pos )
{
FPoint deltaPos = ev->getTermPos() - lower_right_pos;
int w = lower_right_pos.getX() + deltaPos.getX() - getTermX() + 1;
int h = lower_right_pos.getY() + deltaPos.getY() - getTermY() + 1;
setSize (w, h);
}
else
drawBorder();
}
else
resize_click_pos.setPoint (0,0);
2016-06-12 23:06:58 +02:00
}
else // ev->getButton() != fc::LeftButton
{
// click on titlebar menu button
if ( mouse_x < 4 && mouse_y == 1 && dialog_menu->isVisible() )
2016-06-13 22:44:15 +02:00
leaveMenu(); // close menu
// cancel resize
if ( ! resize_click_pos.isNull() )
{
resize_click_pos.setPoint (0,0);
drawBorder();
updateTerminal();
}
2015-05-23 13:35:12 +02:00
}
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton )
2015-05-23 13:35:12 +02:00
{
// click on titlebar: just activate
if ( mouse_x >= 4 && mouse_x <= getWidth() && mouse_y == 1 )
2015-05-23 13:35:12 +02:00
{
if ( ! isActiveWindow() )
2016-07-25 23:50:57 +02:00
activateDialog();
2015-05-23 13:35:12 +02:00
}
}
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::MiddleButton )
2015-05-23 13:35:12 +02:00
{
// click on titlebar: lower + activate
if ( mouse_x >= 4 && mouse_x <= getWidth() && mouse_y == 1 )
2015-05-23 13:35:12 +02:00
{
bool has_lowered = lowerWindow();
if ( ! isActiveWindow() )
2016-07-25 23:50:57 +02:00
activateDialog();
else if ( has_lowered )
2015-05-23 13:35:12 +02:00
updateTerminal();
}
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FDialog::onMouseUp (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int zoom_btn;
if ( ! isResizeable() )
zoom_btn = 0;
else if ( isNewFont() )
zoom_btn = 2;
else
zoom_btn = 3;
2015-05-23 13:35:12 +02:00
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::LeftButton )
2015-05-23 13:35:12 +02:00
{
int mouse_x = ev->getX();
int mouse_y = ev->getY();
int titlebar_x = titlebar_click_pos.getX();
int titlebar_y = titlebar_click_pos.getY();
2016-06-12 23:06:58 +02:00
if ( ! titlebar_click_pos.isNull()
&& titlebar_x > getTermX() + 3
&& titlebar_x < getTermX() + getWidth()
&& titlebar_y == getTermY() )
2015-05-23 13:35:12 +02:00
{
FPoint currentPos(getGeometry().getX(), getGeometry().getY());
FPoint deltaPos = ev->getTermPos() - titlebar_click_pos;
2015-05-23 13:35:12 +02:00
move (currentPos + deltaPos);
titlebar_click_pos = ev->getTermPos();
2015-05-23 13:35:12 +02:00
}
2016-06-12 23:06:58 +02:00
// click on titlebar menu button
if ( mouse_x < 4
&& mouse_y == 1
&& dialog_menu->isVisible()
&& ! dialog_menu->hasSelectedItem() )
{
// Sets focus to the first item
selectFirstMenuItem();
2016-06-12 23:06:58 +02:00
}
else if ( mouse_x > getWidth() - zoom_btn
&& mouse_y == 1
&& zoom_button_pressed )
{
// zoom to maximum or restore the window size
zoomWindow();
setZoomItem();
}
// resize the dialog
if ( isResizeable() && ! resize_click_pos.isNull() )
{
FWidget* r = getRootWidget();
resize_click_pos = ev->getTermPos();
int x2 = resize_click_pos.getX();
int y2 = resize_click_pos.getY();
int x2_offset = 0;
int y2_offset = 0;
if ( r )
{
x2_offset = r->getLeftPadding();
y2_offset = r->getTopPadding();
}
if ( ev->getTermPos() != getTermGeometry().getLowerRightPos() )
{
int w, h;
FPoint deltaPos = ev->getTermPos() - resize_click_pos;
if ( x2 - x2_offset <= getMaxWidth() )
w = resize_click_pos.getX() + deltaPos.getX() - getTermX() + 1;
else
w = getMaxWidth() - getTermX() + x2_offset + 1;
if ( y2 - y2_offset <= getMaxHeight() )
h = resize_click_pos.getY() + deltaPos.getY() - getTermY() + 1;
else
h = getMaxHeight() - getTermY() + y2_offset + 1;
setSize (w, h);
}
// reset the border color
resize_click_pos.setPoint (0,0);
// redraw() is required to draw the standard (black) border
// and client objects with ignorePadding() option.
redraw();
}
}
if ( zoom_button_pressed || zoom_button_active )
{
zoom_button_pressed = false;
zoom_button_active = false;
drawTitleBar();
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FDialog::onMouseMove (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int zoom_btn;
if ( ! isResizeable() )
zoom_btn = 0;
else if ( isNewFont() )
zoom_btn = 2;
else
zoom_btn = 3;
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::LeftButton )
2015-05-23 13:35:12 +02:00
{
int mouse_x = ev->getX();
int mouse_y = ev->getY();
if ( ! titlebar_click_pos.isNull() )
2015-05-23 13:35:12 +02:00
{
FPoint currentPos(getGeometry().getX(), getGeometry().getY());
FPoint deltaPos = ev->getTermPos() - titlebar_click_pos;
2015-05-23 13:35:12 +02:00
move (currentPos + deltaPos);
titlebar_click_pos = ev->getTermPos();
2015-05-23 13:35:12 +02:00
}
2016-06-12 23:06:58 +02:00
if ( dialog_menu->isVisible() && dialog_menu->isShown() )
{
// Mouse event handover to the menu
const FRect& menu_geometry = dialog_menu->getTermGeometry();
2016-06-13 22:44:15 +02:00
2016-06-12 23:06:58 +02:00
if ( dialog_menu->count() > 0
&& menu_geometry.contains(ev->getTermPos()) )
2016-06-12 23:06:58 +02:00
{
const FPoint& g = ev->getTermPos();
const FPoint& p = dialog_menu->termToWidgetPos(g);
2016-06-12 23:06:58 +02:00
int b = ev->getButton();
FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, g, b);
dialog_menu->mouse_down = true;
setClickedWidget(dialog_menu);
dialog_menu->onMouseMove(_ev);
delete _ev;
}
}
if ( mouse_x > getWidth() - zoom_btn && mouse_y == 1 && zoom_button_active )
zoom_button_pressed = true;
else if ( zoom_button_pressed )
zoom_button_pressed = false;
drawTitleBar();
// resize the dialog
if ( isResizeable() && ! resize_click_pos.isNull()
&& ev->getTermPos() != getTermGeometry().getLowerRightPos() )
{
FWidget* r = getRootWidget();
resize_click_pos = ev->getTermPos();
int x2 = resize_click_pos.getX();
int y2 = resize_click_pos.getY();
int x2_offset = 0;
int y2_offset = 0;
if ( r )
{
x2_offset = r->getLeftPadding();
y2_offset = r->getTopPadding();
}
int w, h;
FPoint deltaPos = ev->getTermPos() - resize_click_pos;
if ( x2 - x2_offset <= getMaxWidth() )
w = resize_click_pos.getX() + deltaPos.getX() - getTermX() + 1;
else
w = getMaxWidth() - getTermX() + x2_offset + 1;
if ( y2 - y2_offset <= getMaxHeight() )
h = resize_click_pos.getY() + deltaPos.getY() - getTermY() + 1;
else
h = getMaxHeight() - getTermY() + y2_offset + 1;
setSize (w, h);
}
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FDialog::onMouseDoubleClick (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int x, y, mouse_x, mouse_y, zoom_btn;
2015-05-23 13:35:12 +02:00
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton )
2015-05-23 13:35:12 +02:00
return;
mouse_x = ev->getX();
mouse_y = ev->getY();
if ( ! isResizeable() )
zoom_btn = 0;
else if ( isNewFont() )
zoom_btn = 2;
else
zoom_btn = 3;
x = getTermX();
y = getTermY();
2015-05-23 13:35:12 +02:00
FRect title_button(x, y, 3, 1);
FPoint tPos = ev->getTermPos();
if ( title_button.contains(tPos) )
2015-05-23 13:35:12 +02:00
{
// double click on title button
FWidget* window_focus_widget;
2016-06-12 23:06:58 +02:00
dialog_menu->unselectItem();
dialog_menu->hide();
activateWindow();
raiseWindow();
window_focus_widget = getWindowFocusWidget();
if ( window_focus_widget )
window_focus_widget->setFocus();
2015-05-23 13:35:12 +02:00
setClickedWidget(0);
2016-06-12 23:06:58 +02:00
if ( isModal() )
done (FDialog::Reject);
2016-06-12 23:06:58 +02:00
else
close();
2015-05-23 13:35:12 +02:00
}
else if ( isResizeable()
&& mouse_x >= 4
&& mouse_x <= getWidth() - zoom_btn
&& mouse_y == 1 )
{
// double click on titlebar
zoomWindow(); // window zoom/unzoom
setZoomItem();
}
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::onAccel (FAccelEvent*)
{
if ( ! (isHiddenWindow() || isActiveWindow()) )
{
2016-07-25 23:50:57 +02:00
bool has_raised = raiseWindow();
activateDialog();
2016-07-25 23:50:57 +02:00
if ( has_raised )
redraw();
2016-07-25 23:50:57 +02:00
updateTerminal();
}
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
void FDialog::onWindowActive (FEvent*)
{
if ( isVisible() && isShown() )
drawTitleBar();
if ( ! FWidget::getFocusWidget() )
2015-05-23 13:35:12 +02:00
{
FWidget* win_focus = getWindowFocusWidget();
if ( win_focus
&& win_focus->isVisible()
&& win_focus->isShown() )
{
win_focus->setFocus();
win_focus->redraw();
}
else
focusFirstChild();
2015-05-23 13:35:12 +02:00
}
if ( statusBar() )
statusBar()->drawMessage();
updateTerminal();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::onWindowInactive (FEvent*)
{
if ( dialog_menu && ! dialog_menu->isVisible() )
FWindow::previous_widget = this;
2015-05-23 13:35:12 +02:00
if ( isVisible() && isEnabled() )
drawTitleBar();
if ( hasFocus() )
unsetFocus();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::onWindowRaised (FEvent*)
{
if ( ! (isVisible() && isShown()) )
2015-09-15 23:07:24 +02:00
return;
putArea (getTermPos(), vwin);
2015-05-23 13:35:12 +02:00
// handle always-on-top windows
if ( always_on_top_list && ! always_on_top_list->empty() )
{
widgetList::const_iterator iter, end;
iter = always_on_top_list->begin();
end = always_on_top_list->end();
while ( iter != end )
{
putArea ((*iter)->getTermPos(), (*iter)->getVWin());
++iter;
}
}
2015-05-23 13:35:12 +02:00
if ( ! window_list )
return;
2015-05-23 13:35:12 +02:00
if ( window_list->empty() )
return;
}
//----------------------------------------------------------------------
void FDialog::onWindowLowered (FEvent*)
{
widgetList::const_iterator iter, end;
if ( ! window_list )
return;
2015-05-23 13:35:12 +02:00
if ( window_list->empty() )
return;
iter = window_list->begin();
end = window_list->end();
while ( iter != end )
{
putArea ((*iter)->getTermPos(), (*iter)->getVWin());
2015-05-23 13:35:12 +02:00
++iter;
}
}
//----------------------------------------------------------------------
void FDialog::show()
{
if ( ! isVisible() )
return;
FWindow::show();
2015-05-23 13:35:12 +02:00
// set the cursor to the focus widget
FWidget* focus_widget = FWidget::getFocusWidget();
if ( focus_widget
&& focus_widget->isVisible()
&& focus_widget->hasVisibleCursor()
&& focus_widget->isCursorInside() )
2015-05-23 13:35:12 +02:00
{
focus_widget->setCursor();
2015-05-23 13:35:12 +02:00
showCursor();
flush_out();
}
if ( isModal() )
{
FApplication* fapp = static_cast<FApplication*>(getRootWidget());
fapp->enter_loop();
if ( this == getMainWidget() )
fapp->quit();
}
}
//----------------------------------------------------------------------
void FDialog::hide()
{
FWindow::hide();
2015-05-23 13:35:12 +02:00
if ( isModal() )
{
FApplication* fapp = static_cast<FApplication*>(getRootWidget());
fapp->exit_loop();
}
}
//----------------------------------------------------------------------
int FDialog::exec()
{
result_code = FDialog::Reject;
show();
return result_code;
}
//----------------------------------------------------------------------
void FDialog::move (const FPoint& pos)
{
move ( pos.getX(), pos.getY() );
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FDialog::move (int x, int y)
{
int dx, dy, old_x, old_y, rsw, bsh, width, height;
FRect old_geometry;
2015-05-23 13:35:12 +02:00
if ( getX() == x && getY() == y )
2015-05-23 13:35:12 +02:00
return;
width = getWidth();
height = getHeight();
// Avoid to move widget completely outside the terminal
if ( x+width-1 < 1 || x > getMaxWidth() || y < 1 || y > getMaxHeight() )
2015-05-23 13:35:12 +02:00
return;
if ( isZoomed() )
return;
dx = getX() - x;
dy = getY() - y;
old_x = getTermX();
old_y = getTermY();
const FPoint& shadow = getShadow();
rsw = shadow.getX(); // right shadow width;
bsh = shadow.getY(); // bottom shadow height
old_geometry = getTermGeometryWithShadow();
2015-05-23 13:35:12 +02:00
// move to the new position
2015-05-23 13:35:12 +02:00
FWidget::move(x,y);
setPos(x, y, false);
putArea (getTermPos(), vwin);
2015-05-23 13:35:12 +02:00
// restoring the non-covered terminal areas
if ( getTermGeometry().overlap(old_geometry) )
2015-05-23 13:35:12 +02:00
{
// dx > 0 : move left
// dx = 0 : move vertical
// dx < 0 : move right
// dy > 0 : move up
// dy = 0 : move horizontal
// dy < 0 : move down
if ( dx > 0 )
{
if ( dy > 0 )
restoreVTerm (old_x+width+rsw-dx, old_y, dx, getHeight()+bsh-dy);
2015-05-23 13:35:12 +02:00
else
restoreVTerm (old_x+width+rsw-dx, old_y+abs(dy), dx, height+bsh-abs(dy));
2015-05-23 13:35:12 +02:00
}
else
{
if ( dy > 0 )
restoreVTerm (old_x, old_y, abs(dx), height+bsh-dy);
2015-05-23 13:35:12 +02:00
else
restoreVTerm (old_x, old_y+abs(dy), abs(dx), height+bsh-abs(dy));
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
if ( dy > 0 )
restoreVTerm (old_x, old_y+height+bsh-dy, width+rsw, dy);
2015-05-23 13:35:12 +02:00
else
restoreVTerm (old_x, old_y, width+rsw, abs(dy));
2015-05-23 13:35:12 +02:00
}
else
{
restoreVTerm (old_geometry);
2015-05-23 13:35:12 +02:00
}
// handle overlaid windows
if ( window_list && ! window_list->empty() )
{
bool overlaid = false;
widgetList::const_iterator iter, end;
iter = window_list->begin();
end = window_list->end();
while ( iter != end )
{
if ( overlaid )
putArea ((*iter)->getTermPos(), (*iter)->getVWin());
2015-05-23 13:35:12 +02:00
if ( vwin == (*iter)->getVWin() )
overlaid = true;
2015-05-23 13:35:12 +02:00
++iter;
}
}
FWidget::adjustSize();
// set the cursor to the focus widget
FWidget* focus_widget = FWidget::getFocusWidget();
if ( focus_widget
&& focus_widget->isVisible()
&& focus_widget->hasVisibleCursor() )
2015-05-23 13:35:12 +02:00
{
FPoint cursor_pos = focus_widget->getCursorPos();
if ( ! focus_widget->setCursorPos(cursor_pos) )
2015-05-23 13:35:12 +02:00
hideCursor();
}
2015-05-23 13:35:12 +02:00
updateTerminal();
}
//----------------------------------------------------------------------
void FDialog::setSize (int w, int h, bool adjust)
{
int x, y, dw, dh, old_width, old_height, rsw, bsh;
if ( getWidth() == w && getHeight() == h )
return;
if ( isZoomed() )
return;
x = getTermX();
y = getTermY();
old_width = getWidth();
old_height = getHeight();
dw = old_width - w;
dh = old_height - h;
const FPoint& shadow = getShadow();
rsw = shadow.getX(); // right shadow width;
bsh = shadow.getY(); // bottom shadow height
FWindow::setSize (w, h, adjust);
// get adjust width and height
w = getWidth();
h = getHeight();
// dw > 0 : scale down width
// dw = 0 : scale only height
// dw < 0 : scale up width
// dh > 0 : scale down height
// dh = 0 : scale only width
// dh < 0 : scale up height
// restoring the non-covered terminal areas
if ( dw > 0 )
restoreVTerm (x+w+rsw, y, dw, h+bsh+dh); // restore right
if ( dh > 0 )
restoreVTerm (x, y+h+bsh, w+rsw+dw, dh); // restore bottom
redraw();
// handle overlaid windows
if ( window_list && ! window_list->empty() )
{
bool overlaid = false;
widgetList::const_iterator iter, end;
iter = window_list->begin();
end = window_list->end();
while ( iter != end )
{
if ( overlaid )
putArea ((*iter)->getTermPos(), (*iter)->getVWin());
if ( vwin == (*iter)->getVWin() )
overlaid = true;
++iter;
}
}
// set the cursor to the focus widget
FWidget* focus_widget = FWidget::getFocusWidget();
if ( focus_widget
&& focus_widget->isVisible()
&& focus_widget->hasVisibleCursor() )
{
FPoint cursor_pos = focus_widget->getCursorPos();
if ( ! focus_widget->setCursorPos(cursor_pos) )
hideCursor();
}
}
2016-07-25 23:50:57 +02:00
//----------------------------------------------------------------------
void FDialog::activateDialog()
{
FWidget* old_focus = FWidget::getFocusWidget();
FWidget* win_focus = getWindowFocusWidget();
2016-07-25 23:50:57 +02:00
setActiveWindow(this);
2016-07-28 23:38:17 +02:00
setFocus();
setFocusWidget(this);
2016-07-25 23:50:57 +02:00
if ( win_focus && numOfFocusableChildren() > 1 )
2016-07-25 23:50:57 +02:00
{
win_focus->setFocus();
win_focus->redraw();
2016-07-25 23:50:57 +02:00
if ( old_focus )
old_focus->redraw();
}
else if ( old_focus )
{
if ( ! focusFirstChild() )
old_focus->unsetFocus();
if ( ! old_focus->isWindowWidget() )
2016-07-31 22:49:09 +02:00
old_focus->redraw();
2016-07-25 23:50:57 +02:00
}
if ( statusBar() )
statusBar()->drawMessage();
updateTerminal();
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FDialog::setFocus (bool on)
{
FWidget::setFocus(on);
if ( on )
2016-01-24 14:53:09 +01:00
flags |= fc::focus;
2015-05-23 13:35:12 +02:00
else
2016-01-24 14:53:09 +01:00
flags &= ~fc::focus;
2015-05-23 13:35:12 +02:00
return on;
}
//----------------------------------------------------------------------
bool FDialog::setDialogWidget (bool on)
{
if ( isDialogWidget() == on )
return true;
if ( on )
{
flags |= fc::dialog_widget;
setTermOffsetWithPadding();
}
else
{
flags &= ~fc::dialog_widget;
setParentOffset();
}
return on;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FDialog::setModal (bool on)
{
if ( isModal() == on )
return true;
if ( on )
{
2016-01-24 14:53:09 +01:00
flags |= fc::modal;
2015-05-23 13:35:12 +02:00
modal_dialogs++;
}
else
{
2016-01-24 14:53:09 +01:00
flags &= ~fc::modal;
2015-05-23 13:35:12 +02:00
modal_dialogs--;
}
2015-05-23 13:35:12 +02:00
return on;
}
//----------------------------------------------------------------------
bool FDialog::setTransparentShadow (bool on)
{
if ( on )
{
2016-01-24 14:53:09 +01:00
flags |= fc::shadow;
flags |= fc::trans_shadow;
setShadowSize (2,1);
2015-05-23 13:35:12 +02:00
}
else
{
2016-01-24 14:53:09 +01:00
flags &= ~fc::shadow;
flags &= ~fc::trans_shadow;
setShadowSize (0,0);
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
resizeArea (vwin);
return on;
}
//----------------------------------------------------------------------
bool FDialog::setShadow (bool on)
{
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
return false;
2015-05-23 13:35:12 +02:00
if ( on )
{
2016-01-24 14:53:09 +01:00
flags |= fc::shadow;
flags &= ~fc::trans_shadow;
setShadowSize (1,1);
2015-05-23 13:35:12 +02:00
}
else
{
2016-01-24 14:53:09 +01:00
flags &= ~fc::shadow;
flags &= ~fc::trans_shadow;
setShadowSize (0,0);
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
resizeArea (vwin);
return on;
}
//----------------------------------------------------------------------
bool FDialog::setScrollable (bool on)
{
if ( on )
2016-01-24 14:53:09 +01:00
flags |= fc::scrollable;
2015-05-23 13:35:12 +02:00
else
2016-01-24 14:53:09 +01:00
flags &= ~fc::scrollable;
2015-05-23 13:35:12 +02:00
return on;
}
//----------------------------------------------------------------------
bool FDialog::setResizeable (bool on)
{
if ( on )
{
2016-01-24 14:53:09 +01:00
flags |= fc::resizeable;
zoom_item->setEnable();
}
2015-05-23 13:35:12 +02:00
else
{
2016-01-24 14:53:09 +01:00
flags &= ~fc::resizeable;
zoom_item->setDisable();
}
2015-05-23 13:35:12 +02:00
return on;
}