rabbibotton / clog

CLOG - The Common Lisp Omnificent GUI
Other
1.51k stars 104 forks source link

Working time tracking tool using CLOG (programming noob) #130

Closed hapst3r closed 1 year ago

hapst3r commented 2 years ago

Hej,

I recently wrote on reddit, asking for a way to find out the screen resolution.

Trying to give a bit more context, maybe it will be easier to understand what I am trying to achieve, as I still struggle to formulate in proper terms what I require for my program.

I am currently trying to design and program a user interface which gives users (my coworkers and me) the possibility to input working time data, especially regarding the spread of working time over two types of categories: (1) pedagogical work/preparation of that work/administration (2) a specification of what was chosen for (1). Using this, I want to gather data in order to pressure my superiors into either accepting that we have way more administrative chores then they see, or changing something about this problem. Because it is a problem when we are supposed to have 20% of our working time in administration and I find myself since more than one year having around 40%.

The user interface mainly revolves around two sections which could be dubbed "Input" and "Output".

Input

Output

So, I guess this should do as an explanation for a start. The code already present is public and can be found over at gitlab: https://gitlab.com/hapster/azvdoc . The repo is a bit messy because I am still learning how to use it and how to manage a repo. Most of the work happens in the files "construct-transform", "date", "day", "time" and "save-restore". I am also in the process of experimenting how to structure my program, since it is the first "real" program I write (excercise programs don't count in my opinion).

I hope I am not taking too much of your time with this issue where I'm basically asking for spoonfeeding and already want to thank you for the offer to discuss (here or over on reddit doesn't make a difference for me). Have a good day and thanks for your contribution to the community with clog, the resources you offer (tutorials etc) and your willingness to help people.

Have a good day :)

rabbibotton commented 2 years ago

Look at https://github.com/rabbibotton/clos-contact Also see the tutorial https://www.reddit.com/r/lisp/comments/t61sib/clog_builder_tutorial_4_a_complete_database_app/ Even if you do not use the builder that should give you some ideas of how to work with clog-gui

rabbibotton commented 2 years ago

Let me know how you are doing on that :)

hapst3r commented 2 years ago

Hej,

I have now arrived at tutorial 4 and can see why you suggested it ;-) Also, I believe it is a good idea that you don't immediately answer, for quite often I am able to find the problem by myself. The problem I posted yesterday was that the DB file couldn't be opened... turns out, I put the wrong path in there :exploding_head:

Yet, the old question remains, and I am confident that I found a typo in the tutorial:

Typo In Step 7 of the CLOG Builder Tutorial 4, a database listbox is created. The related table name is event_types. However, insofar as event_types relates to the tables created in the sqlite database, it has to be event_type (not event_typeS).

Not a major error, but since I am a hardcore noob I trip over every banana lying on the ground and fall :sweat_smile:

Question In the beginning of the tutorial, everything happens in CLOG builder: new windows are created, properties are defined etc. Thus, whenever a change has happened in CLOG builder, I could save to a CLOG file and then render to a LISP file.

However, later on, this way of working changes: function definitions are input in emacs, in the same file that CLOG builder used to operate on (if I understand correctly).

After working on the LISP file manually, I cannot use the RENDER functionality in CLOG builder because this will overwrite the contents of the LISP file.

What is the correct way to work side-by-side in CLOG builder and emacs?

I am asking because for some time I had a DIV centering the elements (that's what I'd seen in an earlier tutorial, can't recall which one). Then, when I first ran into the error above, I decided to remove it (less deviation from the tutorials equals less sources of error, I thought). I did remove it in CLOG builder, but now I don't know how to make changes appear in the LISP file in emacs.

I mean there is a way to do that: copying the manually written functions, RENDER the CLOG file to a LISP file, paste the manually written functions. But this seems unintuitive, is there a better way to do this?

QUESTION 2 After some time reading and re-reading the tutorial (in particular, step 7), I've hit another road block. I was unable to have the list box table control ("Listbox table lookup" in the Builder's database category, no?) be pinned as was described in the tutorial (positioning absolute, top/bottom 45px, left/right 15px, height/width 0). Maybe I forgot a minor setting here or there?

