PR# 4042 EV_COMBO_BOX does not work as expected

Problem Report Summary
Submitter: ericbe
Category: EiffelVision
Priority: High
Date: 2004/09/21
Class: Bug
Severity: Critical
Number: 4042
Release: 5.5.0927
Confidential: No
Status: Analyzed
Responsible: misterieking
Environment: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.0.2) Gecko/20030208 Netscape/7.02
Synopsis: EV_COMBO_BOX does not work as expected

Description
I noticed that with EV_COMBO_BOX I don't have this popup side-effect that I have with EV_TEXT_FIELD when I drop a pebble on it, and it has the advantage of providing a history. So I switched to EV_COMBO_BOX but I got numerous problems, most of them apparently due to the fact that EV_COMBO_BOX is an EV_PRIMITIVE whereas EV_COMBO_BOX_IMP is made up of two children: the text field and the box.

1) First, EV_SCREEN.widget_at_position is broken. When the position passed as arguments is over the arrow box I get the EV_COMBO_BOX, but when it is over the text field I get Void. The fix is to add the local variable:

  internal_combo_field: EV_INTERNAL_COMBO_FIELD_IMP

to EV_SCREEN_IMP.widget_at_position and add the following code at the end of this routine:

  internal_combo_field ?= wel_point.window_at
  if internal_combo_field /= Void then
     Result := internal_combo_field.parent.interface
  end

It would also probably be good to put `wel_point.window_at' in a local variable once and for all before doing the assignment attempts.


2) When the focus is in the text field and I click on the arrow box the EV_COMBO_BOX loses the focus. The agents registered in:

  my_combo_box.focus_out_actions

are executed. This does not seem right to me. If it was a design decision to make EV_COMBO_BOX an atomic widget and not provide access to its text field and box subcomponents then the focus should not have been lost when clicking on the arrow box.

Furthermore, EV_APPLICATION.focused_window returns void! This is because `has_focus' in EV_COMBO_BOX_IMP looks like this:

   has_focus: BOOLEAN is
         -- Does `Current' have focus?
     do
         if text_field /= Void then
              Result := text_field.has_focus
         else
                  --| If `Current' is non editable, then there will be no
                  --| text field. This is the correct result in this case.
             Result := combo.has_focus
         end
     end

So if `text_field' is not void and the focus is on the box subcomponent then EiffelVision2 claims that no widget has the focus! Here again, if EV_COMBO_BOX has been designed to be atomic then the widget under focus should be the EV_COMBO_BOX when the focus is in fact on its box subcomponent.


3) I noticed that when typing text in the EV_COMBO_BOX the mouse cursor disappears. It reappears when we move the mouse. I experienced the same behavior with the combo boxes included in EiffelStudio. Furthermore, after calling:

  my_combo_box.enable_capture

the cursor not only disappears but does not reappear when moving the mouse. I had to explicitly display it again using an agent in:

  my_combo_box.pointer_motion_actions


4) After calling:

  my_combo_box.enable_capture

(and when the focus is on the text field) when typing text on the keyboard it is correctly displayed in the text field, however when using the mouse pointer to change the position of the cursor in the text field or when clicking on the arrow box nothing happens. But agents in:

  my_combo_box.pointer_button_press_actions

are executed. So here again it seems to be a problem with the fact that EV_COMBO_BOX_IMP is made up of subcomponents whereas EV_COMBO_BOX is not. It seems to me that the mouse pointer events are captured by EV_COMBO_BOX_IMP and don't propagate to:

  text_field: EV_INTERNAL_COMBO_FIELD_IMP
  combo: EV_INTERNAL_COMBO_BOX_IMP


All these problems make it very difficult for me to use EV_COMBO_BOX the way I would like. The order of priority for these problems to be addressed to fit my needs is 2), 1), 4) and 3).


BTW, is there a way to know if the mouse has been clicked somewhere? With `enable_capture' we can monitor the actions executed in `pointer_button_press_actions' for example. But what I want is the mouse click to perform its normal behavior (even in other widgets, so `enable_capture' does not work quite well here) but be notified of such click. Adding an agent in `pointer_button_press_actions' of all widgets of my application is quite cumbersome. Is there a better way?
To Reproduce

										
Problem Report Interactions
From:ericbe    Date:2004/09/21    Download   
From: "Eric Bezault" <ebezault@axarosenberg.com>
To: <bugs@berkeley.eiffel.com>
Cc:  Subject: RE: EiffelVision_2/4042
Date: Sun, 19 Sep 2004 07:38:31 -0700

 > 2) When the focus is in the text field and I click on the 
 > arrow box the EV_COMBO_BOX loses the focus. The agents registered in:
 > 
 >   my_combo_box.focus_out_actions
 > 
 > are executed. This does not seem right to me. If it was a 
 > design decision to make EV_COMBO_BOX an atomic widget and not 
 > provide access to its text field and box subcomponents then 
 > the focus should not have been lost when clicking on the arrow box.
 
 My workaround has been to add the following routine in a descendant
 of EV_COMBO_BOX:
 
 	has_box_focus: BOOLEAN is
 			-- Is the focus on the box part of the combo
 box?
 			-- (`has_focus' returns true only if the focus
 is on the text field part!)
 		local
 			l_combo_box_imp: EV_COMBO_BOX_IMP
 		do
 			l_combo_box_imp ?= implementation
 			if l_combo_box_imp /= Void then
 				Result :=
 l_combo_box_imp.combo.has_fo
....
Output truncated, Click download to get the full message