Category Archives: Blog

Drop it like it’s hot

What very little people know is that in the Import Repository Objects component there is a small section where you can drag your export files from Windows Explorer.  After you drop them, the File name box is updated with the list of files that you dropped.

Uniface

The red section is where the drag-and-drop field is located.

Download for this drag n drop sample

Creating this element in your own component is pretty easy. Just follow these steps:

  1. Create a component. In this example I have created a component named DragNDrop
  2. Paint an entity. I used a non-database entity named DE in the DM application model.
  3. Paint a field. DROPTARGET
  4. Now set the properties according to the image below.

Uniface

We set the widget type to DropTarget indicating that this element will be able to receive elements using a drop event. Make sure you painted the widget large enough so that you can find it very easy on the component. In this setting the widget will have the same gray color as the rest of the component, making it impossible to find if you paint it too small. I painted it across the entire component so it is impossible to miss.

I have set the datatype to string since the result will of a type string. Made the interface a shorthand C* just because I do not know how long the string of filenames will be and the default of 40 characters will probably not cut it.

Now compile the component and test it by dragging something from Windows Explorer to the droptarget.

As you may have noticed that did not work at all. No worries you need to make one small change and it will work.

DoubleClick the droptarget widget to open the properties and then navigate to the widget properties. In the valrep list enter a value named “file” and leave the representation empty.

Uniface

When you compile it and test it again you will notice that the mouse pointer changes from the no-entry sign to a arrow with a plus sign when you hover over the drop target. You can drop it, but it will not do very much.

How to get to the goodies

Dropping something on the drop target will fire the value changed trigger. Here you can put the code to verify if the dropped elements are actually the files that you want and process them further.

In my component I have created an entity FILES in the DM application model and added a field named NM of type string and set its interface to C*. The component looks like this:

Uniface

Next I opened the value changed trigger of the DROPTARGET field and added the following:

variables
   string v_nm
endvariables
 
forlist v_nm in <$fieldname>.<$entname>
   if ($lfileexists(v_nm))
      creocc "FILES"
      NM.FILES = v_nm
   endif
endfor
 
sort "FILES", "NM"
 
; reset the background image
<$fieldname>.<$entname> = "image"

In the first line I declared a variables block holding a string variable named v_nm. In the fifth line the forlist command extracts a value from my droptarget field and inserts it in the variable. After I checked if it the file exists, I add a record to my FILES entity and adds the variable value to the NM field in the entity.

The reference to <$fieldname>.<$entname> will be replaced during compilation with the actual fieldname. In my case DROPTARGET.DE.

If you are using Uniface prior to 9.5.01 you cannot use the forlist command. You should use a combination of getitem, delitem. I am assuming you know how to do this, if not here is an example:

variables
   string v_nm
endvariables
 
while <$fieldname>.<$entname> != ""
   getitem v_nm, <$fieldname>.<$entname>, 1
   delitem <$fieldname>.<$entname>, 1
 
   if ($lfileexists(v_nm))
      creocc "FILES"
      NM.FILES = v_nm
   endif
endwhile
 
sort "FILES", "NM"
 
; reset the background image
<$fieldname>.<$entname> = "image"

Picture this

The last line in the previous code might have given it away, but I am using an image to highlight the droparea. On the drop event this value is being reset to the list of files, so after processing I need to reset it. Otherwise I will be left with a grey target or even worse, a target screaming “!format” at me.

In the same location where we created the file valrep just minutes ago, I have added a value “image” and a representation “@droptarget.png”. The @ symbol implies that we are loading an image file named droptarget.png from the project folder and displaying it in the widget. The properties now look like this:

Uniface

Just get your own cool looking image file and play around with the properties to get it right.

To make sure the image is loaded on startup of the component we need to add two more lines to our component. In the EXECUTE trigger we add:

DROPTARGET.DE = "image"
edit

My component finally looks like this:

Uniface

Download for this drag n drop sample

Real Life Scrum: A Presentation to Technology Students in Amsterdam

