note description: "Main window for downloader application." documentation: "[ Allows to download file via net. The download is asynchronous and can be cancelled at any moment. Displays the downloaded size. ]" author: "Alexey Kolesnichenko, Roman Schmocker" updated_by: "Alexander Kogtenkov" date: "$Date$" revision: "2.0.0" class MAIN_WINDOW inherit EV_TITLED_WINDOW redefine create_interface_objects end create make feature {NONE} -- Constants Window_title: STRING = "Downloader" Window_width: INTEGER = 400 -- Initial width for this window. Window_height: INTEGER = 400 -- Initial height for this window. Border_margin: INTEGER = 5 Margin: INTEGER = 15 feature {NONE} -- Initialization make (a_executor: like executor) -- Initialize `Current' with an executor. do executor := a_executor create formatter.make (5,2) default_create -- Build the window layout. build_main_container extend (main_container) -- Set the title of the window set_title (Window_title) -- Set the initial size of the window set_size (Window_width, main_container.height) -- Attach the correct actions to all buttons. download_button.select_actions.extend (agent on_download_button_clicked) cancel_button.select_actions.extend (agent on_cancel_button_clicked) close_request_actions.extend (agent destroy_and_exit_if_last) end create_interface_objects -- do create main_container create status_text status_text.set_text ("No download in progress.") status_text.align_text_left create standard_status_bar standard_status_bar.set_border_width (2) standard_status_bar.extend (status_text) create download_button.make_with_text ("Start download") create cancel_button.make_with_text ("Cancel download") create url_text.make_with_text ("http://download.thinkbroadband.com/50MB.zip") create result_text.make_with_text ("") end build_main_container -- Define the layout of the main container. do lock_update download_button.set_minimum_width (140) cancel_button.set_minimum_width (140) url_text.set_minimum_width (((window_width / 2) * 2).truncated_to_integer) result_text.set_minimum_width (url_text.width - download_button.width - margin) result_text.disable_edit main_container.extend (download_button) main_container.extend (cancel_button) main_container.extend (url_text) main_container.extend (result_text) main_container.set_item_y_position (url_text, 30) main_container.set_item_x_position (url_text, border_margin) main_container.set_item_y_position (download_button, url_text.y_position + url_text.height + margin) main_container.set_item_x_position (download_button, border_margin) main_container.set_item_y_position (cancel_button, download_button.y_position + download_button.height + margin) main_container.set_item_x_position (cancel_button, border_margin) main_container.set_item_y_position (result_text, download_button.y_position) main_container.set_item_x_position (result_text, download_button.width + download_button.x_position + margin) main_container.extend (standard_status_bar) main_container.set_item_position (standard_status_bar, border_margin, main_container.height + margin) unlock_update end feature {NONE} -- UI elements main_container: EV_FIXED -- Main container which contains all widgets displayed in the window. standard_status_bar: EV_STATUS_BAR download_button: EV_BUTTON cancel_button: EV_BUTTON status_text: EV_LABEL url_text: EV_TEXT_FIELD result_text: EV_TEXT_FIELD feature -- Access executor: CP_EXECUTOR_PROXY -- An executor to submit background tasks to. download_handle: detachable CP_PROMISE_PROXY -- A handle to a possible background download. formatter: FORMAT_DOUBLE -- A formatter for progress values. feature -- Status report is_cancelling: BOOLEAN -- Is the download about to terminate? feature {NONE} -- Button press events on_download_button_clicked -- Handler for clicks on download button. local downloader: DOWNLOAD_TASK l_promise: CP_PROMISE_PROXY do if not attached download_handle then create downloader.make (url_text.text) l_promise := executor.new_promise download_handle := l_promise l_promise.change_event.subscribe (agent on_change) downloader.set_promise (l_promise.subject) executor.put (downloader) end end on_cancel_button_clicked -- Handler for clicks on cancel button. do if not is_cancelling and attached download_handle as l_download then l_download.cancel is_cancelling := True status_text.set_text ("Cancelling download...") end end feature {NONE} -- Background download events on_change -- Handler for change notifications generated by the download task. do if attached download_handle as l_handle then if l_handle.is_terminated then if l_handle.is_exceptional then result_text.set_text ("Download aborted.") elseif is_cancelling then result_text.set_text ("Download cancelled.") is_cancelling := False else result_text.set_text ("Download finished.") end download_handle := Void status_text.set_text ("No download in progress.") elseif not is_cancelling then status_text.set_text ("Download progress:" + formatter.formatted (l_handle.progress * 100) + "%%") end end end end