Use your forum account to login.

LOGIN

TOP Contributors

  1. MikroElektronika Team (475 codes)
  2. Shawon Shahryiar (247 codes)
  3. Alcides Ramos (99 codes)
  4. Dany (66 codes)
  5. O B (62 codes)
  6. MikroBUS.NET Team (35 codes)
  7. NART SCHINACKOW (34 codes)
  8. Alberto Trasimeni (25 codes)
  9. Roman Toropov (25 codes)
  10. Arezki YOUYOU (24 codes)

Most Downloaded

  1. Timer Calculator (79618 times)
  2. Network Ethernet Library (38441 times)
  3. FAT32 Library (37747 times)
  4. USB Device Library (29128 times)
  5. Network WiFi Library (27736 times)
  6. FT800 Library (20580 times)
  7. PID Library (19212 times)
  8. GSM click (18754 times)
  9. microSD click - Example (16121 times)
  10. GPS click - Example (12876 times)
Libstock prefers package manager

Package Manager

We strongly encourage users to use Package manager for sharing their code on Libstock website, because it boosts your efficiency and leaves the end user with no room for error. [more info]

< Back
Library

DynTFT

Rating:

Author: VCC _

Last Updated: 2018-01-07

Category: Graphics & LCD

Downloaded: 37 times

Not followed.

DynTFT is a set of visual components, inspired by Delphi's VCL. These components are compilable by mikroPascal, Delphi and FreePascal, allowing faster designing and debugging of the UI part of an application. The API features a runtime component registration, to make sure that users won't have to deal with internal handling of mouse/touch events.

No Abuse Reported

Do you want to subscribe in order to receive notifications regarding "DynTFT" changes.

Do you want to unsubscribe in order to stop receiving notifications regarding "DynTFT" changes.

Do you want to report abuse regarding "DynTFT".

  • Information
  • Comments (3)
DOWNLOAD LINK RELATED COMPILER CONTAINS
mikroPascal PRO for PIC32
  • lib
  • src
  • exa
  • hlp
  • hex
  • sch
  • pcb
  • doc

Library Blog

DynTFT is a set of visual components, inspired by Delphi's VCL. These components are compilable by mikroPascal, Delphi and FreePascal, allowing faster designing and debugging of the UI part of an application. The API features a runtime component registration, to make sure that users won't have to deal with internal handling of mouse/touch events, and no hardcoded list of component types has to be maintained. DynTFT components use dynamic memory allocation, allowing them to be created and destroyed at runtime. Users can write their own custom UI simulators, building upon the provided templates. Compiler differencies are handled by the means of using compiler directives. Although the code was tested on PIC32 and PIC24, it might work on other architectures as well.

There is no 8-bit support.

Features / Advantages:
 - The code can be compiled in mikroPascal, Delphi and FreePascal.
 - All components are created in RAM memory, allowing to be destroyed when no longer needed. For example, a button can create a scroll bar, set the event handlers, then destroy itself.
 - A template high-level simulator is provided, so users can design and simulate their own GUI on desktop. Much of the code will work the same on microcontroller.
 - DynTFT allows faster design of the GUI, by simulating it on PC instead of flashing the microcontroller at every change.
 - DynTFT allows debugging application logic of some non-GUI applications, by creating a debugging GUI and simulating application parts (e.g. state machines).
 - Using the same memory manager on desktop as on microcontroller, memory addresses are more predictable, making bugs easier to reproduce.
 - Using the simulator, various use cases which lead to out of memory, can be identified before verifying the application on microcontroller.
 - Access violations are easier to debug on desktop than on microcontroller.
 - New components can be added as plugins (component type registration at run time).
 - When compiled for desktop (Delphi or FreePascal), the "constructors" raise exceptions if creating unregistered components.
 - Components can be used hierarchically, e.g. a listbox contains items and a scroll bar. The scroll bar contains two arrow buttons and a dragging panel. etc.
 - Mouse and touch events are handled in the same way.
 - Some of the repaint events are handled internally, without user intervention, e.g. showing/hiding or enabling/disabling a component.
 - Various events are internally propagated from subcomponents to parent components, for a proper handling on all levels.
 - At the expense of one additional pointer / component and a bit of processing, the internal structure (simple linked list) is isolated from visual components.
 - Components are organized in screens (each screen has a linked list of components) and multiple screens can be active at the same time.
 - Only active screens can process events. Screens can be activated/deactivated from any event handler.
 - Components have focus support. It will be needed when implementing keyboard support.
 - Multiple components can be destroyed from a single "destructor" if they are allocated one after the other (range of components). This is useful when a component has multiple subcomponents.
 - When a component is destroyed, it repaints the area, which can be a screen, a parent component or other unrelated components.
 - If some projects require custom component properties or event handlers, they can be defined in an .inc file and enabled from project-level definition.


