업데이트된 패키지는 walkmgr, walkmgr_example 2개 입니다.
네이티브 GUI 프로그래밍을 하다 보면 .. 한 화면에 매우 많은 UI요소를 배치해야 하는 경우가 있습니다. 보통 일반 사용자용 프로그램을 만들때 보다는 내부에서 사용할 각종 툴(Tool)같은 것들을 만들때에는 사용성 보다는 기능에 집중하는 경우 같은..
내가 만들어서 나 혼자 쓰는 프로그램이 아니라면 사용자 컴퓨터의 해상도나 모니터 크기 등을 특정할 순 없다보니 일반적으로 최근에 FHD 모니터는 사용하는 편이라 생각 하고 최대 1920*1080 해상도에 맞춰 개발을 했더니 뜬금없이 HD 해상도의 사용자가 화면이 잘린다는 등의 ㅎㅎ
여튼! 그리하야 lxn/walk 에 존재하던 ScrollView를 walkmgr 체계(?)에 끌어다 넣고 관련 예제도 추가해서 Git에 Push 해 두었습니다.
간단한 설명도 남기기 위해 이 글을 작성 합니다.
walkmgr 패키지에 scrollview.go 파일이 추가 되었습니다. 열어보시면 추가된 메소드는 딱 하나입니다.
func (wm *WalkUI) ScrollView(hori bool, vert bool, lt ...LayoutType) *walk.ScrollView {
sv, _ := walk.NewScrollView(wm.Parent())
sv.SetScrollbars(hori, vert)
if len(lt) == 0 {
ly := walk.NewVBoxLayout()
ly.SetMargins(walk.Margins{0, 0, 0, 0})
sv.SetLayout(ly)
} else {
switch lt[0] {
case LAYOUT_VERT:
ly := walk.NewVBoxLayout()
ly.SetMargins(walk.Margins{0, 0, 0, 0})
sv.SetLayout(ly)
case LAYOUT_HORI:
ly := walk.NewHBoxLayout()
ly.SetMargins(walk.Margins{0, 0, 0, 0})
sv.SetLayout(ly)
case LAYOUT_FLOW:
ly := walk.NewFlowLayout()
ly.SetMargins(walk.Margins{0, 0, 0, 0})
sv.SetLayout(ly)
default:
ly := walk.NewVBoxLayout()
ly.SetMargins(walk.Margins{0, 0, 0, 0})
sv.SetLayout(ly)
}
}
wm.parentList.PushBack(sv)
return sv
}
스크롤뷰 자체도 내부적으로는 Composite 객체를 사용하고 있기 때문에 근본적으로 기존의 GroupBox 나 Composite 계열 walkmgr 메소드들과 마찮가지로 영역(?) 시작시에 ScrollView 함수를 호출하고 해당 객체에 포함시킬 UI객체들의 선언을 끝낸 경우 End() 메소드를 호출해서 마무리(?) 해주시면 되겠습니다.
인자는 3개로 hori, vert 는 어느 방향으로 스크롤을 시킬것이냐 일반적으로 상하 좌우 2가지 스크롤바를 프로그램들이 채용하고 있으니까 hori = horizontal, vert = vertical 이니 하단에 좌우로 스크롤되는 스크롤바를 사용 할거면 hori 를 true 로 아니면 false 를 전달하면 되겠습니다. 우측에 상하 스크롤을 사용하려면 vert 에 true 를 안할거면 false 를 지정하시면 되겠습니다.
마지막 lt 의 경우 이 스크롤 뷰 내부에 추가되는 UI 객체들을 어떤 기준으로 쌓을(?) 것이냐에 대한 것인데 이 부분은 GroupBox나 Composite 관련 글에서 사용중인 레이아웃 관련 값들을 그대로 사용 중입니다. 1일1고 카테고리의 다른 글들을 참고 하시면 되겠습니다.
func TestScrollView1(t *testing.T) {
//wm := NewWin("", 640, 480) default layout is vertical
wm := walkmgr.NewWin("스크롤뷰", 320, 320, walkmgr.LAYOUT_VERT)
wm.ScrollView(true, true)
wm.HGroupBox("그룹")
wm.PushButton("버튼1", func() {
})
wm.PushButton("버튼2", func() {
})
wm.PushButton("버튼3", func() {
})
wm.PushButton("버튼4", func() {
})
wm.PushButton("버튼5", func() {
})
wm.PushButton("버튼6", func() {
})
wm.PushButton("버튼7", func() {
})
wm.PushButton("버튼8", func() {
})
wm.PushButton("버튼9", func() {
})
wm.PushButton("버튼10", func() {
})
wm.End() // END of HGroupBox
wm.End()
wm.Start()
}
간단히 작성한 예제입니다.
320×320 짜리 창을 생성 하였고 버튼이 10개나 존재하는 수평방향으로 UI객체를 쌓아 넣는 GroupBox를 내부에 포함 시켰습니다. ScrollView 를 사용하지 않을 경우 실제 창 크기보다 창 내부의 UI객체들의 최소 넓이를 합한 것이 더 넓기 때문에 창 크기가 조정되서 320 보다 큰 창으로 만들어 지고 ..
창 크기가 고정이 아닌 최대화가 가능하거나 창 크기를 조정이 가능하거나 해버리면 .. 내부 UI요소들은 짤리거나 창 크기에 맞춰 너무 줄어들어서 클릭하기 힘든 형태가 될 수도 있습니다.