The database connection stuff works, at least partly. I can enter and delete entries and changes are shown in the listbox. However, all new listbox entries are NIL - even though, as per sqlitebrowser, there are actual entries in the event_type table. And I mean non-NIL entries reflecting what I had input originally.

I don't really know how to debug this one, because there is no error message in the REPL. The only indication I get when I hit RUN in CLOG Builder is a warning message.

EVAL RESULT (window name) WARNING: redefining CLOS-CONTACT::CREATE-CONFIG-EVENT-TYPES in DEFUN =>NIL

My *Messages* buffer in emacs tells me that

[sly] Evaluation aborted on NIL

At first I thought this was due to me moving code in and out from the file as I SAVE/RNDR in CLOG, but from what I can gather that's not the problem. I mean if I had manually changed CREATE-CONFIG-EVENT-TYPES, I could understand that problem, but AFAIK this function is literally written by CLOG itself.

QUESTION 3 Maybe it is time for another bit of context info and a related question. If I understand correctly, what you did for the tutorial you did in one sitting and incrementally, right? That's unfortunately not possible for me because on the one hand I am a noob and make a fair bit of mistakes, and on the other hand I have 45-60minutes per working day to work on this. This means that I have been working on tutorial 4 in like 5 different sessions by now (as you might guess, debugging and writing these questions is part of my "work time").

Thus, is it necessary to follow particular steps (I don't mean starting CLOG/TOOLS or CLOS-CONTACT) to ensure you are in "the same environment" as you used to be in the last time you worked on it? Because now for instance I wonder if the content of QUESTION 2 (a problem of having a function redefined) might be related to this problem or not.

Thanks, have a good time :)

rabbibotton commented 2 years ago

<<Typo In Step 7 of the CLOG Builder Tutorial 4, a database listbox is created. The related table name is event_types. However, insofar as event_types relates to the tables created in the sqlite database, it has to be event_type (not event_typeS).>> Fixed- Thanks!!

rabbibotton commented 2 years ago

<<However, later on, this way of working changes: function definitions are input in emacs, in the same file that CLOG builder used to operate on (if I understand correctly).

After working on the LISP file manually, I cannot use the RENDER functionality in CLOG builder because this will overwrite the contents of the LISP file.>>

You do modify files that were created with the Application Templates, but should never be directly editing any of the lisp files generated by the builder. So if you add an event for example you would not be adding that it the generated files but other files in your application.

So in the builder you are entering in the control events the names of functions from your code.

rabbibotton commented 2 years ago

question 2 - if can send me a zip of your project and would help me understand the question better

rabbibotton commented 2 years ago

question 3 - will help to see how you are going about things in code for me. So end me that zip and I'll see about some steps to make this easier. I really appreciate you taking the time to work thought the tutorials and try them and get stuck :( and write. It really helps me to make the whole process understandable and easier for all my goal. So we end up with a product that is super easy to create apps with.

rabbibotton commented 2 years ago

BTW in case didn't know - the completed tutorial is also at - https://github.com/rabbibotton/clos-contact

hapst3r commented 2 years ago

Okay, first things first: thanks for the headsup regarding the completed clos-contact tutorial. It shows quite clearly the point you are making: no manual code in builder-created files. Unfortunately, it does not solve the problem underlying Question 2, which I had initially hoped.

I think it generally makes sense to put a kind of warning or reminder somewhere (e.g. on the github page itself, or the documentation of the builder, or as a footnote to tutorial 4 since I feel like it was not so much of an issue in earlier tutorials). If there is such a reminder and I have failed to notice it, please pardon my ignorance. If you haven't already, I believe the way you phrased it in your comment above pretty much nails it.

Either way, the tutorial seems a bit misleading in this regard. The first phrase of Step 8 seems to suggest that the new definitions for cet-on-new etc. are to be put in the config-event-types.lisp file.

NILs in config-event-types table Checking out your code for clos-contact, I found the problem which caused NILs being added to my table. In CLOG builder, the Listbox table lookup comes with pre-made values for the table row id name and table columns (both set to rowid). Since those two are not mentioned in the tutorial, I figured "Well, those should be fine I guess". However, in the project uploaded on git, the value for table columns is "rowid description". I'm by now rather certain that this property relates to the columns of the sqlite database which should be displayed in the listbox.