Limitations / Disadvantages (version independent):
 - Compiler directives have to be used at every piece of code which contains event handler assignments, in order to make the code work on all compilers.
 - Creating new components, requires extra care at defining component structures, because pointers to event handlers, must be Word or DWord aligned, depending on architecture.
 - Although components can be structurally inherited, access to base component properties must be done by specifying them as part of the hierarchy, e.g.: DerivedComp^.BaseTypeComp^.BaseProps.Left := 30;
 - The amount of allocated memory may be different between 32-bit and 16-bit architectures.
 - OnMouseMove events are triggered only when mouse button is down. This is to make both touch and mouse events work the same.
 - FreePascal projects must be configured to compile in Delphi mode. This would be an issue if parts of a FreePascal project must be compiled in default (FreePascal) mode.
 - A lot of typecasting has to be done, because components are simple structures not classes.
 - All components use absolute coordinates (Left / Top), regardless of their parents.
 

Limitations / Disadvantages (in current version):
 - There is no automatic event triggering on value change (e.g. OnTextChange, OnPositionChage, OnAddItem), except for ScrollBar. Calls to Repaint have to be manually added when updating properties.
 - Listboxes can't display partial items. Empty space will be displayed at the end of a listbox.
 - Scrollbar dragging buttons are not resized based on scroll page length.
 - Can't set focus to a component from another's component handlers and properly clearing the current focused component.
 - Assigning event handlers must be done in two ways each time, using compiler directives. Function pointers are not compatible across compilers.
 - Limited support for Z order (there is a "BringToFront" procedure). In case of overlapped components, the one which is created before the other(s), will process the events.
 - A page control does not have pages. It provides the same functionality as a radio group.
 - Clicking on a component, outside of a ComboBox, to close the ComboBox, does not allow the event to be handled by pressed component.
 - Text or Caption properties of components which implement them, have fixed length.
 - ListBoxes, RadioGroups and PageControls use fixed-size arrays to store pointers to their elements. These sizes can be changed from external constants.
 - The Edit component does not have text selection support.
 - Scrollbars do not have fast scroll support (i.e. scrolling by clicking between buttons). Because of this, a ComboBox will be closed if clicking its ScrollBar between buttons.
 - Only internal font is supported for now. To use other fonts, a function should be reimplemented. (See FAQ)
 - RadioButtons do not work outside RadioGroups. There would be not a much of a benefit to implement this.
 - Some components lack useful features, like autoarrange items in RadioGroup or PageControl. For now, each item must be manually positioned.
 - A PageControl can't scroll tab buttons if they take more space than displayable.
 - Moving a component across a screen, requires manual repainting. There is however a procedure which can repaint all components from a given area.
 - Components cannot be moved from one "screen" to another (from one parent to another), on run time. However, this can be implemented.
 - A ComboBox drops down by default. It must be configured manually to drop up (or elsewhere) if there is no enough space below it.
 - There is no OnClick handler yet. OnMouseUp should do the job on most cases.
 - Screen color is not fully implemented. Applications will have to draw a screen-sized rectangle at startup. Destroying/hiding components will repaint the screen with assigned screen color.

Known issues / other info:
 - Clicking on an editbox does not always place the caret properly.
 - Some of the provided examples contain hardcoded paths. Because of that, all the three folders, DynTFT, DynTFTDocs and DynTFTSim, must be extracted in D:\, so the paths would be D:\DynTFT, D:\DynTFTDocs and D:\DynTFTSim .

Areas that might change:
 - The Items, RadioGroup and PageControl components should allow dynamic creation/deletion of their elements. At the moment they used a fixed-size array to store elements.
 - Various constants may be moved to external constants (like array lengths).
 - Some datatypes, compiler directives and functions/procedures may be renamed.
 - Adding (important) features, on complex components may lead to various changes in subcomponents, like enabling internal event handlers. This will cause the code to grow.
 - Other stuff as a result of bug fixing.

DynTFT Simulator

DynTFT Simulator

main window

View full image
Screen1 - 320x240

Screen1 - 320x240

Buttons, arrow buttons and a panel.

View full image
Screen1 - 480x272

Screen1 - 480x272

Buttons, arrow buttons and a panel.

View full image
Screen1 - HW

Screen1 - HW

Buttons, arrow buttons and a panel. mikromedia for PIC24EP. mikromedia for PIC32MX7

View full image
Screen2 - 320x240

Screen2 - 320x240

CheckBoxes, ListBoxes and ScrollBars.

View full image
Screen2 - 480x272

Screen2 - 480x272