On Tuesday December 1st, Uniface was invited to deliver a guest lecture at the Technical School in Amsterdam for the students who have ambition in the Technology area. From Uniface Berry Kuijer, JiaoJiao Xia and I were the representatives to share their knowledge, expertise and real-life experiences with the students.

The presentation started with an ‘Introduction of Uniface’ focusing on few key points, by Berry Kuijer:
-History and vision of Uniface
-Customers and the market span
-Business model
-Development and deployment
-A live Uniface application development demo

Next in line were Jiaojiao and I to give a presentation about “Scrum in Uniface lab.” We briefed the students about the software development methodology used for managing the product development in Uniface. First we explained how the agile-scrum methodology are being used in Uniface Lab, by maximizing the team’s ability to deliver quickly, to respond to emerging requirements and to adapt to evolving technologies and changes in market conditions.

Second part of the presentation was about showing the ‘bigger picture’ of scrum by giving a real life example and how to apply it in daily life. We gave an example of what started off as a simple story in the lab and then showed how it became more complex and larger because of additional requirements. We wanted the students to understand that in the “real world” of software development, you can’t always foresee everything in the beginning. With the example we gave—we realized more about the complexity of a feature and its impact on the existing software architecture while started working on the feature, and therefore how a particular requirement would than emerge bigger than it appeared before. There are of course many other examples of how things can change during the process of building software.

Uniface
Uniface Lecture Team

So we took them from defining the features (user stories) into the wish list (product backlog), proceeded by planning those into workable timeslots (sprints) while reviewing the progress on the daily scrums to present the finished result in the review or demo meeting. Concluding with the retrospective to reflect and learn how to improve the process by knowing what went well and what can be improved. This was emphasized while reviewing examples on how it worked in practice in our teams and with our product owners in Uniface. Finally, we told them that they could apply this methodology to their team assignments and their current studies or practices.

The presentation was well received by the students as the whole atmosphere was stimulated by interaction and interesting questions coming from the students. The concept of SCRUM was very clear and they could relate to our “real life” example when requirements change, get larger, etc. It was a great experience for us and we also believe that the students benefited from being exposed to the perspectives that the Uniface guest lecture team provided.

Styling entities and area frames in Uniface 9.7

In Uniface 9.7 we added powerful options to modernize your Uniface application without having to change your code.

Many applications need to run on many desktops and for our Value Added Resellers it may even run at various customer sites. Sometimes it is even a requirement that these sites use different color settings and logo’s. If you have to maintain this customized look using the Property Forms of the Uniface Development Environment it takes a lot of effort.

In Uniface 9.7 we took steps to make this easier:

  • We added new properties on the entity level that will enable you to make an entity (area) look nice.
  • We added a mechanisme to set these properties for individual entities in the .ini file, so outside of your code.
  • We made all graphical entity properties available for Area Frames too. These are only available  from the .ini file.

Bookstore Form without styling:

bookstore_old

Same Form with styling in .Ini file:

bookstore_new

The following example shows how areas on a form can be highlighted with a kind of card layout:

cards2

The Properties

There are properties for the border, the color, and image for the area frames and entities. Some of them are already exists for Shells, Windows or Entities in Uniface. The new property names “borderradius” and “bordercolor” are taken from the W3C standards on CSS.

Border Properties

BorderType
You can give your Entity or Area Frame different types of border.

  • Flat
    The border is one pixel in size and falls inside the area frame. This means that fields painted at the inner edge of a frame area overwrite the border. By default the border is darkgray. You can customize a Flat border with the BorderColor and BorderRadius properties.
  • Groove
    A groove border shows an edged border with a width of 2 pixels and falls inside the area frame. There is no gap between the colored area and the border.

The border that you can set in the Form Painter is separate from this and still works as it did. If you have a border in the Form Painter and have specfied the BorderType property, you will see both.

BorderColor
When you have specified BorderType=Flat, you can set the color of the border with BorderColor.
BorderRadius
When you have specified BorderType=Flat, you can set BorderRadius to give the border round corners by specify the number of pixels for the radius.
DropShadowColor
When you specify a DropShadowColor, your frame will be displayed with a shadow effect in the specified color.
borders2

