목차
프레임: 표현과 컨트롤의 서식, 전체적인 틀
표현: 변수, 데이터 표현(ex: Text, Image)
컨트롤: 변수, 데이터 변경 & 호출(ex: Button, InputText, Slider)
NameID는 중복되면 안된다.(ImGui이벤트맵이 NameID로 찾기 때문이다.)
NameID에 "##"를 먼저 작성하면 NameID가 기본 라벨로 표시되지 않는다.
구현은 기본적으로 윈도우 프레임내에서 대부분 구현이 가능하다.(코멘트는 대략적인 흐름)
bool* active, selected, hide
int* index
if(ImGui::BeginMainMenuBar())
{
//메뉴 추가 or 아이템 구현
ImGui::EndMainMenuBar();
}
if(active)
{
ImGui::Begin(nameID,&active,flag))
//메뉴 or 아이템 구현
ImGui::End();
}
윈도우 프레임 falg에 ImGuiWindowFlags_MenuBar 포함해야함.
if(ImGui::BeginMenuBar())
{
//메뉴 추가 or 아이템 구현
ImGui::EndMenuBar();
}
if(ImGui::BeginMenu(nameID,&active))
{
//하위 메뉴 추가 or 아이템 구현
ImGui::EndMenu();
}
if(ImGui::MenuItem(nameID,HotKey, &selected,&active))
{
//처리 구현
}
selected를 사용하면 토글형식으로 변경됨
if(ImGui::BeginTabBar(nameID,flag))
{
//탭 아이템 & 버튼 구현
ImGui::EndTabBar();
}
if(ImGui::BeginTabItem(nameID,&active,flag))
{
//처리 구현
ImGui::EndTabItem();
}
if(ImGui::TabItemButton(nameID,flag))
{
//처리 구현
}
if(ImGui::CollapsingHeader(nameID,&hide,flag))
{
//아이템 구현
}
if (ImGui::TreeNode(nameID))
{
//서브 노드 or 아이템 구현
ImGui::TreePop();
}
Popup 조건 구현(버튼, 호버체크 등)
if(ImGui::Button(nameID,size))
{
//↓코드 팝업사용시 필수입니다.
//ImGui::OpenPopup(nameID);
}
//동일한 nameID를 가진 Popup구현
if(ImGui::BeginPopup(nameID,flag)
{
//아이템 구현
}
Popup 조건 구현(버튼, 호버체크 등)
if(ImGui::BeginPopupContextItem(nameID,flag))
{
//아이템 구현
ImGui::EndPopup();
}
Popup 조건 구현(버튼, 호버체크 등)
if(ImGui::BeginPopupModal(nameID,&active,flag))
{
//아이템 구현
//모달 윈도우 닫기
if(ImGui::Button(nameID,size))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
Tooltip 조건 구현(일반적으로 호버체크)
if(ImGui::IsItemHovered(flag))
{
//tooltip 구현
}
툴팁 구현법 2가지
ImGui::SetTooltip("contents");
if(ImGui::BeginTooltip())
{
//콘텐츠 구현
ImGui::EndTooltip();
}
if(ImGui::BeginChild(nameID,size,borded,flag))
{
//
ImGui::EndChild();
}
if (ImGui::BeginListBox(nameID,size))
{
//아이템 구현
ImGui::EndListBox();
}
자동 셀렉터블화(index)
ImGui::ListBox(nameID,&index,&list,listSize,showCount);
if(ImGui::BeginTable(nameID,Column,flag,size))
{
ImGui::TableNextColumn();
//모든 아이템 구현하기
//아이템 구현
//ImGui::TableNextColumn();
//반복...
ImGui::EndTable();
}
ImGui::TableSetColumnIndex(column);//수동 입력
비활성화 구현법 3가지
ImGui::BeginDisabled(disabled);
//비활성화될 수 도있는 아이템
if(disabled)
{
ImGui::EndDisabled();
}
if(disabled)
{
ImGui::BeginDisabled();
}
//비활성화될 수 도있는 아이템
if(disabled)
{
ImGui::EndDisabled();
}
ImGui::BeginDisabled();
//비활성화 아이템
ImGui::EndDisabled();
ImGui::Separator();// 구분선
ImGui::Spacing();// 줄간격 늘리기
ImGui::NewLine();//다음 GUI를 다음 줄에 그리기
ImGui::SameLine(offset,spacing);//다음 GUI를 같은 줄에 그리기
ImGui::Indent();//들여쓰기
ImGui::Unindent();//내어쓰기
ImGui::BeginGroup();
//그룹화
ImGui::EndGroup();
그룹 아이템 처리
윈도우 프레임 flag에 ImGuiWindowFlags_HorizontalScroll을 포함
ImGui::SetScrollHereX()
ImGui::SetScrollHereY()
ImGui::Text("contents");//일반 쓰기
ImGui::TextColored(color,"contents");//글자 색상 쓰기
ImGui::TextDisabled("contents");//비활성화 쓰기
ImGui::Value("%format",typeValue)
ImGui::Bullet();
ImGui::BulletText("contents");
ImDrawList* dl =
ImGui::GetWindowDrawList(); or
ImGui::GetForegroundDrawList(); or
ImGui::GetBackgroundDrawList();
dl->AddXXX(pos, size);
ImGui::Image(TextureID,size,uv0,uv1,tintcolor,framecolor);//일반 이미지
TextureID는 void* 타입이다.
renderBackend에 의해 결정된다.
ImGui::PlotLines(nameID,list,listSize,offset,overlayText,scaleMin,scaleMax,graphSize,stride);
ImGui::PlotHistogram(nameID,list,listSize,offset,overlayText,scaleMin,scaleMax,graphSize,stride);
ImGui::Dummy(size);
컨트롤(키, 마우스) 체크, 변수 참조
ImGui에서 컨트롤를 사용하려면 ImGuiProc를 플랫폼의 메시지 Proc에 추가해야된다.
ImGui:::IsMouseClicked(0)
ImGui:::IsMouseDoubleClicked(0)
ImGui:::IsMouseDown(0)
ImGui:::IsMouseReleased(0)
ImGui:::IsMouseDragging(0)
ImGui:::IsMouseHoveringRect(0,pos,size)
(0=left, 1=right, 2=middle)
ImGui::IsWindowedFocused()
ImGui::IsWindowHovered()
ImGui::IsWindowCollapsed()
if(ImGui::GetIO().KeyXX)
KeyCtrl, KeyShift, KeyAlt, KeySuper
for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1))
{
if(!ImGui::IsKeyDown(key))continue;
ImGui::GetKeyName(key);
ImGui::GetKeyIndex(ImGuiKey_XX);
ImGui::GetKeyData(key);
}
if(ImGui::IsKey_XXX(ImGuiKey_XX))
ImGui::IsItemFocused()
ImGui::IsItemHovered()
ImGui::IsItemActive()
ImGui::IsItemEdited()
ImGui::IsItemVisible();
ImGui::IsItemClicked();
ImGui::IsItemActivated();
ImGui::IsItemDeactivated();
ImGui::IsItemDeactivatedAfterEdit()
ImGui::IsItemToggledOpen()
static ImGuiTextFilter filter("default filter contents");
filter.Draw();//inputfield
filter.PassFilter("filter contents");
if(filter.PassFilter("contents"))
{
//처리
}
Type Float, Float2, Float3, Float4, Int, Int2, Int3, Int4, Scalar, ScalarN, Double
ImGui::InputXXX();
ImGui::InputTextWithHint(nameID,"hint",buffer,bufferSize);
ImGui::InputTextMultiline(nameID,buffer,bufferSize,fieldSize,ImGuiInputTextFlags);
ImGui::SliderXXX(nameID,&T,minValue,maxValue,format);
ImGui::VSliderXXX(nameID,&T,minValue,maxValue,format);
ImGui::DragXXX(nameID,&T,float dragSpeed,T min, T max);
ImGUI::Button(nameID,size,)
if(ImGui::RadioButton(nameID,&enabled))
if(ImGui::ArrowButton(nameID,ImGuiDir_XX))
if (ImGui::ImageButton(nameID my_tex_id, size, uv0, uv1, bg_col, tint_col))
ImGui::SmallButton(nameID);
ImGui::InvisibleButton(nameID);
ImGui::CloseButton();
ImGui::CollapseButton();
ImGui::PushButtonRepeat(true);
ImGui::PopButtonRepeat();
if(ImGui::BeginCombo())
{
ImGui::EndCombo();
}
ImGui::Combo("NameID",&T,"first\0second\0third");
ImGui::Checkbox(nameID, &address);
ImGui::CheckboxFlags(nameID,&address,flag);
ImGui::Selectable(nameID,&select,flag,size);
bool형 반환
ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0);
ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0);
ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0);
ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL);
ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, const ImVec2& size = ImVec2(0, 0));
SetColorEditOptions(ImGuiColorEditFlags flags);
ImGui::PushID();// //ImGui::PopID();
ImGui::PushItemWidth(-160);
ImGui::GetID(nameID);
ImGui::PushID(intID);
ImGui::PushID(nameID);
ImGui::PopID();
ImGUI::PushStyleColor(ImGuiCol_Button, thisbuttonColor);
ImGUI::PushStyleColor(ImGuiCol_ButtonHovered, thisbuttonColor);
ImGUI::PushStyleColor(ImGuiCol_ButtonActive, thisbuttonColor);
ImGui::PopStyleColor(3);
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment);
ImGui::PopStyleVar();
ImGui::PushStyleCompact();
ImGui::PopStyleCompact();
ImGui::PushItemWidth(x)
ImGui::PopItemWidth()
ImGui::LogButtons();
ImGui::LogToTTY();
ImGui::LogToClipboard();//클립보드 복사
ImGui::LogText("Hello, world!" IM_NEWLINE);
ImGui::LogFinish();
컨트롤(키, 마우스) 체크, 변수 참조
ImGui::GetWindowPos()
ImGui::GetWindowSize()
Imgui::GetIo()
namespace ImGui
{
void HelpMarker("HelpContents")
{
ImGui::TextDisabled("(?)");
if(ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort))
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted("HelpContents");
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
}
폰트 로드하기(InitScope)
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\malgun.ttf",18.0f,NULL,io.Fonts->GetGlyphRangesKorean());
사용하기
ImGui::Text(u8"콘텐츠"); //u8
if(ImGui::Begin("window"))
{
ImGui::End();
}
ImGui윈도우나 자식윈도우를 이 방법으로 선언하면 해당 윈도우에 도킹할 수 없다.(Begin()과 End()호출이 짝이맞지 않기 때문?)
ImGui::Begin();
//context
ImGui::End();
식으로 선언할 것.
ImGui기능으로 연결한 플래그들은 그 값을 바꾸는 것이지, 값을 통해 ImGui컨텍스트들이 변경되지않는다.(표시는 변경)
if(actived)
{
//윈도우에 종료 버튼이 생긴다. 해당 버튼을 누를 시 acitved가 변경된다.
ImGui::Begin("sample", &actived);
ImGui::End();
}
else
{
//윈도우 자체가 함수일때, 해당 로직을 통해 GUI연산을 멈추도록 한다.
return;
}
//InitScope안에 ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;//선언필요
//FrameScope안에 ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
ImGui는 기본 암시적 Debug윈도우를 호출해서 ImGui를 메인 뷰포트에 바로 그릴 수 없다.
아래 코드를 작성하면 메인뷰포트 크기의 윈도우를 생성가능하고, 해당 윈도우에 Imgui 그릴 수 있다.
ImGui::SetNextWindowPos({0,0}, ImGuiCond_Always);
ImGui::SetNextWindowSize({ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y}, ImGuiCond_Always);
ImGui::Begin("##main",nullptr,ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize);
ImGui::End();
https://github.com/dfranx/ImFileDialog
https://github.com/nothings/stb/blob/master/stb_image.h
해당 소스다운로드후 ImGui폴더에 추가
해당 소스가 #include <filesystem>를 이용해 구현했기 때문에
c++17이상 환경에서 작동
ImFileDialog.h 파일에서
std::function인 CreateTexture, DeleteTexture 부분을 찾아서 아래 빈 람다식으로 초기화선언한다.(필요하면 구현할 것)
std::function<void*(uint8_t*, int, int, char)> CreateTexture = [](uint8_t* data, int w, int h, char fmt) -> void* {return nullptr;}; // char -> fmt -> { 0 = BGRA, 1 = RGBA }
std::function<void(void*)> DeleteTexture = [](void* tex){};
ImFileDialog.cpp 파일 #include "windows.h"하단에 아래 코드 추가
#ifdef max
#undef max//for use std::max
#endif
ImFileDialog.cpp 파일 #Include imgui.h,imgui_internal.h파일과 상대 경로맞추기
<imgui/imgui.h>
<imgui/imgui_internal.h>
같은 위치에 존재한다면
"imgui.h"
"imgui_internal.h"
ImFileDialog.cpp 파일 하단 ImGui 키입력 코드변경
int escapeKey = ImGui::GetIO().KeyMap[ImGuiKey_Escape];
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) &&
escapeKey >= 0 && ImGui::IsKeyPressed(ImGuiKey_Escape))
m_isOpen = false;
TMI.C++20이상환경에서 오류
c++20에서 새로운 자료형 char8_t가 생겨서 char와 char8_t 연산이 불가능하기 때문.
c++20에 맞는 표준 라이브러리를 소유시 string생성자(char8_t*)가 새로 지원되기 때문에 string(path.u8string)으로 감싸주면 사용할 수 있다.
메인 에디터 사용 예제
상단 헤더 추가
#include "ImFileDialog.h"
예제코드
if (ImGui::Button("Open a texture"))
{
ifd::FileDialog::Instance().Open("TextureOpenDialog", "Open a texture", "Image file (*.png;*.jpg;*.jpeg;*.bmp;*.tga){.png,.jpg,.jpeg,.bmp,.tga},.*");
}
if (ImGui::Button("Save a texture"))
{
ifd::FileDialog::Instance().Save("TextureSaveDialog", "Open a texture", "Image file (*.png;*.jpg;*.jpeg;*.bmp;*.tga){.png,.jpg,.jpeg,.bmp,.tga},.*");
}
if (ifd::FileDialog::Instance().IsDone("TextureOpenDialog"))
{
if (ifd::FileDialog::Instance().HasResult())
{
std::wstring res = ifd::FileDialog::Instance().GetResult().wstring();
//파일을 선택하면 res에 파일 경로가 반환된다.
//해당 경로로 파일입력, 혹은 리소스 생성함수에 전달하면 된다.
}
ifd::FileDialog::Instance().Close();
}
if (ifd::FileDialog::Instance().IsDone("TextureSaveDialog"))
{
if (ifd::FileDialog::Instance().HasResult())
{
std::wstring res = ifd::FileDialog::Instance().GetResult().wstring();
//마찬가지
//printf("SAVE[%s]\n", res.c_str());//콘솔
//OutputDebugStringW(res.c_str());//스튜디오
//MessageBoxW(g_HWND,res.c_str(),"Notice",MB_OK);//윈도우
}
ifd::FileDialog::Instance().Close();
}