Jump to content

Joel Bodenmann

Administrators
  • Posts

    2,653
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by Joel Bodenmann

  1. Hello Sillvers! Is it possible for you to provide us with a minimum working example (main.c, gfxconf.h, the actual original image and the converted image) so we can easily try this ourselves? That would save us a heap of time setting up a new project Note that you can easily upload a .ZIP archive to your post. ~ Tectu
  2. Happy to help! ~ Tectu
  3. Assuming that you are using the existing image rendering routine for the button widget you just have to change the image that's being passed through the custom parameter. You do that by calling gwinSetCustomDraw() again and just using a different parameter. Note that as you only change a pointer the GWIN module doesn't know that it has to redraw the button widget. Therefore you have to issue a redraw manually using gwinRedraw() after you modified the image pointer. Keep in mind that the image passed to the rendering function must be opened already. You might also want to close the previous image - depending on your needs. Important note: When you just want to show a different image for when the button is released and when the button is pressed to make a visual "Click" effect then that has already been done for you! The existing image rendering function for the button widget can take an image that's either one, two or three times the height of the actual button. This way you can stack the image for the 'released', the 'pressed', (and optionally the 'disabled') state on top of each other and use that as one image. The button widget will automatically render the correct one depending on its current state. You can find more information about this in the API documentation and by using the forum search. This is also already supported by the uGFX-Studio. If you select the image rendering function on a button then you can not only submit the image path but also specify how many images you have (1, 2 or 3). ~ Tectu
  4. If the currently existing label widget does everything for you and you only want to make it look different then the right way to implement a label with a transparent background is to write a custom drawing routine which is explained in this article (please do not hesitate to ask if something in that article is unclear). Inside that drawing routine you'd use gdispGDrawStringBox() instead of gdispGFillStringBox(). Note that you can dynamically change the used rendering routine during runtime by using gwinSetCustomDraw(). You can pass built-in rendering functions to that function too. Otherwise, depending on your needs, you can write a custom rendering function that conditionally clears the background or not. You can use the custom parameter for this. The nice thing about a void* is that you can either just pass a boolean or an entire configuration struct should you have more complex needs and still want to avoid writing a custom widget. If by user you mean the person that uses the uGFX library (the developer of the firmware) then he has to know whether he wants to use a transparent label or not. It depends on the application. As mentioned in another thread using transparent labels doesn't make a lot of sense because when the label text changes you are forced to clear the area somehow. If it's not done inside of the label rendering routine you'll have to do it externally by refreshing whatever is below the label which kinda breaks the purpose of having a window manager in the first place. In my opinion having the need for a label with transparent background is a strong indication that you'd want to write a custom widget instead. It again depends on your needs. If you for example want a label with a transparent background because you want to make a button with an image then use the existing image rendering routine of the existing button widget instead. It will draw the image and then the text on top of it so it behaves like it's a label with transparent background. If you have more specific needs write your own widget where you render the text on top of whatever it is by using one of the GDISP text drawing functions that doesn't fill the background. One of the limitations of the GWIN module is that each widget must be able to clear it's own background. This is a limitation we decided to have in order to keep the resource requirements as low as possible. So far the only exception we made is with the container where we supply a transparent rendering function because containers can be used to just logically group other widgets. I'm afraid I am not sure whether I understand what you mean. If you want to be able to conditionally clear or not clear the background of a label then using a custom rendering function and using the custom parameter for this as explained above is the right way to go. If you have more complex needs you could add your own color format that supports transparency (eg. ARGB). That however will be more work than just writing your own widget (again, depends on what you want to archive). Two main reasons for that: 1) We feel that the two functions behave very differently and distinguishing them is easier by just looking at the function name rather than searching for some parameter hidden in the already very long list of parameters. Also, that parameter would either be a boolean value which would make it very hard to guess what the function really does for somebody who's reading the code or it could be a flag which would be harder to remember. 2) We found that some compilers are having serious issues with passing function pointers conditionally which would be requires when using one function and just enabling/disabling the background filling by a function parameter. It's possible that there are other reasons why we settled this way. The code was written a long time ago and with increasing complexity of the uGFX library we can't remember every decision anymore. inmarket might have a follow-up on this one. After all it can just be a personal and very subjective preference as to point 1) and that it's possible to optimize this. I hope that helps ~ Tectu
  5. The usage text states: "filter ... Remove everything except specified characters."This means that you can specify multiple ranges after the filter keyword and the corresponding file. I assume that filter foo.dat should work. ~ Tectu
  6. The limiting factor regarding multiple filter ranges is the web interface (the online converter), not the actual converter itself. You can manually convert your font using the font encoder which you can find under /tools/mcufontencoder/. The filter parameter takes an unlimited amount of range parameter. We should probably add this option to the online converter as well ~ Tectu
  7. Please have a look at this article: http://wiki.ugfx.org/index.php/Font_rendering It will lead you through the process of adding your own fonts (see the Adding fonts) section. The article contains links to both the online font converter as well as to a wikipedia page that contains tables for all languages to figure out the required filter range. Back when we added unicode support we even created a dedicated article talking about Cyrillic: http://wiki.ugfx.org/index.php/Cyrillic It's currently not possible to specify multiple filter ranges. If the gap is big enough it might make sense to simply generate two font files. We hope that helps. ~ Tectu
  8. That is what the uGFX-Studio is supposed to become eventually: A tool that allows to design a complete GUI within minutes. However, the studio is a long way away from being that tool. The uGFX-Studio is currently a side project and we try to focus on working on the actual library instead. But even if we'd make the studio become our main project it would easily take a year or more to make it become a tool that is powerful enough to handle every-day GUI designing requirements. As inmarket mentioned the uGFX-Studio was initially supposed to become nothing but a simple layout assistance tool. User feedback suggested that it should become a full GUI design suite instead and that is what our goal has become ever since. It just that we currently don't have the resources to put more time into developing the studio. The µGFX library is supposed to be (as the name suggests) a very small and fast library. Whenever we write a single line of code we have to ask ourselves how we can keep both the CPU time and the memory requirements at a bare minimum. That is one of the reasons why everything is modular and why so many features (and sub-features) are completely optional. If you don't need to draw circles your compiler won't even see the circle drawing code. If your hardware provides hardware accelerated circle drawing we will take use of that and so on but everything needs to be able to run on any platform. There are many users who use the uGFX library on a very small ultra-low power device. These microcontrollers often don't provide more than slow 16-Bit CPUs with only a couple of kilobytes of RAM and are powered by batteries way below the 100mAh mark. Every microsecond the CPU is active counts in these applications. That is why the GWIN module only implements very basic functionalities. For example it's not possible to loop through widgets in both directions as we use a singly-linked list for that. Neither is it possible to handle overlapping widgets as you have discovered. However, if you need that and if you can spare the resources you can just write a your own window manager and use it by just calling one simple function that registers your own manager. We are certain that we'll have more than just one built-in window manager in the future so that users with more complex needs will have an out-of-the box solution but we currently lack the man power to do all that and as we provide easy to use interfaces for people to do it themselves we think that things like that are a relatively low-priority task compared to other features. Also note that after all we target embedded applications most of which are running no very low resolution displays. These types of applications usually just require a very static user interface. Unlike with a desktop computer the user usually doesn't need (or expects) to move around windows or minimize and maximize dialog boxes. That is why we spare every byte we can and hence the reason why, for example, you can't dynamically change the parent of a widget. We will never be able to satisfy 100% of all needs but given our focus on providing highly flexible interfaces for customization wherever we can we think that we are on the right track. It's mostly just a matter of time to implement more widgets, more built-in rendering functions and more window managers to meet the needs of more uses. That is the point where you are supposed to write your own custom widget. Custom rendering routines are an easy way to quickly modify the look'n'feel of existing widgets. But when you need behavior that is not already supported by an existing widgets you have to get one step further and write your own widget. And in all cases we focus on providing a highly flexible yet very easy to use interface. The existing facilities such as the GWIN core module, the GDISP module and so on take care of any difficult such as word-wrapping that you mentioned in a previous post. It's just a matter of calling the corresponding GDISP function that draws a string in a box using word-wrapping inside your widget drawing routine to have a widget with a text label that is automatically word-wrapper. If you need an image, just use the GDISP function that draws an image in your widget rendering function and you're done. The GWIN module will take care of coordinate translations, visibility, enable/disable state, event propagation and so on without you having to worry about anything like that. Just create a new widget (you can copy an existing one that matches your needs the best such as the button widget), name it differently (for example "Unit Label"), modify the mouse handling functions to iterate through your four different states and implement a default rendering routine and you are done. No magic (or hacking or work-arounds) involved. And as always we are here to help if you have any questions. First of all it will have an impact on resource requirements. Even if it's just so little and totally negligible for your hardware platform it won't be for others. And secondly - and probably in this case the more important point - it will break the philosophy behind uGFX. The main goals of the uGFX library are to be very platform independent. We want to be able to run the exact same application code on a small, slow and stupid 16-bit microcontroller with a few kB of RAM and on a multi-core high performance platform with gigabytes of RAM and CPUs running in the GHz section. For that we need to do two things: 1. Everything needs to have as low resource requirements as anyhow possible and 2. everything needs to have a highly flexible and modular interface. This results in implementing something like the GWIN widget system by just focusing on the bare minimal functionalities (behavior) for each widget as inmarket mentioned. The thing that will vary from use to use is just the visual representation (the rendering function). In uGFX you can take an existing widget and just change the rendering function or you can write your own widget. You can even write your own window manager and using it is in all three cases just a matter of one line of code. Most other embedded GUI libraries don't provide you with this freedom. See above. We are pretty confident that you won't find an embedded library that will give you more flexibility in any regard. In any case you just should never take the uGFX-Studio into account when thinking about the actual uGFX library. We are light years away from having an uGFX-Studio that can represent the power of the actual uGFX library. ~ Tectu
  9. We didn't know that you were actually using an imagebox for your container background. Using the image rendering function for the container is of course a lot faster as you've seen Note that you can further increase performance by caching the image (in case of it's an encoded format such as GIF). Caching an image keeps the decompressed image in RAM so drawing the image is just a matter of pushing out the pixels from RAM. In case of the STM32F7 with using the LTDC interface this is blazingly fast. Also make sure that your DMA2D is enabled to free even more CPU resources. You can find more information about image caching here: http://wiki.ugfx.org/index.php/Images#Caching ~ Tectu
  10. That is exactly what custom rendering functions are meant for! The widget just implements some logic - the look'n'feel can be implemented by the user of the widget however he wants. Inside the drawing routine you can use any of the GDISP drawing functions. As Word-Wrapping is also implemented inside those GDISP functions you can easily make a button look like a label while still having word-wrapping and so on. Note that in case of your microphone button with the two volume level indicators we'd still strongly recommend writing a custom widget for that. As mentioned before you can copy paste the corresponding parts of the rendering routine of the progressbar widget to save yourself some time. As inmarket mentioned the uGFX-Studio is in a very early stage. It will take ages to make it become a fully featured GUI designing tool. Right now it's helpful to get started and to create quick drafts of your final GUI. Please note that the uGFX-Studio website as well as the "New Project"-Dialog inside the studio itself clearly state that the studio is in a very early beta stage and that it is NOT meant to be used in a productive environment. Right no we don't even guarantee that project files between different studio versions are compatible. The studio has a long way ahead of it but feedback from users like you help us to improve it quickly. We plan to release the first real version within July 2016. ~ Tectu
  11. There's nothing that prevents overlapping images and this should work just fine without any problems at all. Most likely it's just that your GFILE_MAX_GFILES is not set to a large enough value (assuming that you're using ROMFS). This would prevent the second gwinImageOpenFile() call from succeeding which would result in the second image box not rendering the image which would just leave the widget area cleared with the current background color and therefore hiding the image of the underlying imagebox (which would be the case anyway). ~ Tectu
  12. That's true - as long as nothing inside the same part of the uGFX code changes that will make applying the patches fail That's a very interesting use case and we haven't thought of something like that! We'll discuss adding click events for all widgets. Thanks for your feedback! ~ Tectu
  13. We agree with everything that you are saying and the most proper solution to solve your task the best way is to write that custom widget. It will not only take less time now to write that widget (as you can copy paste most of the code of existing widgets) but will also save you time when upgrading to newer uGFX versions in the future. The only argument I can't argue with is that the uGFX-Studio currently doesn't allow you to place custom widgets. I guess that should become a more important task too. Maybe we should even provide a temporary solution for the 0.13 release - not sure. What I can recommend you to do in the meantime (in case of you write custom widgets) is to place a dummy widget such as a console window and then just replace the code (manually by hand) once you're done. After all the studio doesn't offer much advantages besides placing the components at the moment. We appreciate any contributions whether they are bug reports, fixes or just patches for implementing different behavior. Things like this don't only help ourselves to improve the library over time but might also be useful for other users that face a similar problem. ~ Tectu
  14. When you want a background image for your container it is strongly recommended to use the corresponding rendering routine for the container: gwinContainerDraw_Image(). That function takes the gdispImage pointer as parameter and will use the supplied image as the background of the container. That will not only solve your problem but will also be a much more robust and less resource hungry solution. The corresponding API documentation will give you more information about using this rendering function: http://api.ugfx.org/master/group___rend ... adfa961280 ~ Tectu
  15. In order to make the label and the progressbar widget sending events you will have to modify the actual widgets code. What you need to do is implementing the MouseDown function and register the corresponding function pointer in the widget VMT. You can find the definition of the GWIN widget VMT in /src/gwin/gwin_class.h. However, for your particular case I would STRONGLY recommend following the advice I gave in your other thread (viewtopic.php?f=9&t=341#p2546) and implement a custom widget that does what you want for the following reasons: This is the intended usage of the GWIN module It is proper as it doesn't include any hacks or work-arounds It's a portable and future proof solution. You can upgrade to newer uGFX versions in the future without any hassle as all your custom code is outside of the actual library. Thank you for your feedback. We will consider this for future releases. ~ Tectu
  16. Note that a progressbar is just a passive element like a label. It's only purpose is to provide a visual representation of something. A progressbar shows a state of something - the user is not supposed to interact with the progressbar. If you want a progressbar where the user can change the value then you want to use the Slider widget. In fact, the default rendering functions make them look very similar - just that the slider accepts mouse input while the progressbar doesn't take any input at all. ~ Tectu
  17. Well, in this case it's not a workaround as being able to submit custom rendering routines is expected usage and in fact one of the main goals of the GWIN modules: Everything is supposed to be fully customizable. That is also the reason why you can submit your own window manager. Most other libraries don't offer this Note: Judging from the screenshots that you've shown in the uGFX-Studio thread it seems like you only need to be able to stack widgets because you want a special button that shows an icon, two volume levels and a text. Personally I think that in your case it's the best solution to write your own widget that does exactly that. I guess 90% of the rendering function of this new custom widget can be copy-pasted from the button, the progressbar and the label. That custom widget would then provide an interface like myWidgetSetLevelLeft() and myWidgetSetLevelRight() for the two volume progress bars and so on. As you only need one text attribute (again, judging from what we've seen in your studio screenshots) you can keep using the built-in text attribute from the GWIN base class. When you take a closer look at some of the built-in widgets you can see that most advanced widgets are implemented this way. Take the frame widget for example. The frame widget provides buttons in the window decoration (window border). However, these buttons are not real GWIN PushButtons. Instead it's just an area that gets drawn in the rendering function using primitive gdispDrawXxx() calls and in the touch coordinates handling functions we just check whether the touch occurred inside of those areas. The same applies to the list widget (the scroll bar) and so on. This technique allows to implement advanced widgets using very little resources. This keeps your application small and fast even when you need such an advanced widget as in your case. We are happy to help you where we can whenever you have any questions. ~ Tectu
  18. Adding a drawing function for the label widget that doesn't clear the background (so it's transparent) is fairly easy and you can either do that yourself by creating your own custom rendering routine as explained in this article or we can add it to be an official built-in rendering routine for the label widget. It's really just a matter of minutes. The reason it's not there yet is because it doesn't make much sense. When you change the text of the label you NEED to clear the previous text - otherwise you'll just stack the two texts. Clearing the previous text happens through filling the label area with the background. When using a transparent background we don't know the background in the label rendering function so we can't clear it. This would mean that when using a label with a transparent background you'll have to clear the area yourself before the label gets redrawn. ~ Tectu
  19. Yep, we thought that this won't work As mentioned this is untested as it is not the expected behavior / usage. Yes, that is correct. You can see in the implementation of the label that it didn't register any functions to handle mouse interaction (line 54:56): https://bitbucket.org/Tectu/ugfx/src/a7 ... label.c-43 The same goes for the progressbar: https://bitbucket.org/Tectu/ugfx/src/a7 ... ssbar.c-38 You cant (with the default implementation of the widgets as linked above). You'd have to create your own specialized widget class for that. As inmarket explained the best and most proper solution is to write your own window manager and register that using gwinSetWindowManager(). ~ Tectu
  20. Both ChibiOS 2.6 and ChibiOS 3.x are known to work very well with uGFX. ChibiOS is what most uGFX users use as uGFX originated as a ChibiOS/RT extension/add-on. However, there's a known issue with the STM32F7 board files of uGFX and ChibiOS. It appears that the STM32F7 headers used by our board file and the one used by ChibiOS/RT are incompatible. Sadly we haven't had time to track down the issue ourselves so far. Last time we checked it seemed that ChibiOS/RT uses older headers than uGFX. But it's possible that it's the other way around or maybe the issue resolved itself by now - we haven't checked up on the state of the STM32F7 support on the ChibiOS/RT site of things for quite some time now. Note: The issues are really just related to the peripherals (LTDC, FMC and so on). The CPU part and all that magic works just fine. We would really appreciate it if you would have a look at the problem and potentially fix it. You can find further information here: viewtopic.php?f=23&t=334 ~ Tectu
  21. A short follow up on the first post: If you'll implement your own widget and you need lists, take a look at the GQUEUE module. This module provides different (highly optimized) queues and buffers. The GQUEUE module is used internally by the GWIN module so it's already enabled anyway. This means that it won't add extra overhead. ~ Tectu
  22. Well, that doesn't make writing that custom container widget easier First of all, can you please tell us what hardware you're using? Eg. the used microcontroller, the display controller, the used interface between the two and so on. It's possible to reduce the flickering with your current solution by just caching the image or by storing the image in the native format. ~ Tectu
  23. When a container gets redrawn, it first clears the entire client area and then iterates through its list of children and redraws each child. This means that whenever you move your element by even just one pixel and in the container then call gwinRedraw() everything gets redrawn and that is what causes flickering due to low hardware performance. The implementation of the currently existing container doesn't allow partial redraws. Depending on your needs I guess the best solution for you is to write your own (container) widget from scratch that is specifically designed to contain a number of widgets that can be moved around and it will just redraw the background area that needs to be redrawn. Of course the actual implementation depends a lot on your needs. When the background is just a solid color then it will be very straight forward. If its an arbitrary pattern that is not known then it will be a bit more difficult as you basically have to buffer the entire background. Sadly there is no official "how to write your own widget" guide at the moment. However, it is rather easy and very straight forward. Basically a widget is nothing but a table of functions that get called by the GWIN module. There's one function that gets called when the widget is supposed to get redrawn, one function that informs the widget about touch coordinates, another function for when a key press event happened and so on. Nearly all of these functions are completely optional. As there are already a lot of different widgets available you should have enough examples to get started. If you have any question regarding the implementation of widgets we are of course very happy to help you where ever we can. I hope that helps. ~ Tectu
  24. Yeah, we have seen that problem many times in the past. The ILI display driver family is a big mess. Anyway, happy that you got it working! ~ Tectu
  25. Hello Kenneth and welcome to the community! I just verified that the gdispFillCircle() function is working as expected. Therefore, this must be an issue inside the driver that you are using. As every drawing function in uGFX, the gdispFillCircle() function will try to use hardware acceleration wherever possible. As the ILI9325 doesn't support hardware acceleration for circle drawing, it will rely on using hardware fills (gdisp_lld_fill_area()) or streaming (gdisp_lld_write_xxx()). Looking at the current state of the ILI9325 it seems like it doesn't support hardware filling either. Therefore, the problem must be inside the streaming function. To verify this, you can disable the hardware streaming support in the drivers configuration file (/drivers/gdisp/ILI9325/gdisp_lld_config.h). You should then be able to draw filled circles without any artifacts. Once you confirmed that that's the problem, the next step will be to figure out whether the problem is inside the actual driver itself or in your board file. As there's not much happening for hardware streaming in the driver itself (it's just wrapping the calls), the problem will be most likely in your board file. I hope that helps. Please do not hesitate to ask should you have any other questions. ~ Tectu
×
×
  • Create New...