If that's the case, I believe this information should be visible in the tutorial. I mean, again, this is something a seasoned programmer and/or sql data scientist might not struggle with, but I have gone to greats lengths to figure out the problem which now turns out to simply be an omission on one CLOG builder field on my part.

Since I can now continue following the tutorial, it is no more necessary for you to check my project (it features no code apart from the tutorial code). Thanks for offering it, though :-)

Pinning the listbox table lookup (builder tutorial 4, step 7/8) The tutorial seems to suggest that removing the height and width of the listbox table lookup will result in pinning the window according to the size of the window itself - alas, it will be bigger if the window is enlarged. The screenshots in step 7 and 8 both support this.

However, I have found this not to be the case, neither in my current tutorial "run" nor in the one before, nor in code provided for the tutorial in github. Instead, when the height and width is removed, a standard value (168 or 169) is input for the height. Afterwards, height and width seem to dependent upon the size of the content. That is, when I have a short string like "falcon" the width will be small, and with a long string like "I would like to have a good idea for a long string but I don't", the width will be bigger.

Maybe I overlooked a setting that you made. I'd love to know how "pinning" works properly because it seems like such a useful technique for gui programming because you don't have to bother with particular heights or widths.

The description of how to use Find It took me quite some time to figure out that the tutorial is quite literal giving its example for how to use find. I tried many combinations BEFORE I just "copy pasted" what you put into parentheses: name like 'david%'. I mean, maybe this is, again, a problem of me being new to programming and/or sql, but I believe it makes sense to try to make the search parameters more transparent or clear. For me personally, a bash-style description or some more examples would have helped tremendously: COLUMNNAME like 'SEARCH%', or name like 'david%' / phone like 555 (with some kind of highlighting).

rabbibotton commented 2 years ago

Thank you so much, all of this gives me many perspectives in how to improve everything for those approaching it the first time. My ultimate goal is to make everything stupid simple so a pointy hared boss man could even do much of the programming work.

hapst3r commented 2 years ago

Providing "style guideline" in tutorial In Tutorial 1 you mentioned that using a "div" to align several elements - div in "relative" positioning, the (text) elements either "static" or "absolute" - is often times what you want. I am trying to adopt this habit because I find it a nightmare to manually adjust the elements and still look "right". Wouldn't it make sense to suggest this use further along in the other tutorials or to show that you are using this in later tutorials? Because it seemed kinda off to me that while your GUI windows always look kinda lit, you never apply the suggestion you made yourself.

Saving CLOG Builder layouts The more I work with CLOG the more I wish there would be a way to memorize the way I arrange the windows I work with. I am so used to it from working with music programs where you can store layout presets that you can make the default and load etc.

Is there a way this is coming to CLOG Builder eventually?

aykaramba commented 2 years ago

I would recommed that you consider the tutorials as version 1 and that additional revisions might be appropriate to improve them. Having read all of the written tutorials my self, they also skip a bunch of information and assume you have learned from previous tutorials to just get the project done.

What this means is that, in my reading, we would benefit by NOT changing the existing tutorials much at all, only fixing grammar, spelling and maybe a bit wording here or there. The reason for that recommendation is that all tutorials have a target audience, no tutorial can ever satisfy all audiences because everyone is at a different part of the learning curve and therefore the tutorials are perfect for their intended audience: slightly more than basic to kind of intermediate audience that is enthusiastic and is willing to look things up.

I would also, therefore, suggest that we put together a set of guides and best practices. For example, the one that I wanted to write was the one that deals with the use of a main relative dive and the child divs as static or absolute as necessary. I am testing out creating of templates that look modern right now in order to figure out how to write this tutorial in a way that is somewhat based on trying to make real things.

The other tutorial that needs writing is how to read the documentation and translate that into code. I am starting to get it but as I am not a full time Lisp programmer I am still guessing. This should be straight forward in terms of explanation the bulk of the work being done to provide examples for each item in the documentation.

