func main() { gtk.Init(&os.Args) window := gtk.Window(gtk.GTK_WINDOW_TOPLEVEL) window.SetTitle("GTK Table") window.Connect("destroy", gtk.MainQuit) swin := gtk.ScrolledWindow(nil, nil) swin.SetPolicy(gtk.GTK_POLICY_AUTOMATIC, gtk.GTK_POLICY_AUTOMATIC) table := gtk.Table(5, 5, false) for y := uint(0); y < 5; y++ { for x := uint(0); x < 5; x++ { table.Attach(gtk.ButtonWithLabel(fmt.Sprintf("%02d:%02d", x, y)), x, x+1, y, y+1, gtk.GTK_FILL, gtk.GTK_FILL, 5, 5) } } swin.AddWithViewPort(table) window.Add(swin) window.SetDefaultSize(200, 200) window.ShowAll() gtk.Main() }
func Init(size uint) { var ( files *gtk.GtkHBox examples_cnt int newfile_flag bool cs_desc_normal *_Ctype_char cs_desc_bold *_Ctype_char ) s = new(solver.Solver) s.Size = size if s.Size == 9 { cs_desc_normal = C.CString("Sans 14") cs_desc_bold = C.CString("Sans Bold 14") } else { cs_desc_normal = C.CString("Sans 16") cs_desc_bold = C.CString("Sans Bold 16") } desc_normal = C.pango_font_description_from_string(cs_desc_normal) desc_bold = C.pango_font_description_from_string(cs_desc_bold) C.free_string(cs_desc_normal) C.free_string(cs_desc_bold) gtk.Init(&os.Args) window := gtk.Window(gtk.GTK_WINDOW_TOPLEVEL) window.SetResizable(false) window.SetTitle("Sudoku solver") window.Connect("destroy", func() { gtk.MainQuit() }) window.Connect("key-press-event", func(ctx *glib.CallbackContext) { arg := ctx.Args(0) kev := *(**gdk.EventKey)(unsafe.Pointer(&arg)) r, st := rune(kev.Keyval), gdk.GdkModifierType(kev.State) if st&gdk.GDK_CONTROL_MASK != 0 { if r == 122 || r == 90 { // Ctrl-Z m := cs_pop() clear() for i := uint(0); i < s.Size; i++ { for j := uint(0); j < s.Size; j++ { v := int(m[i][j]) if v != 0 { entries[i][j].SetText(strconv.Itoa(v)) } } } } } }) vbox := gtk.VBox(false, 10) table := gtk.Table(3, s.Size/3, false) bg := [2]*gdk.GdkColor{gdk.Color("white"), gdk.Color("#e9f2ea")} for y := uint(0); y < 3; y++ { for x := uint(0); x < s.Size/3; x++ { subtable := gtk.Table(s.Size/3, 3, false) for sy := uint(0); sy < s.Size/3; sy++ { for sx := uint(0); sx < 3; sx++ { w := gtk.Entry() w.SetWidthChars(1) w.SetMaxLength(1) if s.Size == 9 { w.SetSizeRequest(23, 25) } else { w.SetSizeRequest(25, 27) } w.Connect("key-press-event", func(ctx *glib.CallbackContext) bool { data := ctx.Data().([]uint) y, x := data[0], data[1] arg := ctx.Args(0) kev := *(**gdk.EventKey)(unsafe.Pointer(&arg)) r := rune(kev.Keyval) switch r & 0xFF { case 81: if x != 0 || y != 0 { if x == 0 { x = s.Size - 1 y-- } else { x-- } } case 82: if y != 0 { y-- } case 83: if x != s.Size-1 || y != s.Size-1 { if x == s.Size-1 { x = 0 y++ } else { x++ } } case 84: if y != s.Size-1 { y++ } } if y != data[0] || x != data[1] { entries[y][x].GrabFocus() } if unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.Z}, r) { return true } return false }, []uint{(s.Size/3)*y + sy, 3*x + sx}) w.Connect("grab-focus", func(ctx *glib.CallbackContext) { data := ctx.Data().([]uint) y, x := data[0], data[1] for k := 0; k < 2; k++ { for i := uint(0); i < s.Size; i++ { modify_base(unsafe.Pointer(entries[i][prev_x].Widget), bg[k]) } for j := uint(0); j < s.Size; j++ { modify_base(unsafe.Pointer(entries[prev_y][j].Widget), bg[k]) } prev_y, prev_x = y, x } }, []uint{(s.Size/3)*y + sy, 3*x + sx}) subtable.Attach(w, sx, sx+1, sy, sy+1, gtk.GTK_FILL, gtk.GTK_FILL, 0, 0) entries[(s.Size/3)*y+sy][3*x+sx] = w modify_font((s.Size/3)*y+sy, 3*x+sx, desc_bold) } } table.Attach(subtable, x, x+1, y, y+1, gtk.GTK_FILL, gtk.GTK_FILL, 3, 3) } } solve_btn := gtk.ButtonWithLabel("Solve") solve_btn.Clicked(func() { var m1, m2 [9][9]uint for i := uint(0); i < s.Size; i++ { for j := uint(0); j < s.Size; j++ { v, _ := strconv.Atoi(entries[i][j].GetText()) m1[i][j] = uint(v) } } if !check_field(&m1) { return } cs_push(m1) s.Load(m1) s.Solve() if s.Finals != s.Size*s.Size { // let's try some tough algorithms :) s.ToughSolve() } for i := uint(0); i < s.Size; i++ { for j := uint(0); j < s.Size; j++ { v := int(s.Get(i, j)) m2[i][j] = uint(v) if v != 0 { entries[i][j].SetText(strconv.Itoa(v)) } else { var c_string [9]string // get list of candidates c_uint, l := s.GetCandidates(i, j) for k := uint(0); k < l; k++ { c_string[k] = strconv.Itoa(int(c_uint[k])) } // make a tooltip with them entries[i][j].SetTooltipText(strings.Join(c_string[:l], " ")) } } } // check for differences for i := uint(0); i < s.Size; i++ { for j := uint(0); j < s.Size; j++ { if m1[i][j] == m2[i][j] { modify_font(i, j, desc_bold) } else { modify_font(i, j, desc_normal) } } } }) clear_btn := gtk.ButtonWithLabel("Clear") clear_btn.Clicked(func() { m := [9][9]uint{} for i := uint(0); i < s.Size; i++ { for j := uint(0); j < s.Size; j++ { m[i][j] = s.Get(i, j) } } cs_push(m) clear() }) examples = gtk.ComboBoxText() // scan `examples` folder sz := strconv.Itoa(int(s.Size)) dir, err := os.Open("examples/" + sz + "x" + sz) if err == nil { names, err := dir.Readdirnames(0) if err == nil { for _, v := range names { examples.AppendText(v) examples_cnt++ } } dir.Close() } examples.Connect("changed", func() { sz := strconv.Itoa(int(s.Size)) load_sudoku("examples/" + sz + "x" + sz + "/" + examples.GetActiveText()) }) newfile := gtk.Entry() newfile.Connect("activate", func() { filename := newfile.GetText() if filename != "" { sz := strconv.Itoa(int(s.Size)) f, err := os.Create("examples/" + sz + "x" + sz + "/" + filename) if err == nil { for i := uint(0); i < s.Size; i++ { for j := uint(0); j < s.Size; j++ { v := []byte(entries[i][j].GetText()) if len(v) == 0 || v[0] < 49 || v[0] > byte(48+s.Size) { v = []byte{' '} } f.Write(v) if (j+1)%3 == 0 && j+1 != s.Size { f.WriteString("*") } } f.WriteString("\n") if (i+1)%(s.Size/3) == 0 && i+1 != s.Size { if s.Size == 9 { f.WriteString("***********\n") } else { f.WriteString("*******\n") } } } f.Close() } examples.AppendText(filename) examples.SetActive(examples_cnt) examples_cnt++ } files.ShowAll() newfile.SetText("") newfile.Hide() }) icon := gtk.Image() icon.SetFromStock(gtk.GTK_STOCK_SAVE_AS, gtk.GTK_ICON_SIZE_BUTTON) export := gtk.Button() export.SetImage(icon) export.Clicked(func() { if !newfile_flag { files.Add(newfile) newfile_flag = true } files.ShowAll() examples.Hide() export.Hide() newfile.GrabFocus() }) files = gtk.HBox(false, 0) files.Add(export) files.Add(examples) buttons := gtk.HBox(true, 5) buttons.Add(solve_btn) buttons.Add(clear_btn) vbox.Add(table) vbox.Add(files) vbox.Add(buttons) window.Add(vbox) window.ShowAll() }