300 lines
7.8 KiB (Stored with Git LFS)
Markdown
300 lines
7.8 KiB (Stored with Git LFS)
Markdown
# StreamDock 샘플 플러그인 개발 가이드
|
|
|
|
## 🎯 목표
|
|
이 가이드를 통해 StreamDock용 첫 번째 플러그인을 만들어보겠습니다.
|
|
|
|
## 📁 프로젝트 구조
|
|
|
|
### 1. 기본 구조
|
|
```
|
|
my-first-plugin/
|
|
├── manifest.json # 플러그인 메타데이터
|
|
├── plugin/
|
|
│ ├── index.js # 메인 플러그인 로직
|
|
│ └── utils/
|
|
│ └── plugin.js # 유틸리티 함수들
|
|
├── propertyInspector/
|
|
│ └── action1/
|
|
│ ├── index.html # 설정 UI
|
|
│ ├── index.js # 설정 로직
|
|
│ └── index.css # 스타일
|
|
├── static/
|
|
│ ├── default.jpg # 기본 아이콘
|
|
│ └── CH.png # 플러그인 아이콘
|
|
└── package.json # Node.js 의존성
|
|
```
|
|
|
|
## 🛠️ 단계별 개발
|
|
|
|
### 1단계: 새 플러그인 폴더 생성
|
|
```bash
|
|
# demo 플러그인을 복사
|
|
cp -r SDNodeJsSDK/com.mirabox.streamdock.demo.sdPlugin SDNodeJsSDK/my-first-plugin
|
|
```
|
|
|
|
### 2단계: manifest.json 수정
|
|
```json
|
|
{
|
|
"Actions": [
|
|
{
|
|
"Icon": "static/CH.png",
|
|
"Name": "내 첫 번째 액션",
|
|
"States": [
|
|
{
|
|
"FontSize": "10",
|
|
"TitleAlignment": "bottom",
|
|
"Image": "static/default.jpg"
|
|
}
|
|
],
|
|
"Controllers": [
|
|
"Keypad",
|
|
"Information",
|
|
"Knob"
|
|
],
|
|
"UserTitleEnabled": true,
|
|
"SupportedInMultiActions": false,
|
|
"Tooltip": "첫 번째 플러그인 액션",
|
|
"UUID": "com.mycompany.streamdock.myfirstplugin.action1",
|
|
"PropertyInspectorPath": "propertyInspector/action1/index.html"
|
|
}
|
|
],
|
|
"SDKVersion": 1,
|
|
"Author": "내 이름",
|
|
"Name": "내 첫 번째 플러그인",
|
|
"Icon": "static/CH.png",
|
|
"CodePath": "plugin/app.exe",
|
|
"Description": "StreamDock용 첫 번째 플러그인",
|
|
"Category": "개발자 도구",
|
|
"CategoryIcon": "static/CH.png",
|
|
"Version": "1.0.0",
|
|
"URL": "https://github.com/myusername/my-first-plugin",
|
|
"OS": [
|
|
{
|
|
"Platform": "windows",
|
|
"MinimumVersion": "7"
|
|
}
|
|
],
|
|
"Software": {
|
|
"MinimumVersion": "2.9"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3단계: 플러그인 로직 작성 (plugin/index.js)
|
|
```javascript
|
|
const { Plugins, Actions, log } = require('./utils/plugin');
|
|
|
|
const plugin = new Plugins();
|
|
|
|
// 첫 번째 액션
|
|
plugin.action1 = new Actions({
|
|
default: {},
|
|
|
|
// 버튼이 나타날 때
|
|
_willAppear({ context }) {
|
|
plugin.setTitle(context, "안녕하세요!");
|
|
log.info('플러그인이 로드되었습니다.');
|
|
},
|
|
|
|
// 버튼이 사라질 때
|
|
_willDisappear(data) {
|
|
log.info('플러그인이 언로드되었습니다.');
|
|
},
|
|
|
|
// 설정 패널이 나타날 때
|
|
_propertyInspectorDidAppear(data) {
|
|
log.info('설정 패널이 열렸습니다.');
|
|
},
|
|
|
|
// 키패드 버튼 클릭
|
|
_keyDown(data) {
|
|
log.info('버튼이 클릭되었습니다!');
|
|
// 여기에 원하는 동작 추가
|
|
// 예: 키보드 단축키 실행, 프로그램 실행 등
|
|
},
|
|
|
|
// 키패드 버튼 해제
|
|
_keyUp(data) {
|
|
log.info('버튼이 해제되었습니다.');
|
|
},
|
|
|
|
// 다이얼 회전
|
|
dialRotate(data) {
|
|
log.info('다이얼이 회전했습니다:', data);
|
|
},
|
|
|
|
// 다이얼 누름
|
|
dialDown(data) {
|
|
log.info('다이얼이 눌렸습니다:', data);
|
|
}
|
|
});
|
|
```
|
|
|
|
### 4단계: 설정 UI 작성 (propertyInspector/action1/index.html)
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>내 첫 번째 플러그인 설정</title>
|
|
<link rel="stylesheet" href="index.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h3>내 첫 번째 플러그인</h3>
|
|
|
|
<div class="form-group">
|
|
<label for="buttonText">버튼 텍스트:</label>
|
|
<input type="text" id="buttonText" placeholder="버튼에 표시할 텍스트">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="actionType">동작 유형:</label>
|
|
<select id="actionType">
|
|
<option value="message">메시지 표시</option>
|
|
<option value="keyboard">키보드 단축키</option>
|
|
<option value="program">프로그램 실행</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<button id="saveButton">저장</button>
|
|
<button id="testButton">테스트</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="index.js"></script>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
### 5단계: 설정 로직 작성 (propertyInspector/action1/index.js)
|
|
```javascript
|
|
let settings = {};
|
|
|
|
// 설정 로드
|
|
function loadSettings() {
|
|
const savedSettings = localStorage.getItem('myFirstPluginSettings');
|
|
if (savedSettings) {
|
|
settings = JSON.parse(savedSettings);
|
|
document.getElementById('buttonText').value = settings.buttonText || '';
|
|
document.getElementById('actionType').value = settings.actionType || 'message';
|
|
}
|
|
}
|
|
|
|
// 설정 저장
|
|
function saveSettings() {
|
|
settings.buttonText = document.getElementById('buttonText').value;
|
|
settings.actionType = document.getElementById('actionType').value;
|
|
|
|
localStorage.setItem('myFirstPluginSettings', JSON.stringify(settings));
|
|
|
|
// StreamDock에 설정 전송
|
|
if (window.streamdeck) {
|
|
window.streamdeck.setSettings(settings);
|
|
}
|
|
}
|
|
|
|
// 이벤트 리스너 등록
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadSettings();
|
|
|
|
document.getElementById('saveButton').addEventListener('click', saveSettings);
|
|
document.getElementById('testButton').addEventListener('click', function() {
|
|
alert('테스트 버튼이 클릭되었습니다!');
|
|
});
|
|
});
|
|
```
|
|
|
|
### 6단계: 스타일 작성 (propertyInspector/action1/index.css)
|
|
```css
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 0;
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.container {
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
h3 {
|
|
margin-top: 0;
|
|
color: #333;
|
|
}
|
|
|
|
.form-group {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
label {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
font-weight: bold;
|
|
color: #555;
|
|
}
|
|
|
|
input, select {
|
|
width: 100%;
|
|
padding: 8px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
button {
|
|
background-color: #007bff;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
|
|
#testButton {
|
|
background-color: #28a745;
|
|
}
|
|
|
|
#testButton:hover {
|
|
background-color: #1e7e34;
|
|
}
|
|
```
|
|
|
|
## 🚀 테스트 및 배포
|
|
|
|
### 1. 로컬 테스트
|
|
1. StreamDock 소프트웨어 실행
|
|
2. 플러그인 폴더에 새로 만든 플러그인 폴더 지정
|
|
3. 플러그인 로드 확인
|
|
4. 버튼 클릭 및 설정 테스트
|
|
|
|
### 2. 디버깅
|
|
- 브라우저 개발자 도구로 Property Inspector 디버깅
|
|
- StreamDock 로그 확인
|
|
- console.log() 활용한 디버깅
|
|
|
|
### 3. 배포 준비
|
|
1. 불필요한 파일 제거
|
|
2. README.md 작성
|
|
3. 라이선스 파일 추가
|
|
4. 패키징
|
|
|
|
## 📚 다음 단계
|
|
|
|
1. **고급 기능 추가**: HTTP 요청, 파일 시스템 접근 등
|
|
2. **다중 액션 지원**: 여러 버튼을 하나의 플러그인에서 관리
|
|
3. **외부 API 연동**: 게임, 스트리밍 플랫폼 API 활용
|
|
4. **UI 개선**: 더 나은 사용자 경험 제공
|
|
|
|
---
|
|
|
|
**이제 첫 번째 StreamDock 플러그인을 만들어보세요! 🎉** |