Then, I would like to build some template libraries and so forth so that people can take a look and see how they are built and improve them.

Your suggestion is fine but there are better ways to accomplish what you are suggesting other than changing the main tutorials. I thank my lucky stars we have all of this documentation, tutorials and so forth.

rabbibotton commented 2 years ago

How you doing :) Making progress? any issues?

hapst3r commented 2 years ago

Hej david, thanks for keeping in touch!

The last two weeks I was busy with other stuff and it is only now that I get back at it (finally!).

I am approaching the end of the tutorial, which means that I will soon bombard you with questions because I am starting to ACTUALLY get into programming the GUI for my program ;-)

Step 13/14: Problem with create-contact-report, report-contacts undefined PLACEHOLDER, WILL COME BACK TOMORROW!

Question: How are values typed in form elements passed to "local" functions? So in the contact manager tutorial, you are working with a database. Even though I see the merits of this approach, I have decided against rewriting my program from the ground up, also because I am afraid the database might add complexity which leads to more errors down the line (might consider using sql for a second project I got in mind though ;-)).

Thus, I wonder how values are passed from the GUI to the functions I wrote in advance. I will have two different GUI windows which serve the same purpose but with different levels of detail. The purpose is to specify how much working time has been expended in which of these three areas of work: (1) pedagogic work, (2) the preparation of pedagogic work, (3) administration.

In the simpler case, this will boil down to around 4 form input elements: (1) date (2-4) working time for the three areas of work. To those corresponds a function that creates a plist. The function and the resulting plist look like this (PK, OV2 and OV1 are the names for the work areas):

(defun construct-timespan (&optional start end pause place pk ov2 ov1)
  "Constructs an arbitrary timespan with the given parameters.
Applicable for TIMESPAN, DAY, MONTH, QUARTER, YEAR."
  (list :start start
    :end end
    :pause pause
    :place place
    :pk pk
    :ov2 ov2
    :ov1 ov1))

(:START 162 :END nil :PAUSE nil :PLACE nil :PK 2 :OV2 2 :OV1 1)

Now, I'd love to understand how the information input into the form inputs is transferred to the function. I have a vague idea and will start experimenting with it (maybe it's obvious), but this was the first conundrum I hit when approaching my GUI in thought.

rabbibotton commented 2 years ago

You set-on-click for a button that says ready to get the form contents, you then just access the form contents directly (text-value some-control) there are more ways but that is a good starting place.

rabbibotton commented 2 years ago

https://github.com/rabbibotton/clog/blob/main/tutorial/17-tutorial.lisp

hapst3r commented 2 years ago

I started to design my GUI and ran into problems not related to my earlier question. Thanks a bunch for the link!

EDIT: For clarity, I move "done" or "solved" issues in the first post, and current ones in a second one. I hope this makes it easier to see where problems arise and not get confused by stuff already past.

SOLVED: How to set $ELEMENT (table) borders in Builder

If I understand correctly, it is possible to set both borders and outlines for clog elements via an elements' builder settings. The settings for both outline and borders consists of three elements: size, type and color.

Now, I've tried to change those settings to something like (for border): 5px medium rgb(0, 0, 0. So far, with Builder, the values would change as soon as I leave the value cell of said element. However, for border and outline, nothing happens.

Changing the element focus to another element and back to the element with border, I realised that somehow Builder didn't take the values but has reverted to the default values.

EDIT: Found solution in w3-bordered

KINDA SOLVED: How to align GUI elements in Builder?

Essentially I am wondering how I can manage to have the elements in Builder aligned (as if they were in a table). I might be OCD'ish about this, but I cant deal with manually setting GUI elements with absolute positioning. And it seems like static positioning seems to produce problems of its own: while margins and padding slots work when it comes to working with labels, they don't work as I'd expect them to when using the date-picker. For instance, padding makes the date-picker element expand in either the horizontal or the vertical direction, while the margin setting makes it expand in all four cardinal directions.

I'd love to be able to insert a specified "space" between elements, or to have them stick to grids (like in a table) - or be able to have a margin in but one direction. Currently, my approach to the GUI shebang is that each portion of the GUI has a div. For instance, when I have a "date picker" label and date-picker, they will be in a "date picker"-div. I feel like I am committing a grave sin by manually "spacing" the elements out with a text label which consists of a bunch of spaces (those which divide the words).