CheckBoxes, ListBoxes and ScrollBars.

View full image
Screen2 - HW

Screen2 - HW

CheckBoxes, ListBoxes and ScrollBars. mikromedia for PIC24EP. mikromedia for PIC32MX7

View full image
Screen3 - 320x240

Screen3 - 320x240

Labels and RadioGroups

View full image
Screen3 - 480x272

Screen3 - 480x272

Labels and RadioGroups

View full image
Screen3 - HW

Screen3 - HW

Labels and RadioGroups. mikromedia for PIC24EP. mikromedia for PIC32MX7

View full image
Screen4 - 320x240

Screen4 - 320x240

Editbox and VirtualKeyboard.

View full image
Screen4 - 480x272

Screen4 - 480x272

Editbox and VirtualKeyboard.

View full image
Screen4 - HW

Screen4 - HW

Editbox and VirtualKeyboard. mikromedia for PIC24EP. mikromedia for PIC32MX7

View full image
Screen5 - 320x240

Screen5 - 320x240

ListBoxes, ComboBoxes and Labels.

View full image
Screen5 - 480x272

Screen5 - 480x272

ListBoxes, ComboBoxes and Labels.

View full image
Screen5 - HW

Screen5 - HW

ListBoxes, ComboBoxes and Labels. mikromedia for PIC24EP. mikromedia for PIC32MX7

View full image

FAQ:
 - Where is the documentation?
     In work.

- What is the purpose of the DynTFT simulator?
     Since the DynTFT library/infrastructure is pretty complex, it was designed to be compilable both for microcontroller and desktop. The desktop application is the simulator.
     Users are adviced to test as many application features as possible by writing this kind of code, because debugging on the microcontroller would be more difficult.
     Each application should have its own derived simulator (derived from provided template), with its custom features.

- How do I start using DynTFT?
     Start by modifying provided examples. Some files should always be shared between Delphi/FreePascal and mikroPascal projects, like: DynTFTGUI.pas, DynTFTGUIObjects.pas, DynTFTHandlers.pas and some .inc files (e.g. DynTFTColorTheme.inc)
     Each .pas file should have an equivalent .mpas file, which includes the former.

- What if there are type/var/func/proc name collisions between DynTFT and the user application?
     Most variables, functions and procedures are prefixed with DynTFT to avoid such collisions. Not sure what to do with the remaining ones.

- Some components do not work as expected. How do I know if it's a bug?
     For starters, see "Limitations / Disadvantages" sections. Indeed some components have incomplete implementation. Others work in a particular way by design. And.. yes, there may be bugs in some components.

- There is no OnClick event, and the OnMouseUp one is fired even if releasing the mouse ouside the pressed component. When will this be implemented?
     It will be implemented when the time allows. This may also be placed under a compiler directive, because not all applications need it.

- How do I change the font?
     At the moment, all components will use the same font. It can be changed by reimplementing DynTFT_Set_Font procedure in DynTFTUtils.pas.

- How do I create my own custom component?
     At first, identify if your component requires existing components as subcomponents or not. Then, look at how existing components are created. They follow a template.
     Each component should have its own unit and implement a set of functions/procedures like: Draw<CompName>, <CompName>_Create, <CompName>_Destroy, <CompName>_DestroyAndPaint, Register<CompName>Events and Get<CompName>Type.
     You can start by copy-pasting an existing unit. Then, rename everything to match your component. Do not use the DynTFT name, because it might collide with some future implementation of the same component from the DynTFT library.
     Pay extra attention at complex components (those which use subcomponents), because subcomponents data types are available in your code and typecasting to them instead of the main component, may lead to problems.

- No automated regression tests?
     No, not at this time. The whole thing started as a hobby experiment. It was not designed with automated testing in mind.
     Again, time will tell when and if there will be tests. Indeed, they would be very useful when implementing features and fixing bugs.

- How much is this library expected to grow and in what direction?
     New components should be added, but new featues of the infrastructure should not go too far. This is because the code may already be to big for a microcontroller application.
     Fancy/exotic features should be placed under compiler directives, to keep the code small in most cases.

- How do I change the visual appearance of the provided components?
     At the moment, only the colors can be changed, by providing new .inc files with color constants. Other visual aspects can't be changed. Fonts can be changed with some limitations, see above.
     If more than colors must be changed, then new custom components must be created.

- How do I use the generic "constructor" and "destructor"?
     There is a generic "constructor" and a generic "destructor", which can be called by knowing the component registration number only.
     They can be used to create and destroy all components, regardless their type. This requires enabling the RTTIREG project-level definition.
     Calling the generic "constructor" and "destructor" also requires knowing in advance the order of the registered components. Their types are index-based.
     A small description about how they work can be found in DynTFTBaseDrawing.pas, at the implementation of DynTFTComponent_CreateFromReg "constructor".

