<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hey list!</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I've been trying to isolate the keyboard navigation as much as i could since you guys said it should be compiled optionally. </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
While a lot of stuff could be moved to it's own file (g_kbdnav.c) there are also a lot of code that need to be in the middle of pd's core functions.</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
For example, here is the modified <b>canvas_obj()</b> function on the <i>g_text.c
</i>to not cinlude the code related to keyboard navigation:<br>
<br>
<a href="https://gist.github.com/HenriAugusto/e417c8f269ad10df2dc3359b907ea588" id="LPNoLP512917">https://gist.github.com/HenriAugusto/e417c8f269ad10df2dc3359b907ea588</a><br>
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
It's not as pretty as it could be but it's readable (if your editor has code folding you can just hide the relevant lines to see what the code looks like, for example).</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Is there a better way to do this?</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Cheers,</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Henri.</div>
<div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
____________________________</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Just in case, those are examples of some other modified core functions:</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span><br>
</span></div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span><b>in g_text.c</b><br>
</span>
<div><br>
</div>
<div><span style="font-family: Calibri, Helvetica, sans-serif; background-color: rgb(255, 255, 255); display: inline !important">glist_drawiofor(...) - draws a rectangle around the selected in/outlet</span></div>
<div>canvas_howputnew(...) - position a new object exactly below/above to selected in/outlet<br>
</div>
<div><br>
</div>
<div><b>in g_canvas.c</b></div>
<div><b><br>
</b></div>
<div><span style="font-family: Calibri, Helvetica, sans-serif; background-color: rgb(255, 255, 255); display: inline !important">canvas_drawlines(...) - draws lines in different colors while navigating through connections</span><br>
</div>
<div><span style="font-family: Calibri, Helvetica, sans-serif; background-color: rgb(255, 255, 255); display: inline !important">canvas_map(...) - draws each object's index if the user has asked so (useful for the goto functionality)<br>
</span></div>
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>De:</b> Christof Ressi <christof.ressi@gmx.at><br>
<b>Enviado:</b> terça-feira, 16 de julho de 2019 14:32<br>
<b>Para:</b> Henri Augusto Bisognini <msndohenri@hotmail.com><br>
<b>Cc:</b> pd-dev@lists.iem.at <pd-dev@lists.iem.at><br>
<b>Assunto:</b> Aw: Re: [PD-dev] First complete keyboard navigation prototype</font>
<div> </div>
</div>
<div>
<div style="font-family:Verdana; font-size:12.0px">
<div>
<div>Hi,</div>
<div> </div>
<div>> But it appears that actually the size of the struct is deduced <span style="font-family:Calibri ,Helvetica ,sans-serif; background-color:rgb(255,255,255); display:inline">
while compiling.<span> S</span></span>o if you write an external it is going to think the canvas struct is the same size as it was in the pd header files that were used during compilation.</div>
<div> </div>
<div>exactly.</div>
<div>
<div> </div>
<div>> <span>When using the pointer to implementation idiom, wouldn't the pointer itself change the size of the struct?
</span></div>
<div> </div>
<div><span>yes, it will</span></div>
<div> </div>
<div><span>> You've said something about that not being a problem when you add it as the last member of the struct but i don't understand why and how that would work.</span></div>
<div> </div>
<div><span>usually, externals shouldn't care about the *size* the t_editor struct (at least I can't think of any use case), so you can get away with adding new fields at the end (although it's certainly not recommended). Note that those headers aren't really
 public anyway!</span></div>
<div> </div>
<div>However, appending fields conditionally can lead to problems:</div>
<div> </div>
<div><span>struct Foo {</span></div>
<div><span>    int a;</span></div>
<div><span>#ifdef FOO_EX</span></div>
<div>    int c;</div>
<div><span>#endif</span></div>
<div>};</div>
<div> </div>
<div>Now let's say we need to add another member:</div>
<div> </div>
<div>
<div><span>struct Foo {</span></div>
<div><span>    int a;</span></div>
<div><span>#ifdef FOO_EX</span></div>
<div>    int c;</div>
<div><span>#endif</span></div>
</div>
<div>
<div><span>    in b;</span></div>
<div><span>};</span></div>
</div>
<div> </div>
<div>If the host compiles with FOO_EX defined and the client doesn't, the latter will assume a wrong offset for 'b'.</div>
<div> </div>
<div>The solution is to add a field for private data *once*. The advantage is that a) we can hide the private data and b) we can extend it without worrying about compatibility:</div>
<div> </div>
<div>struct Foo {</div>
<div>   int a;</div>
<div>   PrivateFoo *p;</div>
<div>};</div>
<div> </div>
<div>We can still add public members if needed:</div>
<div> </div>
<div>struct Foo {</div>
<div>    int a;</div>
<div>    void *private;</div>
<div>    int b;</div>
<div>};</div>
<div> </div>
<div>'private' points to a private data structure that is not be visible to clients. There you can conditionally enable members without problems:</div>
<div> </div>
<div>struct PrivateFoo {</div>
<div>#ifdef USE_BAR</div>
<div>    struct MyFeature feature;</div>
<div>#endif</div>
<div>};</div>
<div> </div>
<div>MyFeature could be in a seperate source file together with your methods and it only gets compiled when needed.</div>
<div> </div>
<div>Again, have a look at the "t_canvas_private" struct and the "gl_privatedata" member of "_glist" (aka "t_canvas") and do the same for "_editor", e.g.:</div>
<div> </div>
<div>in g_canvas.h:</div>
<div> </div>
<div>typedef struct _editor {</div>
<div>    ...</div>
<div>    void *e_privatedata;</div>
<div>} t_editor;</div>
<div> </div>
<div>in g_editor.c:</div>
<div> </div>
<div>#ifdef HAVE_KEYBOARDNAV</div>
<div>#include "g_keyboardnav.h"</div>
<div>#endif</div>
<div> </div>
<div>typedef struct _editor_private {</div>
<div>#ifdef HAVE_KEYBOARDNAV</div>
<div>    t_keyboardnav keyboardnav;</div>
<div>#endif</div>
<div>} t_editor_private;</div>
<div> </div>
<div>the "t_keyboardnav" struct is defined in "g_keyboardnav.h" and its methods implemented in "g_keyboardnav.c". Both only get compiled when needed.</div>
<div> </div>
<div>Hope this makes sense.</div>
<div> </div>
<div>Christof</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>