EDIT: I just found a working-ish solution with "my" method. I'm still not 100% satisfied, but using relative instead of static works fine after some experimentation. What tripped me up at first is that it is seemingly necessary to manually reset the values for top, left, bottom, right to 0px and start from there.

Praise

Also, I finally managed to get to the newest version of CLOG (Builder) using UltraLisp (had been waiting on QuickLisp for like 2 months, lol). You're doing a great job, I'm kinda stoked by the pace of development!

SOLVED: How to access form contents via (text-value some-control) pt2

I finally got busy with fetching GUI input. Progress being made, yay!

So I though to myself: before I try the "heavyweight" stuff (interacting with files on the system, the programs array, ...), I might use a (confirm-dialog ...) to make sure that values are read and parsed properly. It turns out that I am using (text-value some-control) wrong, since whenever I try to preview the input, I receive this error

There is no applicable method for the generic function

<STANDARD-GENERIC-FUNCTION CLOG:TEXT-VALUE (4)>

when called with arguments (AZVDOC::PK).

This is my code for the function that is in the on-click slot of a button in Builder.

(defun input-simple-preview (panel)
  (confirm-dialog panel
          (format nil "Correct? ~A" (text-value (pk-input panel)))
          (lambda (answer)
            (if answer 'yes 'no))))

Some explanations: in builder, there is an input form called pk-input. The name on form slot is set to "pk". I've tried to invoke (text-value ...) with "pk-input" as well as "pk", as a symbol, a string and without anything (text-value pk-input).

At first, I thought the problem is that I have not input anything in the pk-input form, but it turned out this is not the issue.

EDIT: It took me a while, but the CLOG builder tutorial 4 showed me the way: (text-value (clog-object panel)). In my case, it was (text-value (pk-input panel)). Not that it matters, but I updated the code above to reflect that. I would love to learn more about the "logic" behind CLOG. I am slowly understanding that somehow I have to not refer to a clog-element such as pk-input on its own, but in a separate form, (pk-input panel). While having understood that, I have no idea why that is the case, which severely limits my capacity to generalise - essentially, I have to re-acquaint myself with similar problems every time because I don't know if I can transfer my current knowledge.

hapst3r commented 2 years ago

Why does table column alignment stop working as soon as I start using form inputs?

I am starting to experiment with the table elements to which IIUC corresponds HTMLs variants. Thus, a table consists of those elements:

So far, when I worked with only headings and columns, everything went fine. The column dividers (how to make them visible!?) would adjust to the size of the inserted element so that the overall formatting does not get screwed.

When I added a first form input, this still worked, the column size was adjusted accordingly. However, as soon as I added a second form input in one row, this mechanism stopped working. Also, it seemed like with the second form input added, the correspondence ONE ELEMENT-ONE COLUMN has been broken, because both form inputs appeared in the first column.

Why is this, and is there a possibility to change that?

How to make font bold in Builder?

I am trying to make the text of a label bold. How do I do that? I have seen the font properties slot and experimented with it but have been unable to get what I wanted.

How to insert a linebreak in a tooltip?

I discovered that it is possible to use placeholder text and tooltips to supply more information in one window and I gotta say I love it.

So I started creating tooltips in places where I deem it important. However, I don't see the possibility to insert linebreaks. Guessing I might have to input a HTML command (because many things in CLOG are) I tried <br> in the tooltip value area but without success.

Is this possible, and if so, how?

How to change the date format settings?

I am still experimenting with a function that shows the data input before submitting it. Currently, when picking a date in the Date Picker, it represents the date (probably according to my locale settings for Germany) in the DD.MM.YYYY format (which is the norm). However, when I get the Date Picker value with (value (date-picker panel)), it is represented in another format, YYYY-MM-DD.

Since the program targets a german-speaking audience, I would like the date to be represented in a familiar fashion - some of my colleagues are oldies and I want to lower barriers of entry as much as possible. Thus, I need a way to change date format settings.

