# How AnnotationWinController Displays Chinese Translations and IPA Phonetic Symbols in hallelujahim

> Learn how AnnotationWinController displays Chinese translations and IPA symbols in hallelujahim by receiving formatted strings and rendering text in an NSTextField panel.

- Repository: [dongyuwei/hallelujahim](https://github.com/dongyuwei/hallelujahim)
- Tags: how-to-guide
- Published: 2026-02-28

---

**AnnotationWinController displays Chinese translations and IPA phonetic symbols by receiving a pre-formatted annotation string from the ConversionEngine through InputController, then rendering the text in a floating NSTextField panel.**

The hallelujahim input method for macOS provides an optional annotation window that appears beside candidate suggestions, showing both Chinese translations and International Phonetic Alphabet (IPA) symbols for English words. Understanding how `AnnotationWinController` renders this linguistic data requires examining the coordinated workflow between user selection handling, dictionary lookup, and macOS window management as implemented in the dongyuwei/hallelujahim repository.

## The Three-Component Display Pipeline

The annotation display relies on a coordinated pipeline across three core Objective-C classes. When a user highlights a candidate word, the system propagates data from input handling through linguistic processing to final UI rendering.

### InputController.mm: Detecting Candidate Selection

Located in `src/InputController.mm` at lines 86‑92, the `InputController` class monitors candidate selection changes through the `candidateSelectionChanged:` method. When the user enables the *Show Translation* preference, the controller immediately triggers the annotation display workflow.

The controller extracts the plain string from the selected `NSAttributedString` and calls the internal `showAnnotation:` method:

```objc
- (void)showAnnotation:(NSAttributedString *)candidateString {
    NSString *annotation = [engine getAnnotation:candidateString.string];
    if (annotation.length) {
        [_annotationWin setAnnotation:annotation];
        [_annotationWin showWindow:[self calculatePositionOfTranslationWindow]];
    } else {
        [_annotationWin hideWindow];
    }
}

```

This method serves as the gateway, delegating linguistic lookup to the `ConversionEngine` while managing the `AnnotationWinController` visibility state.

### ConversionEngine.mm: Composing Translations and IPA Symbols

The `ConversionEngine` class in `src/ConversionEngine.mm` (lines 23‑38) constructs the actual annotation content through its `getAnnotation:` method. This implementation performs dual dictionary lookups: fetching Chinese translations via `getTranslations:` and retrieving IPA phonetic symbols through `getPhoneticSymbolOfWord:`.

When a phonetic symbol exists, the engine wraps it in square brackets and **prepends** it to the translation list, joining all elements with newline characters:

```objc
- (NSString *)getAnnotation:(NSString *)word {
    NSString *input = word.lowercaseString;
    NSArray *translation = [self getTranslations:input];
    NSString *phoneticSymbol = [self getPhoneticSymbolOfWord:input];
    
    if (phoneticSymbol.length) {
        NSArray *list = @[ [NSString stringWithFormat:@"[%@]", phoneticSymbol] ];
        return [[list arrayByAddingObjectsFromArray:translation] componentsJoinedByString:@"\n"];
    }
    return [translation componentsJoinedByString:@"\n"];
}

```

The resulting string places the IPA symbol (e.g., `[həˈloʊ]`) on the first line, followed by Chinese translations on subsequent lines.

### AnnotationWinController.m: Displaying the Floating Panel

The `AnnotationWinController` class in `src/AnnotationWinController.m` provides the minimal UI surface for presenting the processed text. At lines 43‑45, the `setAnnotation:` method assigns the received string directly to its `NSTextField` view:

```objc
- (void)setAnnotation:(NSString *)annotation {
    (self.view).stringValue = annotation;
}

```

The controller manages a borderless floating panel that appears at coordinates calculated by `InputController`'s `calculatePositionOfTranslationWindow` method, ensuring the annotation appears adjacent to the active candidate selection.

## Step-by-Step Execution Flow

The complete display sequence follows this precise execution path:

1. **User highlights candidate** → `InputController` receives `candidateSelectionChanged:` with an `NSAttributedString`.
2. **Preference check** → The controller verifies `[preference boolForKey:@"showTranslation"]` before proceeding.
3. **Linguistic lookup** → `ConversionEngine` queries both translation and IPA dictionaries, formatting results with the symbol wrapped in `[]` brackets.
4. **UI update** → `AnnotationWinController` receives the formatted string via `setAnnotation:` and updates `(self.view).stringValue`.
5. **Window positioning** → The panel displays at calculated screen coordinates via `showWindow:` or hides if no annotation exists.

## Summary

- **InputController.mm** (lines 86‑92) triggers the annotation workflow when candidates are selected and the translation preference is enabled.
- **ConversionEngine.mm** (lines 23‑38) builds the display string by prepending IPA phonetic symbols in square brackets to Chinese translation lists.
- **AnnotationWinController.m** (lines 43‑45) renders the final text in a floating `NSTextField` panel positioned beside the candidate list.
- The architecture separates concerns between input handling, linguistic data processing, and presentation rendering.

## Frequently Asked Questions

### How does AnnotationWinController receive the Chinese translation data?

`AnnotationWinController` does not fetch data directly. Instead, `InputController` calls `ConversionEngine`'s `getAnnotation:` method to retrieve a pre-formatted string containing both the IPA symbol and Chinese translations, then passes this string to the controller's `setAnnotation:` method.

### Why are IPA phonetic symbols wrapped in square brackets?

According to the implementation in `ConversionEngine.mm` at lines 30‑31, the code explicitly formats the phonetic symbol using `[NSString stringWithFormat:@"[%@]", phoneticSymbol]` to visually distinguish pronunciation guides from semantic translations in the floating panel.

### Where is the annotation window positioned on screen?

The display coordinates are calculated by `InputController` using the private `calculatePositionOfTranslationWindow` method. This ensures the `AnnotationWinController` panel appears immediately adjacent to the active candidate list in the input method interface.

### Can the annotation display be disabled by users?

Yes. The `InputController` checks the user preference via `[preference boolForKey:@"showTranslation"]` before calling `showAnnotation:`. When this boolean returns false, the annotation window remains hidden regardless of candidate selection changes.