Skip to content

Commit eebec3e

Browse files
authored
Merge pull request #13 from Garume/garume/edit-markdown
Garume/edit markdown
2 parents 4fb1e27 + ede14d1 commit eebec3e

File tree

4 files changed

+485
-80
lines changed

4 files changed

+485
-80
lines changed

README.md

Lines changed: 242 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,40 +20,31 @@ Context Circle Menu is a simple open-source tool for Unity. It lets users open a
2020
### Feature
2121

2222
- Create Context Circle Menu
23-
24-
![alt text](docs/image.png)
25-
2623
- Easy to use Editor Icon
27-
2824
- Customized Menu
29-
3025
- Add from Attribute
31-
32-
![alt text](docs/image-1.png)
33-
3426
- Add Manual
35-
36-
![alt text](docs/image-2.png)
37-
27+
- Button design
28+
- Folder design
3829
- Open in Scene View
3930
- Customized Shortcut Key
4031

41-
![alt text](docs/image-3.png)
42-
4332
## Table of Contents
4433
- [Context Circle Menu](#context-circle-menu)
45-
- [Overview](#overview)
46-
- [Feature](#feature)
47-
- [Table of Contents](#table-of-contents)
48-
- [Setup](#setup)
49-
- [Requirements](#requirements)
50-
- [Installation](#installation)
51-
- [Demonstration](#demonstration)
52-
- [Editor Icons](#editor-icons)
53-
- [Customized Menu](#customized-menu)
54-
- [Manual Add Method](#manual-add-method)
55-
- [Customized Button](#customized-button)
56-
- [Customized Shortcut Key](#customized-shortcut-key)
34+
- [Overview](#Overview)
35+
- [Features](#Features)
36+
- [Table of Contents](#Table-of-Contents)
37+
- [Setup](#Setup)
38+
- [Requirements](#Requirements)
39+
- [Installation](#Installation)
40+
- [Demonstration](#Demonstration)
41+
- [Editor Icons](#editor-icons)
42+
- [Add Manual Method](#Add-Manual-Method)
43+
- [Customize](#Customize)
44+
- [Customize Buttons](#Customize-Buttons)
45+
- [Customize Folder](#Customize-Folder)
46+
- [Customize Shortcut](#Customized-Shortcut-Key)
47+
- [API Documentation](#API-Documentation)
5748
- [LISENCE](#lisence)
5849
- [AUTHOR](#author)
5950

@@ -121,7 +112,7 @@ Then you will see below menu.
121112

122113
[![Image from Gyazo](https://i.gyazo.com/39b665e8fdd473bb408102e1b5d5bf09.gif)](https://gyazo.com/39b665e8fdd473bb408102e1b5d5bf09)
123114

124-
## Editor Icons
115+
### Editor Icons
125116

126117
Icons can be attached to menu buttons.
127118

@@ -136,9 +127,6 @@ public static void TestMethod()
136127
Debug.Log("TestMethod");
137128
}
138129
```
139-
140-
## Customized Menu
141-
142130
### Manual Add Method
143131

144132
If you do not want to use the `Context Circle Menu` attribute, you can register the method manually.
@@ -161,25 +149,94 @@ public class Menu
161149
}
162150
```
163151

152+
## Customization
153+
164154
### Customized Button
165155

166-
If you don't like the button UI, you can replace it with your own.
156+
If you don't like the UI of the button, you can replace it with your own button.
167157

168-
Use `builder.ConfigureFolder();`
158+
Use `builder.ConfigureButton` in `ContextCircleMenuLoader.OnBuild`.
169159

170-
> [!CAUTION]
171-
> It is an incomplete feature.
172-
>
173-
> Destructive changes may be made.
160+
```cs
161+
ContextCircleMenuLoader.OnBuild += (builder =>
162+
{
163+
...
164+
builder.ConfigureButton(FolderMenuFactory);
165+
});
166+
```
167+
168+
To create your own button, you must create a class that extends CircleButton and a corresponding Factory class.
174169

175-
First, you need to create a FolderMenu that extends `CircleMenu`.
176-
You can create buttons freely in `CreateButtons`.
177-
Please refer to `FolderCircleMenu.cs` for detailed code.
170+
Here is an example code similar to the one provided in Sample's Custom.
178171

179-
Next, create a FolderMenuFactory that implements `IFolderCircleMenuFactory`.
180-
Please refer to `CircleMenuFactory` for detailed code.
172+
Samples can be imported from Package Manager > ContextCircleMenu > Samples.
181173

182-
Finally, you can replace the UI by doing the below.
174+
In this example, the button is replaced with a button that displays only an icon.
175+
176+
Create the following class
177+
178+
```cs
179+
public class CustomButtonFactory : IButtonFactory
180+
{
181+
public CircleButton Create(string path, GUIContent icon, Action onSelected, int section)
182+
{
183+
return new OnlyImageCircleButton(path, icon, section, onSelected);
184+
}
185+
186+
// Back button is needed when creating a folder structure menu.
187+
// section should be -1 unless ConfigureFolder is used.
188+
public CircleButton CreateBackButton(Action onBack)
189+
{
190+
return new OnlyImageCircleButton("Back", EditorGUIUtility.IconContent(EditorIcons.Back2x),
191+
-1, onBack);
192+
}
193+
}
194+
195+
public class OnlyImageCircleButton : CircleButton
196+
{
197+
public OnlyImageCircleButton(string text, GUIContent icon, int section, Action onSelect) : base(text, icon, section, onSelect)
198+
{
199+
}
200+
201+
// You can edit the generated buttons.
202+
// Feel free to customize the buttons here.
203+
protected override void ModifierButton(Button button, string text, GUIContent icon, int section)
204+
{
205+
var image = new Image
206+
{
207+
image = icon.image,
208+
style =
209+
{
210+
width = 32f,
211+
height = 32f,
212+
flexShrink = 0
213+
},
214+
tooltip = text
215+
};
216+
217+
button.Add(image);
218+
}
219+
}
220+
221+
```
222+
223+
Set the created Factory class.
224+
225+
```cs
226+
ContextCircleMenuLoader.OnBuild += (builder =>
227+
{
228+
...
229+
builder.ConfigureButton(new CustomButtonFactory());
230+
});
231+
```
232+
233+
It will then be replaced by a button that displays only the icon as shown below.
234+
235+
![alt text](docs/image-6.png)
236+
237+
### Customize Folder
238+
239+
If you don't like the folder UI, you can replace it with your own folder.
183240

184241
```cs
185242
ContextCircleMenuLoader.OnBuild += (builder =>
@@ -189,7 +246,93 @@ ContextCircleMenuLoader.OnBuild += (builder =>
189246
});
190247
```
191248

192-
## Customized Shortcut Key
249+
> [!CAUTION]
250+
> Destructive changes were made in v1.0.0.
251+
252+
To create your own folder, you need to create a class that extends FolderCircleMenu and a corresponding Factory class.
253+
254+
255+
Here is an example code similar to the one provided in Sample's Custom.
256+
257+
Samples can be imported from Package Manager > ContextCircleMenu > Samples.
258+
259+
In this example, we are replacing an existing UI with vector graphics.
260+
261+
Create the following classes
262+
263+
```cs
264+
public class CustomFolderMenuFactory : IFolderCircleMenuFactory
265+
{
266+
public FolderCircleMenu Create(string path, IMenuControllable menu, CircleMenu parent, IButtonFactory factory)
267+
{
268+
return new CustomFolderCircleMenu(path, menu, parent, factory);
269+
}
270+
}
271+
272+
public class CustomFolderCircleMenu : FolderCircleMenu
273+
{
274+
public CustomFolderCircleMenu(string path, IMenuControllable menu, CircleMenu parent, IButtonFactory factory) :
275+
base(path, menu, EditorGUIUtility.IconContent(EditorIcons.FolderIcon), parent, factory)
276+
{
277+
}
278+
279+
protected override VisualElement[] CreateUtilityElements(ref ContextCircleMenuOption menuOption)
280+
{
281+
var element = new VisualElement();
282+
var option = menuOption;
283+
element.generateVisualContent += context =>
284+
{
285+
var painter = context.painter2D;
286+
var buttonCount = ButtonElements.Length;
287+
for (var i = 0; i < buttonCount; i++)
288+
{
289+
var angle = (float)i / buttonCount * 360f;
290+
if (buttonCount % 2 == 1)
291+
angle += 180f;
292+
else
293+
angle += 180f - 360f / buttonCount / 2;
294+
var vector = new Vector2(
295+
Mathf.Sin(Mathf.Deg2Rad * angle),
296+
Mathf.Cos(Mathf.Deg2Rad * angle)).normalized;
297+
298+
var from = vector * 12f;
299+
var to = vector * option.Radius * 1.5f;
300+
painter.strokeColor = Color.black;
301+
painter.lineWidth = 2f;
302+
painter.BeginPath();
303+
painter.MoveTo(from);
304+
painter.LineTo(to);
305+
painter.Stroke();
306+
}
307+
308+
painter.BeginPath();
309+
painter.Arc(Vector2.zero, option.Radius * 1.5f, 0, 360f);
310+
painter.fillColor = new Color(0f, 0f, 0f, 0.2f);
311+
painter.Fill();
312+
313+
painter.DrawCircle(Vector2.zero, option.Radius * 1.5f, 0, 360f, 5f, Color.gray);
314+
};
315+
return new[] { element };
316+
}
317+
}
318+
```
319+
320+
Set the created Factory class.
321+
322+
```cs
323+
ContextCircleMenuLoader.OnBuild += (builder =>
324+
{
325+
...
326+
builder.ConfigureButton(new CustomButtonFactory());
327+
builder.ConfigureFolder(new CustomFolderMenuFactory());
328+
});
329+
```
330+
331+
Then it will be replaced by the following UI.
332+
333+
! [alt text](docs/image-5.png)
334+
335+
### Customized Shortcut Key
193336

194337
The default menu open/close button is set to the `A` key, but can be changed freely.
195338

@@ -201,6 +344,63 @@ Search for `Context Circle Menu` and you will find the settings as shown in the
201344

202345
Set the keys as you like.
203346

347+
## API Documentation
348+
349+
This section describes the major APIs and can be used as a reference when customizing the UI.
350+
351+
### ContextCircleMenu
352+
353+
#### property
354+
| property name | description |
355+
| ---- | ---- |
356+
| BlockMouseEvents | Disables mouse operations such as clicking if true. |
357+
358+
#### method
359+
| method name | description |
360+
| ---- | ---- |
361+
| Show() | Show menu. |
362+
| Hide() | Hide menu. |
363+
| Open(CircleMenu menu) | Opens the menu specified in the argument. |
364+
| Back() | Open the previous menu. |
365+
| TryForceSelect() | If there is a button in focus, it is forced to select it. |
366+
| TryForceEnterByMousePosition() | Forces the button corresponding to the mouse position to focus. |
367+
| CreateMenu(Action\<CircleMenuBuilder\> configureMenu) | Create the menu content using CircleMenuBuilder. |
368+
369+
### CircleMenuBuilder
370+
#### method
371+
| method name | description |
372+
| ---- | ---- |
373+
| AddMenu(ICircleMenuFactory factory) | Add custom menu. |
374+
| AddMenu(string path, GUIContent content, Action action) | Add a menu manually. |
375+
| AddMenu(ContextCircleMenuAttribute attribute, MethodInfo method) | Add a menu from the attributes. |
376+
| ConfigureFolder(IFolderCircleMenuFactory factory) | Replace with your custom folder menu. |
377+
| ConfigureButton(IButtonFactory factory) | Replace with your custom button. |
378+
379+
### CircleMenu
380+
#### abstract method
381+
| method name | description |
382+
| ---- | ---- |
383+
| CreateButtons(IButtonFactory factory, ref ContextCircleMenuOption menuOption) | Create a button to be displayed on the menu. The IButtonFactory passed here will be the one set in CircleMenuBuilder.ConfigureButton(). |
384+
385+
#### virtual method
386+
| method name | description |
387+
| ---- | ---- |
388+
| CreateUtilityElements(ref ContextCircleMenuOption menuOption) | Create elements other than buttons. |
389+
| OnInitialized(ref ContextCircleMenuOption menuOption) | Called at initialization. |
390+
| OnBuild() | Called when an element is created. Mainly when Show() or Open() is called. |
391+
392+
### CircleButton
393+
#### abstract method
394+
| method name | description |
395+
| ---- | ---- |
396+
| ModifierButton(Button button, string text, GUIContent icon, int section) | Called when creating a button. Use it to modify the elements of the button. |
397+
398+
#### virtual method
399+
| method name | description |
400+
| ---- | ---- |
401+
| OnMouseEnter(Button button, MouseEnterEvent evt) | Called when the mouse enters an element.|
402+
| OnMouseLeave(Button button, MouseLeaveEvent evt) | Called when the mouse leaves an element. |
403+
204404
## LISENCE
205405

206406
MIT

0 commit comments

Comments
 (0)