Skip to content
This repository has been archived by the owner on Dec 31, 2022. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dertseha committed May 21, 2018
0 parents commit 8fc94c0
Show file tree
Hide file tree
Showing 48 changed files with 31,497 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea/

imgui.ini
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Contributing Guidelines

Thank you for considering to contribute to this library!

The following text lists guidelines for contributions.
These guidelines don't have legal status, so use them as a reference and common sense - and feel free to update them as well!


### "I just want to know..."

For questions, or general usage-information about **Dear ImGui**, please refer to the [homepage](https://github.com/ocornut/imgui), or look in the detailed documentation of the C++ source.
This wrapper houses next to no functionality. As long as it is not a Go-specific issue, help will rather be there.

### Scope

This wrapper exposes minimal functionality of **Dear ImGui**. Ideally, this functionality is that of the common minimum that someone would want. This wrapper does not strife for full configurability, like the original library. This is not even possible in some cases, as it requires compilation flags.

### Extensions
At the moment, this library is primarily used by **InkyBlackness**. If you can and want to make use of this library in your own projects, you are happy to do so. Pull-requests with extensions are happily accepted, provided that they uphold the following minimum requirements:
* Code is properly formatted & linted (use [metalinter](https://github.com/alecthomas/gometalinter) for a full check)
* Public Go API is documented (copied documentation from **Dear ImGui** is acceptable and recommended, assuming it is adapted regarding type names)
* Version philosophy is respected (see README.md)
60 changes: 60 additions & 0 deletions Context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package imgui

import (
"errors"
)

// #include "imguiWrapper.h"
import "C"

// Context specifies a scope of ImGui.
//
// All contexts share a same FontAtlas by default.
// If you want different font atlas, you can create them and overwrite the CurrentIO.Fonts of an ImGui context.
type Context struct {
handle C.IggContext
}

// CreateContext produces a new internal state scope.
// Passing nil for the fontAtlas creates a default font.
func CreateContext(fontAtlas *FontAtlas) *Context {
var fontAtlasPtr C.IggFontAtlas
if fontAtlas != nil {
fontAtlasPtr = fontAtlas.handle()
}
return &Context{C.iggCreateContext(fontAtlasPtr)}
}

// ErrNoContext is used when no context is current.
var ErrNoContext = errors.New("no current context")

// CurrentContext returns the currently active state scope.
// Returns ErrNoContext if no context is available.
func CurrentContext() (*Context, error) {
raw := C.iggGetCurrentContext()
if raw == nil {
return nil, ErrNoContext
}
return &Context{raw}, nil
}

// Destroy removes the internal state scope.
// Trying to destroy an already destroyed context does nothing.
func (context *Context) Destroy() {
if context.handle != nil {
C.iggDestroyContext(context.handle)
context.handle = nil
}
}

// ErrContextDestroyed is returned when trying to use an already destroyed context.
var ErrContextDestroyed = errors.New("context is destroyed")

// SetCurrent activates this context as the currently active state scope.
func (context Context) SetCurrent() error {
if context.handle == nil {
return ErrContextDestroyed
}
C.iggSetCurrentContext(context.handle)
return nil
}
71 changes: 71 additions & 0 deletions Context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package imgui

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestCurrentContextReturnsErrorIfNoContextIsCurrent(t *testing.T) {
context, err := CurrentContext()
assert.Nil(t, context, "No context expected")
assert.Equal(t, ErrNoContext, err, "Error expected")
}

func TestCreateContextReturnsNewInstance(t *testing.T) {
context := CreateContext(nil)
require.NotNil(t, context, "Context expected")
context.Destroy()
}

func TestCurrentContextCanBeRetrieved(t *testing.T) {
context := CreateContext(nil)
require.NotNil(t, context, "Context expected")
defer context.Destroy()

current, _ := CurrentContext()
assert.NotNil(t, current, "Current context expected")
}

func TestCurrentContextCanBeChanged(t *testing.T) {
context1 := CreateContext(nil)
require.NotNil(t, context1, "Context expected")
defer context1.Destroy()

first, _ := CurrentContext()
assert.True(t, context1.handle == first.handle, fmt.Sprintf("First context expected"))

context2 := CreateContext(nil)
require.NotNil(t, context2, "Context expected")
defer context2.Destroy()

context2.SetCurrent()

second, _ := CurrentContext()
assert.True(t, context2.handle == second.handle, fmt.Sprintf("Context should have changed to second 1=%v, 2=%v", context1, context2))

context1.SetCurrent()

third, _ := CurrentContext()
assert.True(t, context1.handle == third.handle, fmt.Sprintf("Context should have changed to first 1=%v, 2=%v", context1, context2))
}

func TestDestroyDoesNothingWhenCalledMultipleTimes(t *testing.T) {
context := CreateContext(nil)
require.NotNil(t, context, "Context expected")

context.Destroy()
context.Destroy()
context.Destroy()
}

func TestSetCurrentReturnsErrorWhenContextDestroyed(t *testing.T) {
context := CreateContext(nil)
require.NotNil(t, context, "Context expected")
context.Destroy()

err := context.SetCurrent()
assert.Equal(t, ErrContextDestroyed, err)
}
47 changes: 47 additions & 0 deletions DrawCommand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package imgui

// #include "DrawCommandWrapper.h"
import "C"

// DrawCommand describes one GPU call (or a callback).
type DrawCommand uintptr

func (cmd DrawCommand) handle() C.IggDrawCmd {
return C.IggDrawCmd(cmd)
}

// ElementCount is the number of indices (multiple of 3) to be rendered as triangles.
// Vertices are stored in the callee DrawList's VertexBuffer, indices in IndexBuffer.
func (cmd DrawCommand) ElementCount() int {
var count C.uint
C.iggDrawCommandGetElementCount(cmd.handle(), &count)
return int(count)
}

// ClipRect defines the clipping rectangle (x1, y1, x2, y2).
func (cmd DrawCommand) ClipRect() (rect Vec4) {
rectArg, rectFin := rect.wrapped()
defer rectFin()
C.iggDrawCommandGetClipRect(cmd.handle(), rectArg)
return
}

// TextureID is the user-provided texture ID.
// Set by user in FontAtlas.SetTextureID() for fonts or passed to Image*() functions.
// Ignore if never using images or multiple fonts atlas.
func (cmd DrawCommand) TextureID() TextureID {
var id C.IggTextureID
C.iggDrawCommandGetTextureID(cmd.handle(), &id)
return TextureID(id)
}

// HasUserCallback returns true if this handle command should be deferred.
func (cmd DrawCommand) HasUserCallback() bool {
return C.iggDrawCommandHasUserCallback(cmd.handle()) != 0
}

// CallUserCallback calls the user callback instead of rendering the vertices.
// ClipRect and TextureID will be set normally.
func (cmd DrawCommand) CallUserCallback(list DrawList) {
C.iggDrawCommandCallUserCallback(cmd.handle(), list.handle())
}
35 changes: 35 additions & 0 deletions DrawCommandWrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "imguiWrappedHeader.h"
#include "DrawCommandWrapper.h"
#include "WrapperConverter.h"

void iggDrawCommandGetElementCount(IggDrawCmd handle, unsigned int *count)
{
ImDrawCmd *cmd = reinterpret_cast<ImDrawCmd *>(handle);
*count = cmd->ElemCount;
}

void iggDrawCommandGetClipRect(IggDrawCmd handle, IggVec4 *rect)
{
ImDrawCmd *cmd = reinterpret_cast<ImDrawCmd *>(handle);
exportValue(*rect, cmd->ClipRect);
}

void iggDrawCommandGetTextureID(IggDrawCmd handle, IggTextureID *id)
{
ImDrawCmd *cmd = reinterpret_cast<ImDrawCmd *>(handle);
*id = cmd->TextureId;
}

IggBool iggDrawCommandHasUserCallback(IggDrawCmd handle)
{
ImDrawCmd *cmd = reinterpret_cast<ImDrawCmd *>(handle);
return (cmd->UserCallback != 0) ? 1 : 0;
}

void iggDrawCommandCallUserCallback(IggDrawCmd handle, IggDrawList listHandle)
{
ImDrawCmd *cmd = reinterpret_cast<ImDrawCmd *>(handle);
ImDrawList *list = reinterpret_cast<ImDrawList *>(listHandle);
cmd->UserCallback(list, cmd);
}

18 changes: 18 additions & 0 deletions DrawCommandWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "imguiWrapperTypes.h"

#ifdef __cplusplus
extern "C"
{
#endif

extern void iggDrawCommandGetElementCount(IggDrawCmd handle, unsigned int *count);
extern void iggDrawCommandGetClipRect(IggDrawCmd handle, IggVec4 *rect);
extern void iggDrawCommandGetTextureID(IggDrawCmd handle, IggTextureID *id);
extern IggBool iggDrawCommandHasUserCallback(IggDrawCmd handle);
extern void iggDrawCommandCallUserCallback(IggDrawCmd handle, IggDrawList listHandle);

#ifdef __cplusplus
}
#endif
42 changes: 42 additions & 0 deletions DrawData.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package imgui

// #include "DrawDataWrapper.h"
import "C"
import "unsafe"

// DrawData contains all draw data to render an ImGui frame.
type DrawData uintptr

func (data DrawData) handle() C.IggDrawData {
return C.IggDrawData(data)
}

// Valid indicates whether the structure is usable.
// It is valid only after Render() is called and before the next NewFrame() is called.
func (data DrawData) Valid() bool {
return (data.handle() != nil) && (C.iggDrawDataValid(data.handle()) != 0)
}

// CommandLists is an array of DrawList to render.
// The DrawList are owned by the context and only pointed to from here.
func (data DrawData) CommandLists() []DrawList {
var handles unsafe.Pointer
var count C.int

C.iggDrawDataGetCommandLists(data.handle(), &handles, &count)
list := make([]DrawList, int(count))
for i := 0; i < int(count); i++ {
list[i] = DrawList(*((*uintptr)(handles)))
handles = unsafe.Pointer(uintptr(handles) + unsafe.Sizeof(handles)) // nolint: gas
}

return list
}

// ScaleClipRects is a helper to scale the ClipRect field of each DrawCmd.
// Use if your final output buffer is at a different scale than ImGui expects,
// or if there is a difference between your window resolution and framebuffer resolution.
func (data DrawData) ScaleClipRects(scale Vec2) {
scaleArg, _ := scale.wrapped()
C.iggDrawDataScaleClipRects(data.handle(), scaleArg)
}
25 changes: 25 additions & 0 deletions DrawDataWrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "imguiWrappedHeader.h"
#include "DrawDataWrapper.h"
#include "WrapperConverter.h"

IggBool iggDrawDataValid(IggDrawData handle)
{
ImDrawData *drawData = reinterpret_cast<ImDrawData *>(handle);
IggBool result = 0;
exportValue(result, drawData->Valid);
return result;
}

void iggDrawDataGetCommandLists(IggDrawData handle, void **handles, int *count)
{
ImDrawData *drawData = reinterpret_cast<ImDrawData *>(handle);
*handles = reinterpret_cast<void **>(drawData->CmdLists);
*count = drawData->CmdListsCount;
}

void iggDrawDataScaleClipRects(IggDrawData handle, IggVec2 const *scale)
{
ImDrawData *drawData = reinterpret_cast<ImDrawData *>(handle);
Vec2Wrapper wrappedScale(scale);
drawData->ScaleClipRects(*wrappedScale);
}
16 changes: 16 additions & 0 deletions DrawDataWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "imguiWrapperTypes.h"

#ifdef __cplusplus
extern "C"
{
#endif

extern IggBool iggDrawDataValid(IggDrawData handle);
extern void iggDrawDataGetCommandLists(IggDrawData handle, void **handles, int *count);
extern void iggDrawDataScaleClipRects(IggDrawData handle, IggVec2 const *scale);

#ifdef __cplusplus
}
#endif
29 changes: 29 additions & 0 deletions DrawData_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package imgui_test

import (
"testing"

"github.com/inkyblackness/imgui-go"

"github.com/stretchr/testify/assert"
)

func TestDrawData(t *testing.T) {
context := imgui.CreateContext(nil)
defer context.Destroy()

io := imgui.CurrentIO()
io.SetDisplaySize(imgui.Vec2{X: 800, Y: 600})
io.Fonts().TextureDataAlpha8()

for i := 0; i < 2; i++ {
imgui.NewFrame()
imgui.ShowDemoWindow(nil)
imgui.Render()
}
drawData := imgui.RenderedDrawData()

assert.True(t, drawData.Valid(), "Draw data should be valid")
list := drawData.CommandLists()
assert.True(t, len(list) > 0, "At least one draw data list expected")
}
Loading

0 comments on commit 8fc94c0

Please sign in to comment.