Background Color Properties

BackColorFill
Defines whether the BackColor is shown as a solid color (BackColorFill=Flat) or as a gradient color (BackColorFill=Gradient). Flat is the default.
BackColorStart
When BackColorFill has been set to gradient, the color by default runs from white to the specified background color. With BackColorStart you can make the gradient start from any other color.
GradientStart
When you have specified BackColorFill=Gradient, you can use GradientStart to specify whether you want to start the gradient from the Top (default), Bottom, Left or Right.
colors2

Background Image Properties

BackImage
With BackImage you can specify an image that will be displayed as the background for the whole Entity or Area Frame. (Not per occurrence.)
HAlign
Set HAlign to Left, Right or Center to position the image horizontally.
HScale
Set HScale to a percentage to scale the image. Default is 100 (no scaling is applied).
PreserveAspect
Set PreserveAspect to True to preserve the aspect ratio of the image. The default is False.
VAlign
Set VAlign to Top, Bottom or Center to position the image vertically.
VScale
Set HScale to a percentage to scale the image. Default is 100 (no scaling is applied).

images

Attach Property

The Attach property now also works on entity and area frames.
All values (left,right,top,bottom, hmove, vmove, hsize, vsize) are supported. So in combination with setting the attach properties on fields, you can make resizable areas on your Forms:

attachframe

Setting the Properties

Altough the Entities and Area Frames have the same new properties, there are differences in the ways in which you can apply these properties.

Setting the Properties on Entities

Proc Code
You can set properties on entities using the familiar $entityproperties function. All new properties are dynamic so you can change colors etc. at runtime.

Property Form
For the Entity, some of the properties that are discussed in this blog already exist. You can set them on the Property Form for the Entity in the Development Environment. The really new properties can be set on the More Properties form.
entprops

.Ini file
In the .Ini file, the properties for entities can be set in the [entities] section.

Assigning properties to DefEntity applies them to all Entities in your application:

[entities]
DefEntity=udefentity(Properties)

For example, give ALL entities a border:
DefEntity=udefentity(BorderType=Flat;BorderColor=Black)

The practical value of setting the same properties on all entities is quite limited in a real application, so we also made it possible to set the properties in a more precise manner:

Entity{.Model{.ComponentName}}=udefentity(Properties)

For example, give the Customer entity a color on all Forms:
CUSTOMER.INSURANCE=udefentity(backcolor=powderblue;bordertype=Flat;bordercolor=navy;borderradius=6px)

This really allows you to control the look of your application without having to recode.

Setting the Properties on Area Frames

For Area Frames, the properties are exclusively controlled through the .Ini file. You set them in the [areaframes] section.

One option is to assign properties to “Frame”. The name “frame” is a special frame. This one is used for all frames that do not have a name or are not in the list of area frames in the usys.ini. This is necessary to allow an existing application to be “pimped” without renaming existing area frames. In most cases, the area frame does not have a name because the developer never gave it one.

[areaframes]
Frame=uframe(properties)

For example make all Area Frames blue:
Frame=uframe(backcolor=powderblue)

We also made it possible to set the properties in a more precise manner:

[areaframes]
FrameName{.ComponentName}=uframe(Properties)

For example give the INFO Area Frame a border on every Form:
INFO=uframe(BorderType=Flat;BorderColor=DodgerBlue)
Or give all Area Frames on Form CUST001 a shadow:
Frame.CUST001=uframe(DropShadowColor=Navy)
Or give the INFO Area Frame on CUST001 some properties:
INFO.CUST001=uframe(BorderType=Flat;BorderColor=DodgerBlue;DropShadowColor=Navy)

This really allows you to control the look of your application without having to recode.

 

Named Area Frames
The concept of named Area Frames may not sound familiar to you. In Uniface it always has been possible to rename area frames in the Form Painter, but it had practical use only when printing.

Area frames can have a name, which is used to address them from the usys.ini. The name can be changed in the Form Painter, and does not have to be unique.

