I'm talking about the hard way! The easy way is - just hire a top coder like Chayan😊
What I set out to do, and did : make it possible for the user to press 'd' and then click on an object that is selected to deselect it and press CTRL-'d' and then input a rectangular area using two mouse clicks to have objects touched by that rectangle that are selected be deselected.
In this post, we'll look at the why, the how, and what kind of help you can actually get from chatGPT and Google's Notebook LM (spoiler: cG is good for specific requests to re-do snippets or small files while N-LM is good for diving into an entire code-base, but doesn't do too good a job creatively. Copilot didn't do much at all unfortunately. The intellisense in VS Code did help. But, not sure if Copilot chipped in at all). We'll also see how gdb can get involved to save the day!
To get started, you have to fork Stefan's repo - if you have to fork the starter repo. If you've used GitHub at all, this is probably a breeze for you.
Then, having forked on GitHub, using your browser, you can download your fork - your repo as a .zip, or go to a terminal and use the clone command. And you're in business to hack and then submit a pull request (if you want :)
Why
Why and why CTRL-'d'? I wanted 'd' and SHIFT-'d', like Cadence has it, but, SHIFT-'d' is already being used, so I settled for CTRL-'d'.
The problem - Xschem uses ALT+LMB click and click+drag to deselect objects. But, as anyone with a productivity OCD knows, ALT + Mouse are already reserved for window operations (move, in KDE, and, if you use AHK, on Windows).
How
If you're a crack coder, you can easily jump into the code-base and figure it out - maybe. There are videos on clean code about why clean code is necessary. I listened to Coders at Work in which one of the coding legends says the way he takes a code-base apart is to start with the user-input part of the code and work back from there. What I mean is that a savant will be able to take apart even code that isn't clean. It sure helps if the code *is* clean, which it isn't. Scusa Stefan😊
Meaning? It wasn't easy at all for me. Xschem is not written by a professional coder (as in, he's a professional, but not raised in the software industry). It was the same with the code Elon Musk wrote for Zip2It. When the pros got involved after the acquisition, they had to rewrite it.
This means that "jumping into the code base" can be difficult. What will alleviate this is help from chatGPT and Notebook LM. You are interested in a certain function. You ask Notebook LM about it and it tells you, even pointing out relevant parts of the code. For a start, chatGPT's interface seems broken - uploaded a tonne of files is not easy.. Given that, you can feed chatGPT portions of some of the files and ask for specific recommendations and try them out. Will they work right off the bat? Probably not. But, the moment you've asked, received and put in a hack into the code-base, you've gotten the dopamine going for you. You've set the ball rolling. It's only a matter of time till the finish line from that point on.
So, how do you feed stuff to Notebook LM given that it only accepts PDF, or plain text or markdown? You want to dump .c and .h files.
Simple. Use these two commands to dump the files (mkdir dir_for_NLM) into a directory (so that they're all in one place)
for file in *.c; do cp "$file" "/tmp/files_xschem/${file%.c}_c.txt" # Rename and copy .c files
for file in *.h; do cp "$file" "/tmp/files_xschem/${file%.h}_h.txt" # Rename and copy .h files
Launch a new notebook on N-LM and upload these and you're in business. Example : how does the tool handle the deselection of objects?
Now, before we hack the code, since our task is UI based, let's break it down. The 'd' business is obviously simpler. You take what already exists (bad as it sounds, just pressing the LMB (aka Button1) with ALT pressed on a selected instance will deselect it - you don't need to release the mouse button to "complete a click." Yes, it's not a tool that can go head to head with Cadence and there are number of reasons. UX is a prime one. That it has been done by a single person is commendable, of course.
What about the CTRL-'d' thing? This is trickier - but, let's quickly sum up what needs to happen in this GUI ecosystem. It's built to use the X11 X-Windows system. This system, when you use the appropriate library in your C program, will send your event loop information about the event that caused your callback function to be called. Meaning, there are event types that you can look for - KeyPress, KeyRelease, ButtonPress, ButtonRelease, MotionNotify, EnterNotify, LeaveNotify, etc. You're already guessed which ones we need to take care of for CTRL-'d' - KeyPress (initiator), ButtonRelease and MotionNotify.
Why MotionNotify? Because, once you've entered a state (such as waiting for the next click or ButtonRelease, you need to provide the user with visual feedback about the state of his input - and this is done by drawing a rectangle in "rubber band" fashion following the mouse pointer).
Which introduces another key word - "state". Notebook LM can tell you about all this - how the tool behaves in a certain case, etc. And then you jump in and start filling in the blanks - easy if you were a pro coder, much more time consuming for me. But, very early, you'll see that the program makes heavy use of a "Context" structure (struct) - a global variable referenced by every Tom, D and Harry function to know what's going on and make updates.
So, before getting into the weeds - let's sum up what needs to happen :
You need code to detect that the CTRL-'d' combination was pressed - very easy.
You use this code to get the program to enter a state in which it now looks for a button click. (Hint, set a bit in xctx->ui_state)
Having seen one click (event == ButtonPress and button == Button1 and ...) you now enter a state in which you're looking for the "ending" click.
In this state (waiting for 2nd click), MotionNotify event handling takes care of drawing the rubber-band rectangle.
What to do when you see the 2nd click - tough to come up with on your own - but that's why you have the starter code to refer to - the one that handles ALT+LMB_click_drag.
And that's pretty much it. Took me about three days, but you'll be done much faster, I hope😊
To be continued..
If you want to find out who calls a certain function, you can (once you build using CFLAGS += -g -O0) run gdb and break on that function (after reaching a decent stopping point 😊- meaning, if you insert the breakpoint right at the start, you might get stopped too many times - probably typical with a GUI app). Then, you can run the "bt" command in gdb to see who called the said function. This is in the video.
No comments:
Post a Comment