- Why the 16-bit architecture requires less memory than a 32-bit one?
     Some data types contain architecture-dependent structures and can be better packed in 16-bit architectures.
     Since the simulator reports the memory usage for 32-bit, the 16-bit one should not be a concern.

- Why components are "stored" in isolated linked lists?
     This is by design, to support non-visual components, which do not contain properties like Left, Top, Width, Height etc, so allocation would not be user's job.
     At the moment, the infrastructure does not support non-visual components, so all of them must contain the BaseProps field in their structure.
     Because of this, the component data type "registry" reserves type 0 for screens and negative values for non-visual components. All the others use positive values, in the order they are registered.
     Another reason was to isolate the linked lists from user code, to make memory corruption a bit "safer". Thus, each item of a list, points to a component instance.
     If some components require usage of these lists, they should do it with extra care.
     Another benefit of the linked lists, is the ability to create big complex components, without keeping a separate pointer to each of their subcomponent. For example, the VirtualKeyboard stores only two pointers, to the first and to the last created keys. Thus, all the keys ca be "range destroyed" in one call.

- Some components do not implement all internal event handlers. Why is that?
     At the moment, this to reduce code size. If other complex components will be created, some internal event handlers may have to be implemented as well. This will increase code size of unrelated applications.

- There are many compiler directives. Which is which?
     There are four types
       1. Those which enable/disable code across compilers, i.e. "IsMCU" and "IsDesktop"
       2. Those which define bitness, i.e. "AppArch32" and AppArch16.
       3. Those which enable/disable features, e.g. "RTTIREG" or "ComponentsHaveName".
       4. Those which control if user code should be included/linked into DynTFT units, like data types, other units, component properties, colors and color themes etc.
     The first two types are automatically handled. The others should be project-level defined. Since documentation is not ready, you must look at the code to understand what should be defined and where to include user code.

- Why so much typecasting?
     The main reason is because datatypes are partially the same and can be overlapped in memory. Some typecasting is required by the language rules themselves. Others, to avoid warnings/errors.
     Anyway, handle this with extra care, if using custom component "properties" on generic data types. You should always know what a pointer points to.
     Most (if not) all typecasting involves the TPtrRec data type, to avoid compiler warnings. Normally, this would not be required because this data type is simply the type of pointer, i.e. Word or DWord.

- Why having a wrapper over TFT library?
     Not all applications use TFT compatabile displays, so the DynTFTUtils library allows user code to be included. It was much more practical to wrap each TFT call, than using compiler directives each time.


Troubleshooting:
 - Why the microcontroller keeps resetting either on application startup or on handling some event?
     Make sure all used components are registered in RegisterAllComponentsEvents procedure from DynTFTGUI.pas. The simulator should tell you about this. If it doesn't, make sure the Delphi/FreePascal and mikroPascal apps are using the same files.

- Why some/all components do not handle events at all?
     Make sure the screen they belong to, is active. See SetScreenActivity procedure from DynTFTGUI.pas. Screens can be activated/deactivated when needed.

- The simulator's log turns pink (red was to hard to read) and an exception/error is mentioned.
     You should debug that application and not deploy it in that state to microcontroller. It won't be easy to debug it on microcontroller.
     Some debugging features are available in simulator only. Make sure the application works as expected on simulator.

- mikroPascal debugger won't step into the .pas units, because they are included with {$I} in .mpas files.
     This is a debugger limitation and if you really want to enter those units with debugger, copy-paste their contents into the required .mpas files.
     As soon as the problem is solved, switch back to "include .pas" mode. This is to avoid the need to keep files (.pas and .mpas) in sync.
     Also, make sure each mikroPascal project will share the files with a Delphi/FreePascal project. Do not share GUI files between projects. This will lead to a mess.

Random components

Random components

Components: Button, ArrowButton, Panel, CheckBox, ScrollBar, ListBox, Label, RadioGroup, PageControl, Edit, VirtualKeyboard, ComboBox

View full image

ALSO FROM THIS AUTHOR

All Tools

All Tools is an application, which allows more than 10 user tools to be started from a mikro IDE. It is a menu-based design, as opposed to a list of buttons, thus taking only one button space on the IDE. For each installed tool, two more applications can be executed, one before the tool, and the other, after the tool.

[Learn More]

RTCC_18FxxJ50 library

Library for accessing the PIC18FxxJ50 internal RTCC. The library should be compatible with other PICs with same RTCC.

[Learn More]

PIC32 Memory Statistics

The purpose of this tool is to display a chart containing the memory allocation in a PIC32 project.

[Learn More]