상단의 그림은 실행된 상태 320×320 사이즈의 초기 상태입니다. 내부 내용이 창 크기를 벗어나기 때문에 하단에 스크롤바가 생성 되었습니다. 스크롤을 사용하면 모든 UI요소를 볼 수 있습니다.
맨 하단의 그림은 스크롤 되지 않은 상태의 전체 크기입니다.
모든 스크롤바의 동작여부를 확인하기 위해 UI요소를 좀더 추가해 봅니다.
func TestScrollView2(t *testing.T) {
//wm := NewWin("", 640, 480) default layout is vertical
wm := walkmgr.NewWin("스크롤뷰", 200, 200, walkmgr.LAYOUT_VERT)
wm.ScrollView(true, true)
wm.HGroupBox("그룹")
wm.PushButton("버튼1", func() {
})
wm.PushButton("버튼2", func() {
})
wm.PushButton("버튼3", func() {
})
wm.PushButton("버튼4", func() {
})
wm.PushButton("버튼5", func() {
})
wm.PushButton("버튼6", func() {
})
wm.PushButton("버튼7", func() {
})
wm.PushButton("버튼8", func() {
})
wm.PushButton("버튼9", func() {
})
wm.PushButton("버튼10", func() {
})
wm.End() // END of HGroupBox
wm.HGroupBox("그룹")
wm.PushButton("버튼1", func() {
})
wm.PushButton("버튼2", func() {
})
wm.PushButton("버튼3", func() {
})
wm.PushButton("버튼4", func() {
})
wm.PushButton("버튼5", func() {
})
wm.PushButton("버튼6", func() {
})
wm.PushButton("버튼7", func() {
})
wm.PushButton("버튼8", func() {
})
wm.PushButton("버튼9", func() {
})
wm.PushButton("버튼10", func() {
})
wm.End() // END of HGroupBox
wm.HGroupBox("그룹")
wm.PushButton("버튼1", func() {
})
wm.PushButton("버튼2", func() {
})
wm.PushButton("버튼3", func() {
})
wm.PushButton("버튼4", func() {
})
wm.PushButton("버튼5", func() {
})
wm.PushButton("버튼6", func() {
})
wm.PushButton("버튼7", func() {
})
wm.PushButton("버튼8", func() {
})
wm.PushButton("버튼9", func() {
})
wm.PushButton("버튼10", func() {
})
wm.End() // END of HGroupBox
wm.HGroupBox("그룹")
wm.PushButton("버튼1", func() {
})
wm.PushButton("버튼2", func() {
})
wm.PushButton("버튼3", func() {
})
wm.PushButton("버튼4", func() {
})
wm.PushButton("버튼5", func() {
})
wm.PushButton("버튼6", func() {
})
wm.PushButton("버튼7", func() {
})
wm.PushButton("버튼8", func() {
})
wm.PushButton("버튼9", func() {
})
wm.PushButton("버튼10", func() {
})
wm.End() // END of HGroupBox
wm.End()
wm.Start()
}




200×200 사이즈 창에 10개의 버튼이 포함된 GroupBox를 4개를 아래로 쌓았으니 상하 좌우 방향의 스크롤바가 모두 생성된 것을 확인 가능 합니다.
이렇게 단일 창에 UI요소가 매우 많이 존재할 경우에도 스크롤 바를 통해서 모든 요소를 문제 없이 볼 수 있도록 구성 가능합니다.
MFC에서 FormView 랑 비슷한 느낌으로 사용하시면 되겠습니다.
이상입니다.