Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CloseEvent to DockItem #303

Merged
merged 5 commits into from
Aug 29, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion enaml/qt/qt_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from atom.api import Typed, atomref

from enaml.widgets.dialog import ProxyDialog
from enaml.widgets.window import CloseEvent
from enaml.widgets.close_event import CloseEvent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there. This is the last one that's out of order.


from .QtCore import Qt
from .QtWidgets import QDialog
Expand Down
10 changes: 9 additions & 1 deletion enaml/qt/qt_dock_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from atom.api import Int, Typed

from enaml.styling import StyleCache
from enaml.widgets.close_event import CloseEvent
from enaml.widgets.dock_item import ProxyDockItem

from .QtCore import Qt, QSize, Signal
Expand All @@ -30,8 +31,14 @@ class QCustomDockItem(QDockItem):

def closeEvent(self, event):
""" Handle the close event for the dock item.

"""
d_event = CloseEvent()
d = self._proxy_ref.declaration
d.closing(d_event)
if not d_event.is_accepted():
event.ignore()
return

super(QCustomDockItem, self).closeEvent(event)
if event.isAccepted():
self.closed.emit()
Expand Down Expand Up @@ -59,6 +66,7 @@ def create_widget(self):

"""
self.widget = QCustomDockItem(self.parent_widget())
self.widget._proxy_ref = self

def init_widget(self):
""" Initialize the state of the underlying widget.
Expand Down
2 changes: 1 addition & 1 deletion enaml/qt/qt_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from atom.api import Typed, atomref

from enaml.widgets.main_window import ProxyMainWindow
from enaml.widgets.window import CloseEvent
from enaml.widgets.close_event import CloseEvent

from .QtCore import Qt
from .QtWidgets import QMainWindow
Expand Down
3 changes: 2 additions & 1 deletion enaml/qt/qt_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
from atom.api import Typed, atomref

from enaml.layout.geometry import Pos, Rect, Size
from enaml.widgets.window import ProxyWindow, CloseEvent
from enaml.widgets.window import ProxyWindow
from enaml.widgets.close_event import CloseEvent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

close_event should be imported before window to maintain sort order. /pedantry


from .QtCore import Qt, QPoint, QRect, QSize
from .QtGui import QIcon
Expand Down
35 changes: 35 additions & 0 deletions enaml/widgets/close_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from atom.api import Atom, Bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file needs a copyright header.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is always a bit unclear to me but can the copyright mention 2013 when the file was created only in 2018 ?



class CloseEvent(Atom):
""" An payload object carried by a widget 'closing' event.

User code can manipulate this object to veto a close event.

"""
#: The internal accepted state.
_accepted = Bool(True)

def is_accepted(self):
""" Get whether or not the event is accepted.

Returns
-------
result : bool
True if the event is accepted, False otherwise. The
default is True.

"""
return self._accepted

def accept(self):
""" Accept the close event and allow the widget to be closed.

"""
self._accepted = True

def ignore(self):
""" Reject the close event and prevent the widget from closing.

"""
self._accepted = False
8 changes: 8 additions & 0 deletions enaml/widgets/dock_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from enaml.icon import Icon
from enaml.layout.geometry import Size

from .close_event import CloseEvent
from .container import Container
from .widget import Widget, ProxyWidget

Expand Down Expand Up @@ -81,6 +82,13 @@ class DockItem(Widget):
#: An event emitted when the title bar is right clicked.
title_bar_right_clicked = d_(Event(), writable=False)

#: An event fired when the user request the dock item to be closed.
#: This will happen when the user clicks on the "X" button in the
#: title bar button, or when the 'close' method is called. The
#: payload will be a CloseEvent object which will allow code to
#: veto the close event and prevent the item from closing.
closing = d_(Event(CloseEvent), writable=False)

#: An event emitted when the dock item is closed. The item will be
#: destroyed after this event has completed.
closed = d_(Event(), writable=False)
Expand Down
35 changes: 1 addition & 34 deletions enaml/widgets/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from enaml.layout.geometry import Pos, Rect, Size

from .container import Container
from .close_event import CloseEvent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be imported before .container to maintain sort order.

from .widget import Widget, ProxyWidget


Expand Down Expand Up @@ -89,40 +90,6 @@ def close(self):
raise NotImplementedError


class CloseEvent(Atom):
""" An payload object carried by a window 'closing' event.

User code can manipulate this object to veto a close event.

"""
#: The internal accepted state.
_accepted = Bool(True)

def is_accepted(self):
""" Get whether or not the event is accepted.

Returns
-------
result : bool
True if the event is accepted, False otherwise. The
default is True.

"""
return self._accepted

def accept(self):
""" Accept the close event and allow the window to be closed.

"""
self._accepted = True

def ignore(self):
""" Reject the close event and prevent the window from closing.

"""
self._accepted = False


class Window(Widget):
""" A top-level Window component.

Expand Down
13 changes: 13 additions & 0 deletions examples/widgets/dock_area.enaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ from enaml.layout.api import (
HSplitLayout, VSplitLayout, TabLayout, InsertItem, hbox, vbox, spacer
)
from enaml.stdlib.dock_area_styles import available_styles
from enaml.stdlib.message_box import question
from enaml.widgets.api import (
Window, Container, DockArea, DockItem, PushButton, Field, Html, Slider,
ObjectCombo, CheckBox, MultilineField
Expand All @@ -31,6 +32,16 @@ def cap_case(name):
return ' '.join(s.capitalize() for s in name.split('-'))


def confirm_close(window, event):
button = question(
window, 'Dock item closing', 'Are you sure you want to close this dock item?'
)
if button and button.action == 'accept':
event.accept()
else:
event.ignore()


class LineCollector(Atom):
""" A simple class used to generate event logging text.

Expand Down Expand Up @@ -87,6 +98,8 @@ enamldef MyDockArea(DockArea):
Field: pass
Field: pass
Field: pass
closing ::
confirm_close(self, change['value'])
DockItem:
name = 'item_2'
title = 'Item 2'
Expand Down