Sunday, March 23, 2025

More Critique from the Oracle (chatG)

Critique of C Code Snippet: Handling Button1 Press During Edit Dialog


/* button1 click to select another instance while edit prop dialog open */
if(button==Button1 && xctx->semaphore >= 2) {
  if(tcleval("winfo exists .dialog.textinput")[0] == '1') { /* proc text_line */
    tcleval(".dialog.f1.b1 invoke");
    return;
  } else if(tcleval("winfo exists .dialog.txt")[0] == '1') { /* proc enter_text */
    tcleval(".dialog.buttons.ok invoke");
    return;
  } else if(state==0 && tclgetvar("edit_symbol_prop_new_sel")[0]) {
    tcleval("set edit_symbol_prop_new_sel 1; .dialog.f1.b1 invoke"); /* invoke 'OK' of edit prop dialog */
  } else if((state & ShiftMask) && tclgetvar("edit_symbol_prop_new_sel")[0]) {
    select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
    tclsetvar("preserve_unchanged_attrs", "1");
    rebuild_selected_array();
  }
}

✅ What Works Well

  • Functionally Correct: It correctly distinguishes between various UI dialog contexts and responds appropriately.
  • UI-Sensitive Logic: It properly accounts for Shift key usage and application state (`semaphore`).

❗ Issues & Suggestions

1. Too Many Inline TCL Calls

Calling tcleval("winfo exists ...") multiple times is inefficient and clutters readability.

// Suggestion:
int text_input_exists = tcleval("winfo exists .dialog.textinput")[0] == '1';

2. Hardcoded String Literals

These are fragile and error-prone. Use #define for better readability and maintainability.

#define DIALOG_TEXTINPUT_CHECK  "winfo exists .dialog.textinput"
#define DIALOG_OK_INVOKE        ".dialog.f1.b1 invoke"
#define SYMBOL_PROP_VAR         "edit_symbol_prop_new_sel"

3. Dense Conditional Chain

All logic is packed into a single if block. It's difficult to scan and should be factored into a helper function.

void handle_edit_dialog_selection(int state) {
  if (dialog_exists(".dialog.textinput")) {
    tcleval(".dialog.f1.b1 invoke");
    return;
  }
  if (dialog_exists(".dialog.txt")) {
    tcleval(".dialog.buttons.ok invoke");
    return;
  }

  const char *sel_flag = tclgetvar("edit_symbol_prop_new_sel");
  if (state == 0 && sel_flag[0]) {
    tcleval("set edit_symbol_prop_new_sel 1; .dialog.f1.b1 invoke");
  } else if ((state & ShiftMask) && sel_flag[0]) {
    select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
    tclsetvar("preserve_unchanged_attrs", "1");
    rebuild_selected_array();
  }
}

Then the main logic becomes:

if (button == Button1 && xctx->semaphore >= 2) {
  handle_edit_dialog_selection(state);
}

4. No Feedback or Logging

If none of the dialog paths are valid, the code silently continues. A debug log can help during maintenance.

🧾 Summary

AspectEvaluationNotes
Functionality✅ SolidHandles all expected dialog interactions
Performance⚠️ MediumRedundant calls to tcleval
Readability⚠️ PoorHardcoded strings and dense logic
Maintainability❌ WeakNeeds function separation and better naming

✅ Final Suggestion

Refactor into a dedicated function and avoid repeated logic. Add debug messages for unexpected states.

No comments:

Post a Comment

Who Needs Cadence Anymore (for Schematic Tree Reporting that is :)? Make Your Own Reporter with chatGPT!

You know what I mean, if you've used Cadence - the SHIFT-T thing that gives you the schematic tree can be VERY useful, at times. No Cade...