In the Form Painter you paint an area frame:
areaframe_before
Then right click it:
areaframe_rename
Then select Rename:
areaframe_newname
Assuming that we have this in our .Ini file:

[areaframes]
bok=uframe(backcolor=dodgerblue;backcolorfill=gradient;dropshadowcolor=gray;backcolorstart=lightyellow;borderradius=20px;backimage=@4balls.png;valign=bottom;halign=left;PreserveAspect=TRUE;hscale=50;vscale=50)

When you click OK, you get the following in the GFP:
areaframe_after

Considerations

Attach Property
The widgets inside the area do NOT inherit the Attach property of the area.
So if the widgets need to move with the area, you need to give them an Attach property too.
Printing
The properties are ignored when the area frame or entity is printed. The scope is the GUI only.
Color Inheritance
Fields or widgets on top of the areaframe or entity will only inherit the backcolor property value and do NOT take the gradient into account when inheriting the color.
Form Painter
The Form Painter will display entity and area frames with the properties that are set in the .ini file. You will NOT see the effect of the properties set in the More Properties form.

Example

Same Entity, different properties:
different

 

Gartner Symposium, Barcelona: Strategic Decision Makers, Old Colleagues & a Famous Footballer!

This week, Uniface exhibited at the Gartner Symposium held in BarcelonaOur team was composed of representatives from marketing, sales and management, with the aim to promote Uniface, whilst also attending sessions held by Gartner and its sponsors. We also took the opportunity to interact with many other organizations that were exhibiting. We embraced the chance to speak to strategic decision makers, during which we had a number of very good conversations, illustrating the unparalleled strength of the Uniface platform and how it addresses the ‘challenges that keep CIOs up at night’.

We met many new organizations and partner prospects as well as existing customers, and lots of people who are part of the Uniface ecosystem. Some of those we met started their careers as Uniface professionals, a selection of which were over 20 years ago. They remained happy to see us going from strength to strength. We also met a world famous footballer!  

Uniface
Do you recognize this world famous footballer?

 Having spoken to one Gartner analyst, a key message that came across showed that the world is reacting to the concept of ‘business/mobile moments’, which manifests itself as having smaller focused apps that do one thing well. The huge monolithic applications we know today will transition to API services (i.e. a strong integrated backend) and there will be more targeted single function mobile apps. These will compose the enterprise mobile solutions of the near future. This significant change is touching many parts of the IT industry and the way consumers interact with technology.

To achieve this goal, it is important for organizations to explore and embrace modern approaches, including topics such as Agile, DevOps, Continuous Delivery etc…, all with the goal to improve software quality and the velocity of delivery. Annual release cycles of new solutions have become less desirable, with our industry tending to move to small incremental releases, regularly. Consumers are not worried about version numbers, they just want continual improvement. Given the proposed small changes with each regular release, solution adoption will be better accepted, because each change, although continual, will be gradual. Things will ‘feel’ familiar and evolutionary, rather than creating potential rejection through revolutionary change. This does not suggest the complete end to significant updates by the way.

Now this may sound like a big change to an organization’s way of working…..it is. So how do we address this is a sensible way? One answer is to take Gartner’s bimodal approach. We work in the new way for all new development and innovations, while at the same time continuing in the more traditional modes for existing items, then transition this old style over time. I’ve simplified bi-modal somewhat, however I hope you get the basic idea.

Uniface
Demoing Uniface to Gartner Analyst

I spoke to a second analyst who also provided some good common sense reminders we all forget from time to time e.g. “What is the best reason to try and reduce the cost of IT?” Some would say “to improve profits.” This seems like a sensible answer and can be, however, it is flawed. A better answer is “to allocate more of the IT budget to new innovation instead of regular maintenance.” Studies suggest up to 92% of resources goes into maintenance, leaving only 8% for innovation. It is innovation that makes the difference and yields success.

