Feature #4164
implement misc UI features (frame options, misc attributes)
70%
Related issues
History
#1 Updated by Greg Shah over 4 years ago
test theFRAME-COL
function to ensure it is compatible- frame options
SCROLL
(runtime stubs)USE-TEXT
(runtime stubs)NO-ATTR-SPACE
(partial runtime)
- attributes
browse:num-entries
editor:auto-indent
widget:next-tab-item
frame:prev-tab-item
- event support
SCROLL-NOTIFY
- high level events for browse widget- "A mouse action in the scrollbar area of a browse."
- "This event allows the developer to track physical movement of the focused row in the browse viewport."
- "This event is supported only for backward compatibility. Use SCROLL-HORIZONTAL and SCROLL-VERTICAL instead."
SCROLL-HORIZONTAL
andSCROLL-VERTICAL
- high level events for browse widgetOFF-END
- high level event for browse widget, "A keyboard or mouse actionthat tries to move after the last row of a browse."OFF-HOME
- high level event for browse widget, "A keyboard or mouse actionthat tries to move before the first row of a browse."PARENT-WINDOW-CLOSE
- high level event for window widget, "An event that each descendant window receives when the common ancestor window in that family receives a WINDOW-CLOSE event."DESELECT
- not sure if this is the same as the
DESELECTION
event documented as a direct manipulation event, there is no other documented event that can match - How it is generated? "For all selected widgets in a frame, click the mouse SELECT button on an unselected widget or in empty space in the frame."
- Affects "Frame and field-level widgets with SELECTABLE attribute set to TRUE; browses. For a single selected EXTEND button on a widget, click the mouse selected widget."
- Processing
- "Internal: Sets the widget's SELECTED attribute to FALSE. This setting takes effect after any trigger for the event executes."
- "Screen: Removes the highlight from the affected widget or widgets."
- not sure if this is the same as the
#3 Updated by Greg Shah about 4 years ago
- Status changed from New to WIP
- Assignee set to Greg Shah
I've added testcases/uast/browse/browse_num_entries.p
which shows how num-entries
works:
def temp-table test no-undo field txt as char field num as int field flag as logical index pi_num is primary num ascending. def var last-num as int init 30 no-undo. def var i as int. message "How many records?" update last-num format "999". do i = 1 to last-num transaction: create test. assign txt = string(i) + " text" num = i flag = (i mod 2) eq 0. end. def query q for test. def browse brws query q no-lock no-wait display test with 5 down centered. form brws with frame f-frame. /* 0 */ message "Before OPEN QUERY" browse brws:num-entries. open query q for each test no-lock. /* 0 */ message "After OPEN QUERY" browse brws:num-entries. on f7 of browse brws do: /* this is an undocumented attribute that works on browse */ /* the value depends on the number of records in the query AND on the down value of the browse */ /* if query_record_count < browse_down then query_record_count else browse_down */ /* perhaps this is best described as "returns the number of records that are visible at this time" */ message "F7" browse brws:num-entries. end. enable all with frame f-frame. wait-for go of current-window. disable all with frame f-frame. hide frame f-frame. /* shows same as F7 case */ message "After HIDE" browse brws:num-entries.
#4 Updated by Greg Shah about 4 years ago
Branch 4335a revision 11420 implements the runtime for the BROWSE:NUM-ENTRIES
undocumented attribute. The conversion was already supported. The testcase from #4164-3 is checked in as uast/testcases/browse/browse_num_entries.p
. That testcase works properly with the new implementation.
Stanislav: Please review.
#5 Updated by Stanislav Lomany about 4 years ago
- File browse_num_entries2.p added
Stanislav: Please review.
The approach in getNumEntries
doesn't work if a browse is not fully filled and the number of rows is more that DOWN
, see the testcase. I suppose the only way to get the correct number of rows is to query the client side.
#6 Updated by Greg Shah about 4 years ago
Stanislav Lomany wrote:
Stanislav: Please review.
The approach in
getNumEntries
doesn't work if a browse is not fully filled and the number of rows is more thatDOWN
, see the testcase. I suppose the only way to get the correct number of rows is to query the client side.
Do we already have an API for this? If not, do we store this value on the client?
#7 Updated by Greg Shah about 4 years ago
4335a revision 11428 adds conversion and server-side support for EDITOR:AUTO-INDENT
. The client-side runtime still needs to be implemented. I think the code needs to be changed in com.goldencode.p2j.ui.client.Editor
(see both placeLF()
and splitLine()
).
Interestingly, TABs are used for focus change and they seem to be eaten, even if there is no other widget in the tab order (when the editor is the only enabled widget). So it looks like only space chars need to be considered. We should test if there are any other whitespace chars that are honored (either by typing the characters or from the clipboard or reading from file or variable).
The behavior is pretty simple, it works no matter if you are splitting a line or if you are adding a line by hitting enter at the end of a line. It works anywhere there is a preceding line.
#8 Updated by Greg Shah about 4 years ago
We have usage of both NEXT-TAB-ITEM
and PREV-TAB-ITEM
in a customer application. Frames are used as well as widgets. Our gap analysis marks both attributes as rt_lvl_partial
(conversion is fully supported already). The comment (at least for NEXT-TAB-ITEM
) is that frames aren't supported. But as far as I can see the support seems to be there for both widgets and frames.
Can someone please provide more detail on the parts that are missing in regard to NEXT-TAB-ITEM
and PREV-TAB-ITEM
for frames?
#9 Updated by Greg Shah about 4 years ago
- % Done changed from 0 to 20
There is no further conversion work in this task. Everything is just runtime at this point.
#10 Updated by Stanislav Lomany about 4 years ago
- % Done changed from 20 to 0
Do we already have an API for this? If not, do we store this value on the client?
There's no server API for it, you can create a function to get Browse.getCacheSize()
from the client side.
#11 Updated by Stanislav Lomany about 4 years ago
- % Done changed from 0 to 20
#12 Updated by Constantin Asofiei about 4 years ago
Greg Shah wrote:
Can someone please provide more detail on the parts that are missing in regard to
NEXT-TAB-ITEM
andPREV-TAB-ITEM
for frames?
A part which is missing is the GenericFrame
support - something like frame f1:next-tab-item
will not work, unless all access to these attrs is converted via the frame handle.
#13 Updated by Greg Shah about 4 years ago
Is this just a conversion issue? The methods are implemented in CommonFrame
and FrameWidget
.
#14 Updated by Constantin Asofiei about 4 years ago
Greg Shah wrote:
Is this just a conversion issue? The methods are implemented in
CommonFrame
andFrameWidget
.
GenericFrame
throws an exception for this - the fix is simple, just delegate the call to FrameWidget
.
#15 Updated by Greg Shah about 4 years ago
Task branch 4335a was merged to trunk as revision 11345.
#16 Updated by Roger Borrello about 4 years ago
Greg Shah wrote:
Stanislav Lomany wrote:
Stanislav: Please review.
The approach in
getNumEntries
doesn't work if a browse is not fully filled and the number of rows is more thatDOWN
, see the testcase. I suppose the only way to get the correct number of rows is to query the client side.Do we already have an API for this? If not, do we store this value on the client?
What is NUM-ENTRIES
attribute hold? Is it the number of entries left? When I ran the browse_num_entries2.p
in 4GL, 3 was displayed. In FWD, is displayed 11.
#17 Updated by Stanislav Lomany about 4 years ago
What is
NUM-ENTRIES
attribute hold? Is it the number of entries left?
It is the number of data rows in the view.
#18 Updated by Greg Shah about 4 years ago
#19 Updated by Roger Borrello about 4 years ago
- File num_entries.png added
- File num_entries2.png added
FWD returning 11 leads me to believe there are still 11 rows in the view. Evidence is the slider on the scrollbar has a large proportion of scrollbar below, while the 4GL the slider (in addition to filling the bottom of the scrollbar) is at the bottom.
When you click above the slider, there are 3 clicks to get to the top. Once it is at the top, 1 click below the slider takes you all the way to the bottom of the view, and F7=11 is then accurate, as there are 11 lines in the view. 4GL has no such F7 function.
How should I approach this?
#20 Updated by Greg Shah about 4 years ago
As Stanislav noted above, FWD returning 11 is a BUG. So you don't need to analyze how 11 relates to anything.
4GL has no such F7 function.
You must be testing the wrong code in the 4GL. The "F7 function" that you mention is just a trigger in the 4GL code. It should be there in both FWD and the 4GL.
Please read the testcases and the previous notes carefully. Stanislav has already provided the details on what needs to be done in #4164-10.
#21 Updated by Roger Borrello about 4 years ago
Stanislav Lomany wrote:
Do we already have an API for this? If not, do we store this value on the client?
There's no server API for it, you can create a function to get
Browse.getCacheSize()
from the client side.
Is there already some data sharing from client to server going on, so I can see an example? Is LogicalTerminal's refreshCurrentRow
implementation of ClientExport's refreshCurrentRow
doing the same type of servicing?
#22 Updated by Greg Shah about 4 years ago
Yes, except you will only have the browseId
parameter and you must return an int
.
#23 Updated by Roger Borrello about 4 years ago
Greg Shah wrote:
Yes, except you will only have the
browseId
parameter and you must return anint
.
What's the relationship between the PageRowCount
(number of rows in the browse viewport set either by DOWN or SIZE options) and the CacheSize
(number of entries visible in the browse)? They sound very similar.
#24 Updated by Stanislav Lomany about 4 years ago
Consider you have a browse:
data row 1 data row 2 <empty row> <empty row> <empty row>
DOWN is 5, cache size is 2.
#25 Updated by Roger Borrello about 4 years ago
Stanislav Lomany wrote:
Consider you have a browse:
[...]
DOWN is 5, cache size is 2.
Thanks.
I've added on the server:ClientExports: public int getBrowseCacheSize(int browseId);
BrowseWidget: private int getBrowseCacheSize()
Currently I have this storingLogicalTerminal.getBrowseCacheSize(this)
inprivate Integer cacheSize
LogicalTerminal: public static int getBrowseCacheSize(BrowseWidget bw)
which returnslocate().client.getBrowseCacheSize(bw.getId());
ThinClient: public int getBrowseCacheSize(int browseId)
where this is returningeventDrawingBracket(browse, () -> res[0] = browse.getCacheSize());
Does that look accurate?
I see that on the client, the value returned by Browse.getCacheSize
is dcData.length
. In order to make this available to the server,
#26 Updated by Stanislav Lomany about 4 years ago
ClientExports: public int getBrowseCacheSize(int browseId);
BrowseWidget: private int getBrowseCacheSize()
LogicalTerminal: public static int getBrowseCacheSize(BrowseWidget bw)
I would prefer to name functions in other way, e.g. getBrowseRowsNum
, because the "cache" term is internal to client-side browse part.
eventDrawingBracket(browse, () -> res[0] = browse.getCacheSize());
You don't need to start an eventDrawingBracket
because no drawing happens here.
#27 Updated by Greg Shah about 4 years ago
I don't see any value in BrowseWidget.getBrowseCacheSize()
when getNumEntries()
can call LogicalTerminal.getBrowseCacheSize()
directly.
#28 Updated by Roger Borrello about 4 years ago
Updated per suggestions. Thanks!
Committing to: /home/rfb/secure/code/p2j_repo/p2j/active/4231b/ modified src/com/goldencode/p2j/ui/chui/ThinClient.java modified src/com/goldencode/p2j/ui/ClientExports.java modified src/com/goldencode/p2j/ui/BrowseWidget.java modified src/com/goldencode/p2j/ui/LogicalTerminal.java Committed revision 11377.
#29 Updated by Stanislav Lomany about 4 years ago
Review rev 11377: Roger, you forgot to remove the array need for eventDrawingBracket
. You can just write return browse != null ? browse.getCacheSize() : 0;
Otherwise the update is good.
#30 Updated by Roger Borrello about 4 years ago
Stanislav Lomany wrote:
Review rev 11377: Roger, you forgot to remove the array need for
eventDrawingBracket
. You can just writereturn browse != null ? browse.getCacheSize() : 0;
Otherwise the update is good.
Thanks! I hadn't worked with eventDrawingBracket
so I was being conservative.
#31 Updated by Roger Borrello about 4 years ago
- File frame_loc_attributes_get.png added
This test is promising:
Code below. What else can I do to validate?
def var i as int. def var ch as char. form i ch with frame f1 10 down. do i = 0 to 9: ch = "#" + string(i). display i ch with frame f1. message i:screen-value ":" "x=" i:x /* pix loc of wid left edge rel to left parent edge */ "y=" i:y /* pix loc of wid top edge rel to top parent edge */ "c=" i:column /* col pos of wid left edge rel to left (same as x) */ "r=" i:row /* row pos of wid top edge rel to top (same as y ) */ "fx=" i:frame-x /* pix loc of wid left edge rel to ul of frame */ "fy=" i:frame-y /* pix loc of wid top edge rel to ul of frame */ "fc=" i:frame-col /* Dec col pos of wid left edge rel to ul of wid frame */ "fr=" i:frame-row /* Dec col pos of wid top left edge rel to ul of wid frame */ . down with frame f1. end. up 5 with frame f1. message i:screen-value ":" "x=" i:x /* pix loc of wid left edge rel to left parent edge */ "y=" i:y /* pix loc of wid top edge rel to top parent edge */ "c=" i:column /* col pos of wid left edge rel to left (same as x) */ "r=" i:row /* row pos of wid top edge rel to top (same as y ) */ "fx=" i:frame-x /* pix loc of wid left edge rel to ul of frame */ "fy=" i:frame-y /* pix loc of wid top edge rel to ul of frame */ "fc=" i:frame-col /* Dec col pos of wid left edge rel to ul of wid frame */ "fr=" i:frame-row /* Dec col pos of wid top left edge rel to ul of wid frame */ .
#32 Updated by Greg Shah about 4 years ago
Please read the 4GL docs to see what the FRAME-COL
function is meant to do. It is the counterpart of FRAME-ROW
and both are used to see the location in (characters) of the frame's upper left corner. So in order to test this, you probably need to use it on frames that are displayed at different locations on the screen, right? Also, what happens when the frame is not displayed at all?
#33 Updated by Greg Shah about 4 years ago
#34 Updated by Greg Shah about 4 years ago
- Related to Feature #4394: add some frame options and attributes added
#35 Updated by Greg Shah about 4 years ago
All you care about is positioning the frame in different locations. This is trivial to do in the AT phrase of the frame phrase.
WITH frame f AT { COLUMN column ROW row | X x Y y }
#36 Updated by Roger Borrello about 4 years ago
I had a testcase:
def var i as int init 0 format 99. def frame f0 i with width 10 title "F0 Title". def frame f1 i with width 20 title "F1 Title". def frame f2 i with width 30 title "F2 Title". def frame f3 i with width 40 title "F3 Title". def frame f4 i with width 50 title "F4 Title". def frame f5 i with width 40 title "F5 Title". def frame df0 i with view-as dialog-box width 50 title "Default Dialog Title". message "display-type=" session:display-type. {frame_layout\frame_loc_attributes_helper.i &fr="f0"} {frame_layout\frame_loc_attributes_helper.i &fr="f1"} {frame_layout\frame_loc_attributes_helper.i &fr="f2"} {frame_layout\frame_loc_attributes_helper.i &fr="f3"} {frame_layout\frame_loc_attributes_helper.i &fr="f4"} {frame_layout\frame_loc_attributes_helper.i &fr="f5"} {frame_layout\frame_loc_attributes_helper.i &fr="df0"}
The helper:
view frame {&fr}. message "{&fr}: " "x=" i:x /* pix loc of wid left edge rel to left parent edge */ "y=" i:y /* pix loc of wid top edge rel to top parent edge */ "c=" i:column /* col pos of wid left edge rel to left (same as x) */ "r=" i:row /* row pos of wid top edge rel to top (same as y ) */ "fx=" i:frame-x /* pix loc of wid left edge rel to ul of frame */ "fy=" i:frame-y /* pix loc of wid top edge rel to ul of frame */ "fc=" i:frame-col /* Dec col pos of wid left edge rel to ul of wid frame */ "fr=" i:frame-row /* Dec col pos of wid top left edge rel to ul of wid frame */ . wait-for go of frame {&fr}.
I should just be able to update the frame phrase with AT column x row y
like:
def frame f0 i with width 10 title "F0 Title" at column 0 row 0. def frame f1 i with width 10 title "F0 Title" at column 1 row 10. def frame f2 i with width 10 title "F0 Title" at column 2 row 20. ...
#37 Updated by Roger Borrello about 4 years ago
- File frame_loc_attributes_get2.png added
Greg Shah wrote:
All you care about is positioning the frame in different locations.
That is not really correct, because the attribute is off the widget, in this case i
. See my new output... even thought the frames are all over the place, the widget is still in the same location relative to its frame.
So my original thought, to find and position widgets all over the frame, would be a more valid test.
#38 Updated by Greg Shah about 4 years ago
That is not really correct, because the attribute is off the widget, in this case i.
Please read #4164-1 more carefully. FRAME-COL(frame)
is a built-in function NOT a widget attribute. Your test is written wrong.
In regard to the error 4102, pick frame positions that are inside the same Window.
#39 Updated by Roger Borrello about 4 years ago
Greg Shah wrote:
That is not really correct, because the attribute is off the widget, in this case i.
Please read #4164-1 more carefully.
FRAME-COL(frame)
is a built-in function NOT a widget attribute. Your test is written wrong.In regard to the error 4102, pick frame positions that are inside the same Window.
My bad... I will have results after conversion of the testcase.
view frame {&fr}. /* Returns a DECIMAL value that is the column position of the left corner of a frame within its window. */ message "{&fr}=" frame-col({&fr}). wait-for go of frame {&fr}.
#40 Updated by Greg Shah about 4 years ago
I think you should check the FRAME-ROW(frame)
builtin for all of the same case.
Make sure to test:
- What do these return before the frame is realized (made visible)? Is it different from post-realization?
- Can you set negative values or values outside the window for the frame, when the frame is not realized? If so what is returned for those cases?
- What happens if you use the same values for two frames that share the same window? I suspect the pre-realized/post-realized values might be different. For example, the 4GL may move the frame automatically.
- what happens when you display a frame that has no explicit positioning, but there are already other frames displayed? I think the location will be calculated automatically and will be different pre/post realization.
#41 Updated by Roger Borrello about 4 years ago
- File GUI_frame_loc_attributes_get2.png added
I'll update, now that I (finally) understand. I do have some initial items, some not related to this testcase, but behaviors that are different from 4GL's. How do you want those reported?
With respect to what happens when you display a frame that has no explicit positioning, but there are already other frames displayed? This was covered in the current testcase's dialog frame df5
. In 4GL it is reported as 31.6
. In FWD, it was 1
.
#42 Updated by Greg Shah about 4 years ago
Make a list of the problems here and fix them.
#43 Updated by Roger Borrello about 4 years ago
Greg Shah wrote:
Make a list of the problems here and fix them.
1. What do these return before the frame is realized (made visible)? Is it different from post-realization?
4GL pre-realization values are always 0. FWD are always 1.
#44 Updated by Roger Borrello about 4 years ago
New testcase has expanded my ability to validate values, but I'm not sure it's on the mark yet. I was expecting the frame to move around, but it stays at (1,1).
def var i as int init 0 format 99. def var b4col as int. def var b4row as int. def frame f0 i with title "F0 Title" at column 1 row 1. /*message "display-type=" session:display-type.*/ os-delete "x.txt". {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=1 &rowval=1} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=10 &rowval=2} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=2 &rowval=3} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=10 &rowval=4} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=1 &rowval=5} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=10 &rowval=4} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=2 &rowval=3} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=10 &rowval=2} {frame_layout\frame_loc_attributes_helper.i &out="x.txt" &fr="f0" &colval=1 &rowval=1}
The helper include:
/* Returns a DECIMAL value that is the column position of the left corner of a frame within its window. */ assign b4col = frame-col({&fr}) b4row = frame-row({&fr}) . display i with frame {&fr} at col {&colval} row {&rowval}. output to {&out} append. message "{&fr}: b4col/b4row="b4col "/" b4row "aftcol/aftrow="frame-col({&fr}) "/" frame-row({&fr}) "col/row="{&colval} "/" {&rowval} " i:" "x/y=" i:x "/" i:y /* pix loc of wid left/top edge rel to left parent edge */ "c/r=" i:column "/" i:row /* col/row pos of wid left/top edge rel to left/top (same as x/y) */ "fc/fr=" i:frame-col "/" i:frame-row /* Dec col pos of wid left/top edge rel to ul of wid frame */ "fx/fy=" i:frame-x "/" i:frame-y /* pix loc of wid left/top edge rel to ul of frame */ . output close. wait-for go of frame {&fr}.
#45 Updated by Constantin Asofiei about 4 years ago
Roger, the AT COL ROW
in the frame phrase (for DISPLAY) sets the frame's definition location, not at runtime.
To move it at runtime, use the frame's col/row attributes.
#46 Updated by Greg Shah about 4 years ago
As Constantin notes, you are telling the code to only have the frame positioned in col 1 row 1
because only the FIRST use of that is honored. Since you only ever have one frame, it is always set to the same value.
Instead of changing the attributes, you can just remove the frame definition and then use DIFFERENT frame names in each usage of the inlcude file.
#47 Updated by Roger Borrello about 4 years ago
Please confirm editor:auto-indent
already converts and just needs runtime support only (so I can bypass)?
#48 Updated by Greg Shah about 4 years ago
Roger Borrello wrote:
Please confirm
editor:auto-indent
already converts and just needs runtime support only (so I can bypass)?
From #4164-7:
4335a revision 11428 adds conversion and server-side support for EDITOR:AUTO-INDENT. The client-side runtime still needs to be implemented. I think the code needs to be changed in com.goldencode.p2j.ui.client.Editor (see both placeLF() and splitLine()).
#49 Updated by Roger Borrello about 4 years ago
Greg Shah wrote:
4335a revision 11428 adds conversion and server-side support for
EDITOR:AUTO-INDENT
. The client-side runtime still needs to be implemented. I think the code needs to be changed incom.goldencode.p2j.ui.client.Editor
(see bothplaceLF()
andsplitLine()
).Interestingly, TABs are used for focus change and they seem to be eaten, even if there is no other widget in the tab order (when the editor is the only enabled widget). So it looks like only space chars need to be considered. We should test if there are any other whitespace chars that are honored (either by typing the characters or from the clipboard or reading from file or variable).
The behavior is pretty simple, it works no matter if you are splitting a line or if you are adding a line by hitting enter at the end of a line. It works anywhere there is a preceding line.
Assuming uast/editor_auto_indent.p
the correct testcase for EDITOR:AUTO-INDENT
...
#50 Updated by Roger Borrello about 4 years ago
With respect to FRAME-COL
(and FRAME-ROW
), I am debugging why these are incorrect when checked using this code:
def frame f0 i with width 10 title "Fr f0" at col 1 row 1. def frame f1 i with width 20 title "Fr f1" at col 1 row 10. display i with frame f0. message "aftcol/aftrow="frame-col(f0) "/" frame-row(f0). display i with frame f1. message "aftcol/aftrow="frame-col(f1) "/" frame-row(f1).
This displays:
aftcol/aftrow= 1 / 1 aftcol/aftrow= 0 / 0
When in 4GL it is:
aftcol/aftrow= 1 / 1 aftcol/aftrow= 1 / 10
These values are retrieved from ThinClient
methods getFrameCol
public double getFrameCol(int frameId) { Frame frame = getFrame(frameId); double result = -1; if (frame != null && frame.isVisible() && !frame.isRedirected()) { result = ConfigHelper.getAssignedColumn(frame.config()); } if (result == BaseConfig.INV_COORD) { result = 0; } return ++result; }
and
getFrameRow
:public double getFrameRow(int frameId) { Frame frame = getFrame(frameId); double result = 0; if (frame != null && frame.isVisible()) { result = frame.location().y + 1; } return result; }These both determine whether or not the frame is visible using
frame.isVisible()
. I need to understand a little more before I can fix this.
- For frame
f0
,isVisible
is valid after theDISPLAY
is processed (as you'd expect). But for framef1
, it doesn't not becometrue
after theDISPLAY
. - Why is
FRAME-COL
retrieved from the configuration, butFRAME-ROW
retrieved from the actual coordinates? - Why does
getFrameCol
include!frame.isRedirected()
andgetFrameRow
doesn't?
Since they return DECIMAL
, I believe they should be the actual coordinates, rather than what is configured. Documentation says, "Returns a DECIMAL value that is the column (row position) of the left (upper-left) corner of a frame within its window."
#51 Updated by Roger Borrello about 4 years ago
During debug, I found that when the visible
flag is set prior to the frame being displayed, the getFrame(frameId)
returns FrameGuiImpl
. After the frame is displayed, it returns FrameChuiImpl
.
During the f0
frame handling, the visible
flag is found to be true
in the FrameChuiImpl
, so it's values for FRAME-COL
and FRAME-ROW
are returned correctly. But for all the other frames, it is left as false
.
I am not familiar enough with why FrameGuiImpl
is the frame class before the display, and FrameChuiImpl
after, to know if that's working correctly. I do see when the frame is displayed, the visible
in FrameGuiImpl
is what is set.
#52 Updated by Constantin Asofiei about 4 years ago
Roger Borrello wrote:
During debug, I found that when the
visible
flag is set prior to the frame being displayed, thegetFrame(frameId)
returnsFrameGuiImpl
. After the frame is displayed, it returnsFrameChuiImpl
.During the
f0
frame handling, thevisible
flag is found to betrue
in theFrameChuiImpl
, so it's values forFRAME-COL
andFRAME-ROW
are returned correctly. But for all the other frames, it is left asfalse
.I am not familiar enough with why
FrameGuiImpl
is the frame class before the display, andFrameChuiImpl
after, to know if that's working correctly. I do see when the frame is displayed, thevisible
inFrameGuiImpl
is what is set.
Area you using streams in your tests, or the redirected terminal ( unnamed stream)? In GUI we have ChUI mode for 'redirected terminal' or stream output, and GUI mode otherwise.
Can you post a breakpoint in the c'tor and see who creates FrameChuiImpl (on client-side)?
#53 Updated by Roger Borrello about 4 years ago
Constantin Asofiei wrote:
Area you using streams in your tests, or the redirected terminal ( unnamed stream)? In GUI we have ChUI mode for 'redirected terminal' or stream output, and GUI mode otherwise.
I am using "output to..." to collect the output. I can try without. However, I would think this is a bug.
Can you post a breakpoint in the c'tor and see who creates FrameChuiImpl (on client-side)?
I did, and it shows StreamableWidget.convertToStreamable
-> FrameGuiImpl.convertToStreamable
-> WidgetFactoryAdapter.ChuiWidgetFactory.create
...
#54 Updated by Constantin Asofiei about 4 years ago
Roger Borrello wrote:
I am using "output to..." to collect the output. I can try without. However, I would think this is a bug.
OK, so we are in a 'normal' path for redirected terminal in GUI. Yes, this looks like a bug, the configuration should be shared (or at least sync'ed back) to the GUI frame.
But, in my experience, a frame used for reports (to redirected terminal/streams) will not be used in GUI, too. So, create a duplicate test for this issue and add a bug in the UI project.
#55 Updated by Roger Borrello about 4 years ago
Constantin Asofiei wrote:
Roger Borrello wrote:
I am using "output to..." to collect the output. I can try without. However, I would think this is a bug.
OK, so we are in a 'normal' path for redirected terminal in GUI. Yes, this looks like a bug, the configuration should be shared (or at least sync'ed back) to the GUI frame.
But, in my experience, a frame used for reports (to redirected terminal/streams) will not be used in GUI, too. So, create a duplicate test for this issue and add a bug in the UI project.
This is "normal" in that it's easier for testing, but I would agree, not in "regular" normal.
Testcase:
uast/frame_layout/frame_loc_attributes_get2-redirected.p uast/frame_layout/frame_loc_attributes_get2.p uast/frame_layout/frame_loc_attributes_helper.i
The helper takes a pre-processor directive for a log file. If it's there, it redirects. If it's not, it doesn't redirect.
#56 Updated by Roger Borrello about 4 years ago
- Related to Bug #4625: Frame configuration not shared or synched back to the GUI frame on redirection added
#57 Updated by Roger Borrello about 4 years ago
I also notice on the last frame (a dialog box) the F2
never is recognized in the wait-for go of frame df0.
I have to use ESC
.
Wasn't someone working in the keystroke area of the client that may have changed something related to this?
#58 Updated by Roger Borrello about 4 years ago
- % Done changed from 20 to 40
#59 Updated by Roger Borrello about 4 years ago
When not using redirection, the testcase passes.
f0: b4col/b4row= 0 / 0 aftcol/aftrow= 1 / 1 col/row= 1 / 1 i: x/y= 0 / 0 c/r= 1 / 1 fc/fr= 1 / 2.67 fx/fy= 0 / 35 f1: b4col/b4row= 0 / 0 aftcol/aftrow= 1 / 10 col/row= 1 / 10 i: x/y= 0 / 0 c/r= 1 / 1 fc/fr= 1 / 2.67 fx/fy= 0 / 35 f2: b4col/b4row= 0 / 0 aftcol/aftrow= 10 / 1 col/row= 10 / 1 i: x/y= 0 / 0 c/r= 1 / 1 fc/fr= 1 / 2.67 fx/fy= 0 / 35 f3: b4col/b4row= 0 / 0 aftcol/aftrow= 10 / 10 col/row= 10 / 10 i: x/y= 0 / 0 c/r= 1 / 1 fc/fr= 1 / 2.67 fx/fy= 0 / 35 df0: b4col/b4row= 0 / 0 aftcol/aftrow= 1 / 1 col/row= 1 / 1 i: x/y= 0 / 0 c/r= 1 / 1 fc/fr= 1 / 2.67 fx/fy= 0 / 35
However, I'd still like to understand of getFrameCol
and getFrameRow
need to be merged to using the coordinates or the configuration.
#60 Updated by Roger Borrello about 4 years ago
Hynek: I am trying to understand why the implementations for FRAME-COL
and FRAME-ROW
are so different, and Greg suggested asking you.
ThinClient.getFrameCol
uses ConfigHelper.getAssignedColumn(frame.config())
while ThinClient.getFrameRow
uses frame.location().y
. The results are accurate either way, but was there any specific reason for the difference?
#61 Updated by Hynek Cihlar about 4 years ago
Roger Borrello wrote:
Hynek: I am trying to understand why the implementations for
FRAME-COL
andFRAME-ROW
are so different, and Greg suggested asking you.
ThinClient.getFrameCol
usesConfigHelper.getAssignedColumn(frame.config())
whileThinClient.getFrameRow
usesframe.location().y
. The results are accurate either way, but was there any specific reason for the difference?
Both of these methods were at some point changed by myself and by Constantin as part of bigger refactoring chunk. I don't think there is any valid reason for the different implementations. I don't even think we need to do a remote call to get the value of FRAME-ROW
and FRAME-COL
functions. Both could be determined from the frame's config using ConfigHelper.getEffectiveRow
and ConfigHelper.getEffectiveColumn
.
#62 Updated by Roger Borrello about 4 years ago
Hynek Cihlar wrote:
Both of these methods were at some point changed by myself and by Constantin as part of bigger refactoring chunk. I don't think there is any valid reason for the different implementations. I don't even think we need to do a remote call to get the value of
FRAME-ROW
andFRAME-COL
functions. Both could be determined from the frame's config usingConfigHelper.getEffectiveRow
andConfigHelper.getEffectiveColumn
.
I will update ThinClient
and run my testcases that verify the attributes, then submit for review.
#63 Updated by Roger Borrello about 4 years ago
One other significant difference between the two is that getFrameCol
includes a check for !frame.isRedirected()
where getFrameRow
does not. This condition of whether or not the col/row is retrieved. Which is more correct?
#64 Updated by Hynek Cihlar about 4 years ago
Roger Borrello wrote:
One other significant difference between the two is that
getFrameCol
includes a check for!frame.isRedirected()
wheregetFrameRow
does not. This condition of whether or not the col/row is retrieved. Which is more correct?
Sorry, I can't answer this. But it should be easy to find out by testing in native 4GL.
#65 Updated by Roger Borrello about 4 years ago
getEffectivexxx
methods are returning 0.0
for clientColumn
and clientRow
when reading the attributes. The getAssignedxxx
methods are returning the actual row/col accurately when I call them directly, because in the getEffectivexxx
methods, they are protected by validating the row/col are BaseConfig.INV_COORD
before checking.
The testcases are getting frame-col(f0)/frame-row(f0)
before/after realization. The frames are defined with at col x row y
at the beginning.
It looks like the server-assigned values returned by getAssignedxxx
are more accurate than getEffectivexxx
(albeit 0-based). Does this warrant more investigation, or should I be OK using the getAssignedxxx
methods?
#66 Updated by Roger Borrello about 4 years ago
Updated src/com/goldencode/p2j/ui/chui/ThinClient.java
in 4231b-11504. Please review.
#67 Updated by Roger Borrello about 4 years ago
- % Done changed from 40 to 60
#68 Updated by Roger Borrello about 4 years ago
From Hynek:
Both getAssigned and getEffective return 0-based values. These must be incremented by one (and perhaps also decremented if negative) before the values are returned to legacy code. See BaseEntity.getRow for an example. But please run some test cases in native 4GL to confirm the same behavior for FRAME-ROW
and FRAME-COL
.
I think you have to use getEffective. Consider the case when the frame position is not assigned explicitly, in this case getAssigned should/may return invalid coordinates.
Thanks,
Hynek
#69 Updated by Roger Borrello about 4 years ago
Roger Borrello wrote:
From Hynek:
Both getAssigned and getEffective return 0-based values. These must be incremented by one (and perhaps also decremented if negative) before the values are returned to legacy code. See BaseEntity.getRow for an example. But please run some test cases in native 4GL to confirm the same behavior for
FRAME-ROW
andFRAME-COL
.I think you have to use getEffective. Consider the case when the frame position is not assigned explicitly, in this case getAssigned should/may return invalid coordinates.
Thanks,
Hynek
Thanks for that info. We do have checks for invalid coordinates, as part of the methods. Please review, as my testcases were successful after I incremented the return value.
#70 Updated by Hynek Cihlar about 4 years ago
Code review 4231b revision 11504. The code changes seem OK. I think you should also test the changes in ChUI if you haven't.
#71 Updated by Roger Borrello about 4 years ago
- % Done changed from 60 to 70
Testcase passes in ChUI, as well.
#72 Updated by Roger Borrello almost 4 years ago
NO-ATTR-SPACE¶
All the documentation indicates ATTR-SPACE
and NO-ATTR-SPACE
have no effect. That they are supported only for backward compatibility.
#73 Updated by Greg Shah almost 4 years ago
Prove it (with testcases). You can only do this with frame that have many widgets. Make sure you test:
- more than 1 widget side by side on the same "row"
- widgets in multiple rows
- explicitly using SKIP
- implicitly by having too many widgets for the width of the frame
- ? (other stuff I'm not thinking about now)
#74 Updated by Roger Borrello almost 4 years ago
One issue is there isn't any documentation indicating the proper usage, or even what ATTR-SPACE
and NO-ATTR-SPACE
are supposed to do. The 9.1.E ABL reference says for backward compatibility. That's the oldest I've found. Internet searches, the same thing.
There are about 32 procedures in customer code that use either ATTR-SPACE
or NO-ATTR-SPACE
. I could start with them.
#75 Updated by Roger Borrello almost 4 years ago
Even though documentation for IS-ATTR-SPACE
function indicates it is also supported only for backward compatibility, I'm looking through our code and getting the impression that ATTR-SPACE
is like a setter for setting the "space-taking" attribute to yes
and NO-ATTR-SPACE
is the setter for setting the "space-taking" attribute to no
, and IS-ATTR-SPACE
is the getter for the "space-taking" attribute.
I've captured the sample code provided into ./uast/frames/is_attr_space.p
, only to find we haven't implemented this built-in.
define variable termtype as logical format "spacetaking/non-spacetaking". termtype = is-attr-space. display "You are currently using a" termtype no-label "terminal" with frame d1 centered row 5.
The comment in gaps
is is-attr-space is not supported but runtime backend is ready(for attribute). I don't think the conversion rule is in place, since conversion of the testcase yields:
[javac] /home/rfb/projects/VirtualBox-VMs/shared/projects/testcases/src/com/goldencode/testcases/frames/IsAttrSpace.java:31: error: no suitable method found for assign(no arguments) [javac] termtype.assign()The implementations spread out:
ui.client.Frame
hasisAttrSpace
andsetAttrSpace
methodsui.ControlConfig
haspublic boolean attrSpace = false;
but noisAttrSpace
orsetAttrSpace
methodsui.ControlEntity
hassetAttrSpace
andsetNoAttrSpace
methods, but noisAttrSpace
method.ui.FrameWidget
hassetAttrSpace
andisAttrSpace
methods.ui.GenericFrame
hassetAttrSpace
method, but noisAttrSpace
method.
#76 Updated by Roger Borrello almost 4 years ago
- File 20200514_use-text.png added
- File 20200514_use-text-2.png added
USE-TEXT¶
This looks like it's working properly. However, there are 2 UI issues, one might be related, the other unrelated.- The default values for the fill-ins that weren't included in the display statement seem to default to 0, whereas in 4GL, they are unknown. Give me an idea where to find this, and I can fix it.
- There is an area around the fill-in widget that overlays an area of the screen, specifically the button next to it. Is there a precedent to the widgets, such that the button should lay on top of the fill-in? The second screen shot is the display without
USE-TEXT
which shows the fill-in is slightly covered by the button. When numbers are entered, they disappear behind it (in 4GL, as well) but you can see the commas getting added as you add more digits.
With USE-TEXT
:
Without USE-TEXT
:
Testcase: uast/frames/button_mix_use-text.p
def var my-char as character init "Some text" format "x(20)". def var myint as int initial 0. def var myint2 as int initial 2. def var myint3 as int initial 3. def button MyButton label "My Button". def button MyButton2 label "My Button 2". def button MyButton3 label "My Button 3" font 2. form my-char at column 10 row 1 myint at column 40 row 1 MyButton at column 10 row 2 myint2 at column 40 row 2 MyButton2 at column 58 row 2 MyButton3 at column 10 row 3 myint3 at column 10 row 4 with frame ButtFrame side-labels centered size 80 by 6. def frame ButtFrame my-char myint MyButton myint2 MyButton2 MyButton3 myint3 with centered use-text. display my-char myint with frame ButtFrame. enable all with frame ButtFrame. on choose of MyButton do: myint = myint + 1. message "HELLO!!! (" myint ")". end. on F4 endkey. wait-for endkey of MyButton.
#77 Updated by Greg Shah almost 4 years ago
As part of this task, there were changes to the ThinClient.getFrameCol()
method.
The original code:
public double getFrameCol(int frameId) { Frame frame = getFrame(frameId); double result = 0; if (frame != null && frame.isVisible() && !frame.isRedirected()) { result = ConfigHelper.getAssignedColumn(frame.config()); } if (result == BaseConfig.INV_COORD) { result = 0; } return ++result; }
The changed code which caused a regression in ChUI:
public double getFrameCol(int frameId) { Frame frame = getFrame(frameId); double result = 0; if (frame != null && frame.isVisible() && !frame.isRedirected()) { result = ConfigHelper.getAssignedColumn(frame.config()) + 1; } if (result == BaseConfig.INV_COORD) { result = 0; } return result; }
The problem here is that this line result = ConfigHelper.getAssignedColumn(frame.config()) + 1;
can now assign result = -2147483647
where previously it could result in result = -2147483648
. Consider that INV_COORD Integer.MIN_VALUE -2147483648
. This means that the next code if (result == BaseConfig.INV_COORD)
will be true
in the original version and false
in the changed version. In the original code that means the result
would be reset to 0 and then incremented before returning it. But in the changed code the -2147483647
was returned directly which is bad. This breaks our ChUI regression suite as you can imagine that code dependent upon this value being 1 will not work well when given -2147483647
instead.
I've backed out this change in 4231b rev 11610. The proper fix will need to be in the next branch.
#78 Updated by Greg Shah almost 4 years ago
Task branch 4231b has been merged to trunk as revision 11347.
#79 Updated by Roger Borrello almost 4 years ago
Greg Shah wrote:
As part of this task, there were changes to the
ThinClient.getFrameCol()
method.I've backed out this change in 4231b rev 11610. The proper fix will need to be in the next branch.
Fix checked into 3821c-11354.
#80 Updated by Greg Shah almost 4 years ago
Code Review Task Branch 3821c Revision 11354
This is incorrect. ConfigHelper.getAssignedColumn(frame.config())
can return BaseConfig.INV_COORD
. If you then add 1 to that number, then you will bypass the code below which resets it to 0.
If you test the broken ChUI application (test xxx 146), you will see the change does not work.
#81 Updated by Roger Borrello almost 4 years ago
Greg Shah wrote:
Code Review Task Branch 3821c Revision 11354
This is incorrect.
ConfigHelper.getAssignedColumn(frame.config())
can returnBaseConfig.INV_COORD
. If you then add 1 to that number, then you will bypass the code below which resets it to 0.If you test the broken ChUI application (test xxx 146), you will see the change does not work.
If ConfigHelper.getAssignedRow(frame.config())
can return BaseConfig.INV_COORD
as well, I will have to modify getFrameRow()
method, as well, as that is where I took the getFrameCol()
code from.
#82 Updated by Roger Borrello almost 4 years ago
Roger Borrello wrote:
If
ConfigHelper.getAssignedRow(frame.config())
can returnBaseConfig.INV_COORD
as well, I will have to modifygetFrameRow()
method, as well, as that is where I took thegetFrameCol()
code from.
It does not. So the implementations will need to be a little different. I'll update.
#83 Updated by Roger Borrello almost 4 years ago
This was implemented in 3821c-11358
. Please review, and let me know if there's a way to run an individual test for that ChUI application. I am scrambling to restore some disk space to the laptop so I can complete a customer build.
#84 Updated by Greg Shah almost 4 years ago
Code Review Task Branch 3821c Revision 11358
This seems better. Confirm it with testing.
#85 Updated by Roger Borrello almost 4 years ago
Greg Shah wrote:
Code Review Task Branch 3821c Revision 11358
This seems better. Confirm it with testing.
Regression testing was successful.
#86 Updated by Greg Shah over 3 years ago
- Assignee changed from Greg Shah to Stanislav Lomany
Please see #4164-1 for the remaining work (it is all in the runtime).
#87 Updated by Stanislav Lomany about 3 years ago
My estimates:
SCROLL
- unfortunately, that looks very time-consuming to me.USE-TEXT
- it works, but frame layout is not quite correct.NO-ATTR-SPACE
- documentation states that it has no effect.
auto-indent
- that may take some time to investigate behavior in edge cases
SCROLL-NOTIFY
, OFF-END
, OFF-HOME
, PARENT-WINDOW-CLOSE
- shoudn't be a problem.DESELECT
(DESELECTION
) - assuming that selection/deselection of widgets work fine, that shouldn't be a problem.
So, only SCROLL
looks complicated as this point.
#88 Updated by Greg Shah about 3 years ago
Focus on clearing everything except SCROLL
. That one will be worked last.
#89 Updated by Stanislav Lomany about 3 years ago
USE-TEXT
: currently in FWD this option does two things during conversion:
- Sets
frame.setUseText(true)
which has no actual effect. - Converts widgets to
TextWidget
instead ofFillInWidget
.
It makes a widget affected by USE-TEXT
to be correctly displayed as a text widget. However it may have incorrect width/height/font type because these parameters are controlled by widget.explicitViewAs(true)
flag.
It would probably make sense to check useText
flag of the parent frame in the same location as explicitViewAs
flag. But the problem is that there may be no parent frame when explicitViewAs
is checked (e.g. in widget initialize
).
So the obvious solution I see is to add widget.explicitViewAs(true)
for widgets affected by USE-TEXT
. What do you think?
And another issue to fix:
widget VIEW-AS FILL-IN ... WITH FRAME frame USE-TEXT
results in fill-in in 4GL and text in FWD.
#90 Updated by Constantin Asofiei about 3 years ago
I don't understand how explicitViewAs
flag is used during frame construction. AFAIK this flag is used only on client-side, after the frame has been setup. And a widget can't be pushed to the client-side without its frame.
#91 Updated by Stanislav Lomany about 3 years ago
I don't understand how
explicitViewAs
flag is used during frame construction. AFAIK this flag is used only on client-side, after the frame has been setup.
Yes, it is used on the client side (defines if the font is fixed in initialize
, and in nativeWidth
/nativeHeight
).
And a widget can't be pushed to the client-side without its frame.
That's good! That means I can use TC.getFrame(config.frameId)
there.
#92 Updated by Constantin Asofiei about 3 years ago
Constantin Asofiei wrote:
I don't understand how
explicitViewAs
flag is used during frame construction. AFAIK this flag is used only on client-side, after the frame has been setup. And a widget can't be pushed to the client-side without its frame.
OK, I see what you are referring to - initialize
is called on client-side before the widget is attached to the frame as a child widget (and its parent is set). So you can't find it via that.
But the widget's config.frameId
should be already set - and you can resolve it from the registry via its ID.
#93 Updated by Constantin Asofiei about 3 years ago
Stanislav Lomany wrote:
I don't understand how
explicitViewAs
flag is used during frame construction. AFAIK this flag is used only on client-side, after the frame has been setup.Yes, it is used on the client side (defines if the font is fixed in
initialize
, and innativeWidth
/nativeHeight
).And a widget can't be pushed to the client-side without its frame.
That's good! That means I can use
TC.getFrame(config.frameId)
there.
Exactly.
#94 Updated by Stanislav Lomany about 3 years ago
USE-TEXT
changes are committed 3821c rev 12317. Please review.
#95 Updated by Hynek Cihlar about 3 years ago
Code review 3821c revision 12317.
Text.initialize
assumes there is always a valid parent frame. This assumption may not hold true for dynamic widgets.
#96 Updated by Stanislav Lomany about 3 years ago
Fixed in 3821c revision 12322.
#97 Updated by Stanislav Lomany almost 3 years ago
AUTO-INDENT
committed 3821c rev 12364.
#98 Updated by Stanislav Lomany almost 3 years ago
I assume than implementation of SCROLL-NOTIFY
should include SCROLL-HORIZONTAL
and SCROLL-VERTICAL
events (they are not quite the same).
#99 Updated by Greg Shah almost 3 years ago
Yes.