I have not found a variable or function for CLOG that does this, and the only variable which seemed close enough was trivial-backtrace:*date-time-format*. However, changing this variable didn't yield the desired results: I've (setf trivial-backtrace:*date-time-format* "%d.%m.%Y %H:%M") in the repl, refreshed the window holding the CLOG Builder test window and tried again. Nothing happened.

Would it make a difference if I set this variable somewhere in my package's code? Do I need another value-fetching function?

Is it possible to generate CLOG elements "on the spot" using a button?

My program features two ways of representing working time. A very quick one, which has only four elements per day: (1) date, (2)-(4): working time in hours for different categories. I already have a corresponding GUI window done, more or less.

However, the second way is A LOT more verbose. Essentially, it breaks down one working day into several time spans. Each time span in one day (e.g. 10:00h -- 11:00h) will feature, apart the time span start (1) and end (2), the three categories (3)-(5) and a specifying sub-category (6). When I am using this method on paper (which I do since about 2 years now), the number of time span entries I use ranges somewhere between four and ten for one working day.

Now, I can think of two different approaches: the first would be to supply a specified amount of available time span entries (say, 15), and to ignore those entries which do not contain any data when "transferring" the form input data to my program's calculating functions.

The second approach, which I deem more elegant, would have just one time span present, and something like a "+" sign button at the end of the row. When pressed, this button "produces" a new time span row, and, if necessary, the gui window grows accordingly. Then, there could be another "-" sign button which allows one to delete one row if necessary. The capacity to ignore empty entries should be possible here as well.

rabbibotton commented 2 years ago

<<Why does table column alignment stop working as soon as I start using form inputs?>> I speak code better :)

<<How to make font bold in Builder?>>

  1. (best way) Add the word bold to start of the font property "bold 15px / 22.5px Verdana, sans-serif"
  2. Scroll down to the last property say in a label and you can add .. around your label's text. (when you save the clog file and reload it you will see the bold tags are added as controls)

<<How to change the date format settings?>> The format you get/set is always yyyy-mm-dd but the format the the user sees is always based on his local set on the machine or in the browser. There are ways to override "local"s but not a good idea and not sure if privacy will allow anymore.

<<Is it possible to generate CLOG elements "on the spot" using a button?>> The beauty of CLOG is you can always do anything. Just create an on-click handler and use create-* to create what you want.

I don't really understand the rest, perhaps a code sample.

rabbibotton commented 2 years ago

making progress?

hapst3r commented 2 years ago

Table-stuff I don't know how static and relative positioning differ from one another programmatically, but using relative for the table allowed me to build the kind of GUI window I wanted.

Linebreak in tooltip So when I make a label, it has a tooltip slot. When I insert a linebreak in this tooltip, the two lines separated by line-break are collated to one another.

However, I'd love to have a hover-over label that HAS line-breaks. I guess I will then have to use control-events, right?

rabbibotton commented 2 years ago

Relative means to treat the item as static - but let you position it as absolute. It is key to allowing a control to be used in flex-box and other layouts. Usually I recommend when making controls to use relative as the layout of an outer div around the control. https://www.reddit.com/r/Common_Lisp/comments/w4zwm3/common_lisp_repl_style_dev_visually_with_clog/

rabbibotton commented 2 years ago

You are probably best off making a div as your tool tip and showing it on hover and hiding out when going out of control, that give you real control over the tool tip.

rabbibotton commented 2 years ago

making progress?

hapst3r commented 2 years ago

hej,

again, I much appreciate that you don't just forget about this project, even after these many months.

I currently don't work on the project since it is tied to work and after an accident-induced wrist injury that will take a good few months to heal I don't work. Also because of the wrist injury I can't type nor program properly (one-handed).

If you would like to close the issue, that's completely fine by me. I can also close it.

However, if you don't mind too much, I'll open a new issue as soon as I get back to work and stumble across a problem I deem related to clog.

In the meantime, I will read Practical Common Lisp, I hope that afterwards my journey becomes a bit easier.

Have a good time, good fellow :)

rabbibotton commented 1 year ago

Hope you are doing well! I am going to close the issue but feel free to open another or still ask here.