In a conversation with a third analyst, more aspects about future directions were discussed. Hot topics that came up were API’s (…second nature for Uniface), legacy integration/reuse (…another walk in the park for Uniface), web and mobile development (…please give me a challenge) and aPaaS (…you got me!). The last topic is very interesting and something for us to really think about. The market still faces challenges in this area and CIOs are also ‘kept awake at night’ by this. We also talked about the transition from traditional desktop GUI’s to web based and mobile. The trend is rapidly accelerating with the vast majority of new projects now being targeted at API services & mobile, whether that be phones, tablets, wearables or web.  

Given the four days spent interacting with many new analysts & organizations, I could write endlessly, so I will stop now and save some for another day. In the meantime, enjoy some pictures.

Uniface
Uniface at Gartner Symposium

Modernizing Uniface 9.7: The Buttons

In this final episode of the story about modernizing the Uniface 9.7 IDF in 10 easy steps I will explain how we changed the look of the buttons.

button teaser2

If you want to start reading from the beginning part 1 and 2 of the story can be found here:
The first post was about the changes to the start page.
The second post was about the work that was done to make the screens white.

Again, in theory, it should be possible to do this by just changing a few properties in a configurations file. But as you will see it takes a bit more effort to do it in a nice way in an existing Uniface application. Don’t get me wrong, even with the additional work it still was not much effort to do it.

The small tools that I made to make my life easier are available for download, but:

DISCLAIMER

The tools described in this posting are not supported Uniface software. You can download them and use them, modify to your own taste and use them at your own risk. You need the DICT model to be present in your repository before you can compile and use the tool. Be absolutely sure you have a backup of your dictionary before using any of these tools! You can download them here:
9.7 Modernization tool.zip Oct 26
When you make an improvement to these tools that might be useful to the community please share it.

Step 7 Determine types of buttons

Goal

Now that we changed the color of the Forms and fixed what was needed for that, we focused on the Command Buttons. The requirement was to use flat buttons.

In theory you would only need to change the properties for the Command Button in the .ini file for that. But we have different types of buttons in the IDF and we do not want to style them all in the same way. So we wanted to split up the Command Button in five logical widgets.

Logical Widgets

The first step was to split all buttons into groups and create logical widgets for them in the .ini file so they can styled as a group. These are the logical widgets that we used for the buttons:

IDFButtonBottom, for the big text buttons at the bottom of Forms
IDFButtonBottomIDFButtonBottom=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;frame=off;font=IDFButtonText;labelfont=IDFButtonText;backcolor=#01A7E1;backcolorselect=#97D5EC;backcolorhover=#55C1E8;backcolorfocus=#0084CC;forecolor=white;forecolorselect=black;vsize=80;autolabel=F;position=center;valign=center)

 

IDFButtonSide, for the big text buttons at the right-hand side of Forms
IDFButtonSide
IDFButtonSide=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;font=IDFButtonText;labelfont=IDFButtonText;backcolor=#01A7E1;backcolorselect=#97D5EC;backcolorhover=#55C1E8;backcolorfocus=#0084CC;forecolor=white;forecolorselect=black;vsize=80;autolabel=F;position=top)

Nearly the same as the bottom buttons.

 

IDFButtonSpecial, for the buttons that do not fall in any of the other categories
IDFButtonSpecial
IDFButtonSpecial=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;frame=off;font=IDFButtonText;labelfont=IDFButtonText;backcolor=#01A7E1;backcolorselect=#97D5EC;backcolorhover=#55C1E8;backcolorfocus=#0084CC;forecolor=white;forecolorselect=black;vsize=80;POSITION=CENTER)
Most of these buttons are somewhere in the middle of the window and need to look like a Bottom or Side Button. So we set the most common properties here and overrule them in the Forms when needed.

 

IDFButtonImage, for the very small buttons with an image on them, like the >> button
IDFButtonImage
IDFButtonImage=ucmdbutton(representation=Uniface;cursor=uhand;frametype=off;frame=off;transparency=T)
Here we make the button disappear, leaving just a clickable image.

 

IDFButtonHeader, for the buttons that form the headers of simulated grids
IDFButtonHeader
IDFButtonHeader=ucmdbutton(representation=Header;cursor=uhand;halign=left;valign=center;font=label)
These buttons are simple Windows header buttons.

