note description: " EiffelVision Toolbar button, mswindows implementation." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class EV_TOOL_BAR_BUTTON_IMP inherit EV_TOOL_BAR_BUTTON_I redefine interface end EV_TOOL_BAR_ITEM_IMP undefine parent redefine set_pixmap, interface, pixmap, remove_pixmap, destroy end EV_INTERNALLY_PROCESSED_TEXTABLE_IMP redefine interface end EV_DOCKABLE_SOURCE_IMP redefine interface end EV_TOOLTIPABLE_IMP redefine interface, set_tooltip end WEL_ILC_CONSTANTS EV_TOOL_BAR_BUTTON_ACTION_SEQUENCES_I create make feature {NONE} -- pointer_style: detachable EV_POINTER_STYLE -- do end wel_has_capture: BOOLEAN -- do end feature -- Initialization old_make (an_interface: attached like interface) -- Create `Current' with interface `an_interface'. do assign_interface (an_interface) end make -- Do post creation initialization. do make_id create real_text.make (0) is_sensitive := True set_is_initialized (True) end parent_imp: detachable EV_TOOL_BAR_IMP -- The parent of `Current'. feature -- Access wel_text: STRING_32 -- Text of `Current' do if attached real_text as l_real_text then Result := l_real_text.twin else create Result.make_empty end end text_length: INTEGER -- Number of characters of `real_text'. do if attached real_text as l_real_text then Result := l_real_text.count end end real_text: detachable STRING_32 -- Internal `text'. Not to be returned directly. Use clone. index: INTEGER -- Index of the current item. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.internal_get_index (Current) + 1 end end set_parent_imp (a_parent_imp: like parent_imp) -- Make `a_parent_imp' the new parent of `Current'. -- `a_parent_imp' can be Void then the parent is the screen. do if a_parent_imp /= Void then parent_imp := a_parent_imp a_parent_imp.auto_size else parent_imp := Void end end gray_pixmap: detachable EV_PIXMAP -- Pixmap of `Current'. local pix_imp: detachable EV_PIXMAP_IMP image_icon: WEL_ICON image_list: EV_IMAGE_LIST_IMP do -- Retrieve the pixmap from the imagelist if has_gray_pixmap then if private_gray_pixmap = Void then create Result pix_imp ?= Result.implementation check pix_imp /= Void then end if attached parent_imp as l_parent_imp and then attached l_parent_imp.default_imagelist as l_default_imagelist then image_list := l_default_imagelist image_icon := l_default_imagelist.get_icon (image_index, Ild_normal) pix_imp.set_with_resource (image_icon) else check False end end else Result := private_gray_pixmap end end end pixmap: detachable EV_PIXMAP -- Pixmap of `Current'. local pix_imp: detachable EV_PIXMAP_IMP an_icon: WEL_ICON do -- Retrieve the pixmap from the imagelist if has_pixmap then if private_pixmap = Void then create Result pix_imp ?= Result.implementation check pix_imp /= Void then end if attached parent_imp as l_parent_imp and then attached l_parent_imp.hot_imagelist as l_hot_imagelist then an_icon := l_hot_imagelist.get_icon (image_index, Ild_normal) an_icon.enable_reference_tracking pix_imp.set_with_resource (an_icon) an_icon.decrement_reference else check False end end else Result := private_pixmap end end end feature -- Status report is_sensitive: BOOLEAN -- Is `Current' sensitive? has_pixmap: BOOLEAN -- Has Current a pixmap? has_gray_pixmap: BOOLEAN -- Has Current a gray pixmap? feature -- Status setting enable_sensitive -- Enable `Current'. do is_sensitive := True if attached parent_imp as l_parent_imp then l_parent_imp.enable_button (id) end end disable_sensitive -- Disable `Current'. do is_sensitive := False if attached parent_imp as l_parent_imp then l_parent_imp.disable_button (id) end end parent_is_sensitive: BOOLEAN -- Is parent of `Current' sensitive? do if attached parent_imp as l_parent_imp and then l_parent_imp.is_sensitive then Result := True end end has_parent: BOOLEAN -- Is `Current' parented? do if parent_imp /= Void then result := True end end set_tooltip (a_tooltip: READABLE_STRING_GENERAL) -- Assign `a_tooltip' to `internal_tooltip_string'. do internal_tooltip_string := a_tooltip.as_string_32 if internal_tooltip_string = a_tooltip then internal_tooltip_string := a_tooltip.as_string_32.string end end feature -- Element change wel_set_text (txt: READABLE_STRING_GENERAL) -- Make `txt' the new label of `Current'. do if txt /= Void then real_text := txt.as_string_32.twin end if attached parent_imp as l_parent_imp then l_parent_imp.internal_reset_button (Current) l_parent_imp.auto_size end end set_pixmap (p: EV_PIXMAP) -- Assign `p' to the displayed pixmap. do -- We must destroy the pixmap before we set a new one, -- to ensure that we free up Windows GDI objects if attached private_pixmap as l_private_pixmap then l_private_pixmap.destroy private_pixmap := Void end private_pixmap := p.twin has_pixmap := True -- If the item is currently contained in the toolbar then if attached parent_imp as l_parent_imp then l_parent_imp.internal_reset_button (Current) end end remove_pixmap -- Remove pixmap from `Current'. do if has_pixmap then has_pixmap := False if attached private_pixmap as l_private_pixmap then l_private_pixmap.destroy private_pixmap := Void end -- If the item is currently contained in the toolbar then if attached parent_imp as l_parent_imp then l_parent_imp.internal_reset_button (Current) end end end set_gray_pixmap (p: EV_PIXMAP) -- Assign `p' to the displayed gray pixmap. local l_private_gray_pixmap: like private_gray_pixmap do l_private_gray_pixmap := private_gray_pixmap if l_private_gray_pixmap /= Void then l_private_gray_pixmap.destroy private_gray_pixmap := Void end create l_private_gray_pixmap l_private_gray_pixmap.copy (p) private_gray_pixmap := l_private_gray_pixmap has_gray_pixmap := True -- If the item is currently contained in the toolbar then if has_pixmap and attached parent_imp as l_parent_imp then l_parent_imp.internal_reset_button (Current) end end remove_gray_pixmap -- Remove pixmap from `Current'. do if has_gray_pixmap then has_gray_pixmap := False if attached private_gray_pixmap as l_private_gray_pixmap then l_private_gray_pixmap.destroy private_gray_pixmap := Void end -- If the item is currently contained in the toolbar then if attached parent_imp as l_parent_imp then l_parent_imp.internal_reset_button (Current) end end end set_pixmap_in_parent -- Add the pixmap to the parent by updating the -- parent's image list. local default_imagelist: detachable EV_IMAGE_LIST_IMP hot_imagelist: detachable EV_IMAGE_LIST_IMP local_pixmap: detachable EV_PIXMAP local_gray_pixmap: detachable EV_PIXMAP gray_pixmap_position: INTEGER pixmap_position: INTEGER l_parent_imp: like parent_imp l_private_pixmap: like private_pixmap do l_parent_imp := parent_imp check l_parent_imp /= Void then end default_imagelist := l_parent_imp.default_imagelist if l_parent_imp.has_false_image_list and has_pixmap then -- In this situation, a false image list is being used in `parent_imp' to -- ensure buttons are displayed at their minimum sizes. We remove this image -- list as `Current' has an image and we wish to use this with a new image list. l_parent_imp.remove_image_list default_imagelist := Void end l_private_pixmap := private_pixmap -- Create the image list and associate it -- to the control if it's not already done. if default_imagelist = Void then if has_pixmap then check l_private_pixmap /= Void then end l_parent_imp.setup_image_list (l_private_pixmap.width, l_private_pixmap.height) l_parent_imp.disable_false_image_list else -- Now set up an empty image list in `parent_imp' with a size 1x1. -- This ensures that when no pixmap is associated with an item, the button is -- approximately the size of the text only. l_parent_imp.enable_false_image_list l_parent_imp.setup_image_list (1, 1) default_imagelist := l_parent_imp.default_imagelist hot_imagelist := l_parent_imp.hot_imagelist image_index := -1 end end if private_pixmap = Void and private_gray_pixmap = Void then -- image_index is already up-to-date. else default_imagelist := l_parent_imp.default_imagelist hot_imagelist := l_parent_imp.hot_imagelist local_pixmap := private_pixmap if local_pixmap = Void then local_pixmap := pixmap end check local_pixmap /= Void then end if has_gray_pixmap then local_gray_pixmap := private_gray_pixmap if local_gray_pixmap = Void then local_gray_pixmap := gray_pixmap end else -- No gray pixmap, so both normal and hot state will -- have the same bitmap. local_gray_pixmap := local_pixmap end check local_gray_pixmap /= Void then end -- Look for `gray_pixmap' and `pixmap' in the imagelist check default_imagelist /= Void then end check hot_imagelist /= Void then end default_imagelist.pixmap_position (local_gray_pixmap) hot_imagelist.pixmap_position (local_pixmap) gray_pixmap_position := default_imagelist.last_position pixmap_position := hot_imagelist.last_position if pixmap_position = gray_pixmap_position and then pixmap_position /= -1 then -- Add pixmap. Take cached versions into account. default_imagelist.add_pixmap (local_gray_pixmap) hot_imagelist.add_pixmap (local_pixmap) else -- Add pixmap. Do not take cached versions into account. default_imagelist.extend_pixmap (local_gray_pixmap) hot_imagelist.extend_pixmap (local_pixmap) end check hot_and_default_imagelist_synchronized: default_imagelist.last_position = hot_imagelist.last_position end image_index := default_imagelist.last_position -- Destroy the pixmaps. check l_private_pixmap /= Void then end l_private_pixmap.destroy private_pixmap := Void if attached private_gray_pixmap as l_private_gray_pixmap then l_private_gray_pixmap.destroy private_gray_pixmap := Void end end end feature -- Measurement x_position: INTEGER -- Horizontal offset relative to parent `x_position' in pixels. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.child_x (attached_interface) end end y_position: INTEGER -- Vertical offset relative to parent `y_position' in pixels. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.child_y (attached_interface) end end screen_x: INTEGER -- Horizontal offset relative to screen. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.child_x_absolute (attached_interface) end end screen_y: INTEGER -- Vertical offset relative to screen. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.child_y_absolute (attached_interface) end end width: INTEGER -- Horizontal size in pixels. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.child_width (attached_interface) end end height: INTEGER -- Vertical size in pixels. do if attached parent_imp as l_parent_imp then Result := l_parent_imp.child_height (attached_interface) end end minimum_width: INTEGER -- Minimum horizontal size in pixels. do Result := width end minimum_height: INTEGER -- Minimum vertical size in pixels. do Result := height end feature {EV_TOOL_BAR_IMP} -- Implementation restore_private_pixmaps -- When `Current' is parented, `private_pixmap' and -- `private_gray_pixmap' are assigned Void. This is to stop -- us keeping to many references to GDI objects. When -- `Current' is removed from its parent, we must then -- restore them. do if has_pixmap then private_pixmap := pixmap end if has_gray_pixmap then private_gray_pixmap := gray_pixmap end end feature {NONE} -- Implementation private_gray_pixmap: detachable EV_PIXMAP -- Internal gray pixmap for Current. Void if none. destroy -- Destroy `Current'. do Precursor {EV_TOOL_BAR_ITEM_IMP} if attached private_pixmap as l_private_pixmap then l_private_pixmap.destroy end if attached private_gray_pixmap as l_private_gray_pixmap then l_private_gray_pixmap.destroy end end feature {NONE} -- Implementation, pick and drop widget_source: detachable EV_WIDGET_IMP -- Widget drag source used for transport. do Result := parent_imp end feature {EV_ANY, EV_ANY_I} -- Interface interface: detachable EV_TOOL_BAR_BUTTON note option: stable attribute end; note copyright: "Copyright (c) 1984-2018, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end