메뉴 뒤의 동작 / original
DEVELOPMENT JOURNAL / 18
Photoshot
CODE × UI
무료 포토샵 개발기

메뉴 뒤의 동작

무료 포토샵을 만드는 포토샷 개발기입니다. 17편까지 조정 기능의 계산을 살폈다면, 이제 편집기 전체로 범위를 넓힙니다. 익숙한 메뉴를 나열하는 것에서 끝내지 않고 실행 조건, 명령 연결, 검증 근거와 남은 범위를 함께 기록하는 과정입니다.

PHOTOSHOT DEVELOPMENT JOURNAL / 18

AI 생성 시연용 사진. 편집 화면과 출력 이미지는 실제 포토샷에서 만들었습니다.

Photoshot무료 포토샵 개발기 / 18FOUNDATION

출처에서 시작하다.

메뉴가 보인다고 기능이 완성되는 것은 아니다

기능 대조표에는 메뉴 위치, 기능, 상태, 검증 또는 구현 근거, 남은 범위를 따로 적었습니다. 예를 들어 작업 공간 UI는 부분 구현으로 표시하고, 좌우 도킹과 부동 패널은 해당 검증 근거를 별도로 붙입니다. 하나의 완료 표시로 전체 편집기의 수준을 설명하지 않으려는 구조입니다.

16·17편은 공개 저장소의 고정 커밋을 기준으로 읽었습니다. 이번 편의 소스는 별도 운영 편집기 작업본인 app/studio입니다. 이 확장 코드가 공개 저장소에 모두 들어 있다고 쓰지 않습니다. 홈페이지의 근거 파일에는 실제 읽은 파일명·줄 번호·SHA-256과 발췌를 남겼습니다.

현재 문서 상태가 실행 가능 여부를 결정한다

photoshop-ui.tsx는 선택된 레이어가 있는지, 잠겨 있는지, 조정 레이어인지부터 확인합니다. 변형은 위치 잠금, 필터는 픽셀 잠금 등 추가 조건을 적용합니다. 마스크 편집 중인지에 따라서 픽셀 작업의 조건도 달라집니다.

2026년 10월 22일 운영 화면에서 새 AI 원본 레이어를 잠그자 Edit의 Free Transform이 비활성화됐습니다. 잠금을 풀면 다시 활성화됐습니다. 화면에서 확인한 이 한 사례와 코드에서 읽은 다른 조건들을 구분해 기록했습니다. 잠긴 상태에서 명령을 강제로 실행하는 검사는 하지 않았습니다.

app/studio/photoshop-ui.tsx · SHA-256 13e6e581815a · L94–97포토샷 구현 코드 ↗
 const allowed=!!active&&!layerLocked(doc,active)&&active.kind!=='adjustment';
 const transformAllowed=allowed&&!layerLocked(doc,active!,'position');
 const filterAllowed=allowed&&!layerLocked(doc,active!,'pixels');
 const pixelAllowed=!!active&&!layerLocked(doc,active,p.maskEditing?'all':'pixels')&&(p.maskEditing?!!active.mask?.enabled:active.kind!=='adjustment');
Photoshot무료 포토샵 개발기 / 18IMPLEMENTATION

계산의
안쪽으로.

명령 검색은 같은 기능으로 들어가는 또 하나의 입구다

command-search.tsx는 메뉴 경로·이름·한국어 별칭을 함께 검색합니다. 검색어를 공백으로 나눈 뒤 모든 단어가 포함되는 명령을 고르고, 결과를 최대 60개로 제한합니다. 실행 직전에도 disabled를 확인하므로 검색이 비활성 메뉴의 우회로가 되지 않도록 했습니다.

실제 Help → Search Commands에서 ‘이미지 크기’를 입력하자 Image Size가 검색됐고 Enter로 크기 창이 열렸습니다. 창에는 원본과 같은 1536×1024가 표시됐습니다. 이번 편은 메뉴 연결 시연이므로 크기를 바꾸지 않고 Cancel로 닫았습니다. 아래 결과 화면은 이미지 보정 전후가 아니라 명령 실행 결과입니다.

단축키·패널·검증 결과를 같은 수준으로 말하지 않는다

대조표는 단축키 편집·충돌 재배정·세트 입출력의 브라우저 검증을 기록하면서도 OS나 브라우저가 가로채는 예약 키는 보장할 수 없다고 적습니다. 패널 도킹 검증 역시 운영체제의 다중 모니터 도킹까지 포함하지 않습니다. 기능 이름 옆의 제한이 실사용 범위를 설명합니다.

보관된 workspace-ui와 workspace-structure-ui 보고서는 2026년 10월 12일 파일 기록이며, workspace-render는 10월 14일 기록입니다. 세 보고서의 passed 값과 항목을 읽었지만 오늘 전체 검사를 다시 실행했다는 뜻은 아닙니다. 오늘 새로 확인한 것은 한국어 명령 검색·창 연결과 레이어 잠금에 따른 메뉴 상태입니다.

PHOTOSHOT / SOURCE NOTES18

코드를 읽다.

app/studio/command-search.tsx · SHA-256 4367fb9d8f5f · L4–4포토샷 구현 코드 ↗
export type SearchCommand={id:string;label:string;path:string;key?:string;disabled?:boolean};
app/studio/command-search.tsx · SHA-256 4367fb9d8f5f · L9–9포토샷 구현 코드 ↗
 const terms=query.toLocaleLowerCase().trim().split(/\s+/),matches=commands.filter(c=>terms.every(t=>(c.path+' '+c.label+' '+(aliases[c.id]??'')).toLocaleLowerCase().includes(t))).slice(0,60),current=Math.min(index,Math.max(0,matches.length-1));
app/studio/command-search.tsx · SHA-256 4367fb9d8f5f · L11–11포토샷 구현 코드 ↗
 const execute=(c?:SearchCommand)=>{if(!c||c.disabled)return;close();run(c.id);};
Photoshot무료 포토샵 개발기 / 18IN PRACTICE

편집 화면에서.

메뉴 뒤의 동작 / workspace
실제 포토샷 작업 화면. 설정과 사진을 함께 확인할 수 있습니다.

기능마다 결과·저장·실패 조건을 남긴다

필터 대조표에는 검증 통과와 함께 Adobe 픽셀 동등성 미검증 같은 제한이 남아 있습니다. 이 방식으로 다음 개발기도 어떤 입력을 넣고, 어떤 결과를 확인했으며, 저장 후 무엇이 유지되는지를 나누어 쓰겠습니다. 문서에 메뉴가 있다는 사실만으로 모든 파일·환경을 지원한다고 확대하지 않겠습니다.

시연 인물은 새로 생성한 AI 모델입니다. 원본과 실제 메뉴 화면을 구분해서 보관했습니다. 다음 19편은 여러 문서의 저장·자동 복구·작업 공간을 다루며, 브라우저 로컬 저장과 내려받은 프로젝트 파일의 역할부터 확인합니다.

Photoshot무료 포토샵 개발기 / 18BEFORE / AFTER

원본과 실행 화면.

메뉴 뒤의 동작 / original
01 / AI 생성 시연 원본
메뉴 뒤의 동작 / result
02 / Image Size 명령 실행 화면 · 크기 변경 없이 취소

AI 생성 시연용 사진. 편집 화면과 출력 이미지는 실제 포토샷에서 만들었습니다.