Since flat buttons and clickable images may not look clickable to people who are not used to them, we added cursor=uhand to each button so the mouse arrow changes to a hand when you go over a button.
hand_pointer

Tool

Splitting the Command Buttons in these five logical widgets was a lot of work so I made a tool to assist in this mostly-manual step. I used the tool to query for fields with a Command Button widget, and in another window I looked in the IDF what new logical widget it should be. The main advantage of the tool for this step was making sure that I did not miss any buttons.

The tool is called U97_FRMWIDGETS. You can enter a retrieve profile and then work on the properties of the found painted fields. You can delete a property regardless of its value, or only when it has a specific value. You can also Add (or replace) properties in four ways: apply it to all records, do not replace existing values, only replace existing values, only replace a specific existing value. You can also apply a new widget type to all records.
U97_FRMWIDGETS

Step 8 Match modeled widgets with painted widgets

Goal

In the previous step we determined what painted button should get which new logical widget. But the Development Environment also uses buttons that are modeled in dummy entities in the application model. We want to give them a new logical widget too.

Challenge

You would expect that a modeled button is always used for that same purpose. But in an older application, such programming standards have not always been followed. So now one button in the application model needs to be represented by multiple logical widgets. The only affordable solution was to change the logical widget in the model to the one that is most often used for this button in the Forms.

Tool

The tool and the SQL that I used for this step was of such a ‘quick and dirty’ quality that I will not share this one with you. But it did the trick anyway, and you can easily come up with something similar (or better!)

Step 9 Set the properties on the painted buttons

Goal

We have split the buttons in logical groups by using logical widgets. Now we needed to remove the local properties so they do not override those set in the .ini file.

Widget property inheritance

Challenge

It would be simple if we could just delete all properties of all buttons, but that was not feasible as there was a mix of properties that should be the same on each button and of properties that are specific for a certain button.

Tool

I used my tool U97_FRMWIDGETS from step 7 to remove all properties except ROLE and VSIZE from the IDFButtonsBottom. And I removed all properties except TOOLTIP and VSIZE from the small image buttons. This now allows us to control all other properties from the .ini file.

Step 10 Set the properties on the modeled buttons

Goal

For the modeled buttons we also needed to remove many properties. As they often did not have properties on the Form, the properties from the Model took precedence over the .ini file instead.

Widget property inheritance

Challenge

The challenge was to efficiently change the properties of modeled buttons.

Tool

The tool is called U97_MODWIDGETS. It is similar to the tool of step 7, but acts on a different entity of the DICT model. For more details see step 7.

U97_MODWIDGETS

Conclusion

We here at Uniface B.V. have a big Uniface 10 project running to change the architecture of the Uniface Development environment. But we still wanted to do a very small project to freshen up the appearance of Uniface 9 as well. I think we succeeded in that, thereby proving that it is affordable to apply some lipstick to an existing Uniface application.

Wishes

Making the background of all screens white showed up some things in our GUI that can be improved in the future.

  1. The frames and sizes of our widgets are not fully consistent. That was nicely camouflaged by the grey background of the forms, but it shows more clearly on a white background.
  2. The new entity frame properties work fine and allow you to really spice up your application. We will get a blog post up on this soon. But in a multi-occurrence situation, where the entity is made to look like a grid, there is room for further development. There is no room for the frame, causing some visual imperfections.
  3. We have buttons that used to have an image on them in Uniface 7, but not since then. These are still image buttons. In previous Uniface versions that was not a problem as we used a Windows representation for the buttons and that ignores the image. But in Uniface 9.7 we use flat buttons with a Uniface representation and there the image prevents correct centering of the text. We could not find an affordable risk-free solution within the scope of the project so we decided to deliver with this imperfection in place. We will let you know when we have a good approach for this.

These and some smaller issues have been logged during the project and have been put in our backlog for resolution at a later date according to priority.

I hope these posts on how we changed the look of our Uniface application were useful for you. Have fun modernizing your Uniface application!

With kind regards,

Theo Neeskens