Ring 1.5 での変更点は?

Ring 1.5 公開版の新機能と変更点を学びます。

新機能と変更一覧

Ring 1.5 の新機能!

  • Video-Music-Player アプリケーション
  • Windows StartUp Manager アプリケーション
  • Calculator アプリケーション
  • Ring ノートパッドの改善
  • StdLib の改善
  • WebLib の改善
  • RingQt の改善
  • オブジェクトライブラリの改善
  • RingFreeGLUT 拡張機能
  • RingOpenGL 拡張機能
  • 拡張機能用のコード生成器の改善
  • 拡張機能用のドキュメント生成器の改善
  • Ring 仮想計算機 - トレース関数
  • トレースライブラリとインタラクティブデバッガ
  • より柔軟性のあるシンタックス
  • 型ヒントライブラリ
  • 品質の改善

Video-Music-Player アプリケーション

Video-Music-Player アプリケーションを Applications フォルダへ追加しました。

スクリーンショット:

Video Music Player

Windows StartUp Manager アプリケーション

Windows StartUp Manager アプリケーション

URL : https://github.com/ring-lang/WinStartupManager

スクリーンショット:

Windows Startup Manager

Calculator アプリケーション

Calculator アプリケーションを Applications フォルダへ追加しました。

スクリーンショット:

Calculator アプリケーション

Ring ノートパッドの改善

① Ring ノートパッドは新しいスタイル、およびメインファイルツールバーを搭載するために更新しました。

メインファイルツールバーの考えは、プロジェクトに複数のソースコードのファイルがある場合に プロジェクトのメインファイルを決定することです。

この機能を使用するとプロジェクトでほかのファイルを開いているときに、 プロジェクトを実行するためにメインファイルを切り替えることなくプロジェクト (メインファイル) を実行できます。

この機能を使用するには、プロジェクトのメインファイルを開きます。

現在のソースコードファイルをメインファイルとして設定するには Ctrl+Shift+M を押してください。

プロジェクトで別のソースコードファイルを開いて修正します。

プロジェクト (メインファイル) を実行したいときは Ctrl+Shift+F5 (GUI) または Ctrl+Shift+D (コンソール) を押してください。

スクリーンショット:

Ring Notepad Ring Notepad Ring Notepad

② 改行の正確な表示、および “Clear” ボタンを実装するために実行結果ウィンドウを更新しました。

スクリーンショット:

実行結果ウィンドウ

③ バックグラウンド処理で関数、クラスのリストを準備している間に、 大規模ファイルをすばやく開いて切り替えることができるようにするために Ring ノートパッドを更新しました。

スクリーンショット:

Ring ノートパッド - 大規模ファイル

StdLib の改善

新しい関数

  • Print2Str()
  • ListAllFiles()
  • SystemCmd()

① 新しい関数 Print2Str() を StdLib へ追加しました。

用例:

load "stdlib.ring"

world = "World!"
mystring = print2str("Hello, #{world} \nIn Year \n#{2000+17} \n")

see mystring + nl

実行結果:

Hello, World!
In Year
2017

② 新しい関数 ListAllFiles() を StdLib へ追加しました。

この関数を使用するとフォルダにあるファイルのグループ、およびそのサブフォルダを手軽に処理できます。

用例:

load "stdlib.ring"
aList = ListAllFiles("c:/ring/ringlibs","ring") # *.ring のみ
aList = sort(aList)
see aList

用例:

load "stdlib.ring"
see listallfiles("b:/ring/ringlibs/weblib","") # 全ファイル

③ 新しい関数 SystemCmd() を StdLib へ追加しました。

この関数は System() 関数と同じくシステムコマンドを実行できますが、 実行結果は文字列で返されます。

用例:

cYou = SystemCmd("whoami")
See "SystemCmd: whoami ====="+ nl + cYou +nl

実行結果:

SystemCmd: whoami =====
desktop-umberto\umberto

WebLib の改善

HTMLPage クラスを搭載するために WebLib を更新しました。

このクラスを使用すると標準出力へ出力を行わずに HTML ドキュメントを作成できます。

ウェブアプリケーションだけで WebLib を使用するときの代用になります。

また、コンソール、 GUI、モバイル用のアプリケーションでも使用できます。

用例:

load "stdlib.ring"
load "weblib.ring"

import System.Web

func main

        mypage = new HtmlPage {
                h1 { text("Customers Report") }
                Table
                {
                          style = stylewidth("100%") + stylegradient(4)
                          TR
                          {
                                TD { WIDTH="10%" text("Customers Count : " )  }
                                TD { text (100) }
                          }
                }

                Table
                {
                          style = stylewidth("100%") + stylegradient(26)
                          TR
                          {
                                style = stylewidth("100%") + stylegradient(24)
                                TD { text("Name " )  }
                                TD { text("Age" ) }
                                TD { text("Country" ) }
                                TD { text("Job" ) }
                                TD { text("Company" ) }
                          }
                          for x =  1 to 100
                                TR
                                {
                                        TD { text("Test" )  }
                                        TD { text("30" ) }
                                        TD { text("Egypt" ) }
                                        TD { text("Sales" ) }
                                        TD { text("Future" ) }
                                }
                          next
                }

        }

        write("report.html",mypage.output())

このクラスにより WebLib と GUILib を使用して手軽にレポートを作成できます。

用例:

load "stdlib.ring"
load "weblib.ring"
load "guilib.ring"

import System.Web
import System.GUI

new qApp {
        open_window(:CustomersReportController)
        exec()
}

class CustomersReportController

        oView = new CustomersReportView

        func Start
                CreateReport()

        func CreateReport
                mypage = new HtmlPage {
                        h1 { text("Customers Report") }
                        Table
                        {
                                style = stylewidth("100%") + stylegradient(4)
                                TR
                                {
                                        TD { WIDTH="10%"
                                                text("Customers Count : " )  }
                                        TD { text (100) }
                                }
                        }
                        Table
                        {
                                style = stylewidth("100%") + stylegradient(26)
                                TR
                                {
                                        style = stylewidth("100%") +
                                                stylegradient(24)
                                        TD { text("Name " )  }
                                        TD { text("Age" ) }
                                        TD { text("Country" ) }
                                        TD { text("Job" ) }
                                        TD { text("Company" ) }
                                }
                                for x =  1 to 100
                                        TR
                                        {
                                                TD { text("Test" )  }
                                                TD { text("30" ) }
                                                TD { text("Egypt" ) }
                                                TD { text("Sales" ) }
                                                TD { text("Future" ) }
                                        }
                                next
                        }
                }
                write("report.html",mypage.output())

        func PrintEvent
                printer1 = new qPrinter(0) {
                        setoutputformat(1)
                        setoutputfilename("report.pdf")
                }
                oView {
                        web.print(printer1)
                        web.show()
                }
                system ("report.pdf")

class CustomersReportView

                win = new window() {
                                setwindowtitle("Report Window")
                                setgeometry(100,100,500,500)
                                web = new webview(win) {
                                        setgeometry(100,100,1000,500)
                                        loadpage(new qurl("file:///"+
                                        currentdir()+"/report.html"))
                                }
                                new pushbutton(win) {
                                                setGeometry(100,20,100,30)
                                                settext("Print")
                                                setclickevent(Method(:PrintEvent))
                                }
                                showMaximized()
                        }

スクリーンショット:

顧客報告書

RingQt の改善

新しいクラスを RingQt へ追加しました:

  • QStringRef
  • QMutex
  • QMutexLocker
  • QBuffer
  • QBluetoothAddress
  • QBluetoothDeviceDiscoveryAgent
  • QBluetoothDeviceInfo
  • QBluetoothHostInfo
  • QBluetoothLocalDevice
  • QBluetoothServer
  • QBluetoothServiceDiscoveryAgent
  • QBluetoothServiceInfo
  • QBluetoothSocket
  • QBluetoothTransferManager
  • QBluetoothTransferReply
  • QBluetoothTransferRequest
  • QBluetoothUuid

用例:

### ウェブサイト - vpic.nhtsa.dot.gov - へ VIN (Vehicle Id Number : 車両識別番号) を提出します。
### 返された XML データを解析します。
### 車両情報の結果を表示します

load "libcurl.ring"
load "guilib.ring"
load "stdlib.ring"

curl = curl_easy_init()

# request = "3G1JC5248YS251015?format=xml"  ### VIN - シボレー
  request = "3GYFK62847G247323?format=xml"  ### VIN - キャデラック

call_type   = "decodevinvalues/"
url         = "https://vpic.nhtsa.dot.gov/api/vehicles/"
url_request = url + call_type + request

        See "URL Request: "+ url_request +nl

curl_easy_setopt(curl, curlopt_url, url_request)
response = curl_easy_perform_silent(curl);

        See nl +"Response Raw: "+ response +nl +nl

curl_easy_cleanup(curl)

xml = new qxmlstreamreader()
xml.adddata_2(response)

x = new qstringref()
while not xml.atend()
           if xml.error()
                           see xml.errorstring() see nl
                           exit loop
           ok

           x = xml.text()
           if not x.length() = 0
                           see "Length: " see x.length() +" --- "
                           see "Value: " see x.tostring() see nl
           ok

           xml.readnext()
end

get x

###------------------------------------------
### 実行結果:
#
# ==>Value: 115
# ==>Value: Results returned successfully
# ==>Value: VIN(s): 3G1JC5248YS251015
# ==>Value: 3G1JC5248YS251015
# ==>Value: Sedan/Saloon
# ==>Value: 4
# ==>Value: 2200.0
# ==>Value: 134.25223700841
# ==>Value: 2.2
# ==>Value: 4
# ==>Value: LN2
# ==>Value: CHEVROLET
# ==>Value: GENERAL MOTORS LLC
# ==>Value: Cavalier
# ==>Value: 2000
# ==>Value: Ramos Arzipe
# ==>Value: PASSENGER CAR
# ==>Value: 4
# ==>Value: In-Line
# ==>Value: 1st Row (Driver & Passenger)
# ==>Value: Sequential Fuel Injection (SFI)
# ==>Value: Mexico
# ==>Value: NA
# ==>Value: Manual
# ==>Value: Body Type: Sedan, 4-6 Window, Notchback (GM codes: 19, 69)
# ==>Value:  Name Plate: Chevrolet, Pontiac
# ==>Value: 0 - VIN decoded clean. Check Digit (9th position) is correct
# ==>Value: LAN
# ==>Value: 984
#
###-----------------------------------------

オブジェクトライブラリの改善

オブジェクトライブラリに Open_WindowInPackages() 関数を追加しました。

Open_WindowInPackages() 関数は Open_Window() と同じですが、 ウィンドウを開く前にインポートを行うパッケージの 追加リストを決定します。

文法:

Open_WindowInPackages(cClassName,aPackagesList)

用例:

この用例はフォームデザイナーのソースコードから引用したものです。 open_windowInPackages() 関数でウィンドウフラグのウィンドウを開きます。

クラス名 “WindowFlagsController” とパッケージ名を決定します。

ウィンドウフラグのウィンドウでは FormDesigner および System.GUI パッケージを使用しています。

open_windowInPackages(:WindowFlagsController,[
        "formdesigner",
        "System.GUI"
])

RingFreeGLUT 拡張機能

Ring 1.5 には FreeGLUT ライブラリへ対応するために RingFreeGLUT 拡張機能があります。

用例:

/*
        このサンプルは C チュートリアルを元にしています。
        出典元 : http://www.lighthouse3d.com/tutorials/glut-tutorial/
*/

load "freeglut.ring"
load "opengl21lib.ring"


// カメラ方向に対する回転角度
angle = 0.0

// 実際のベクトルはカメラ方向を表しています。
lx=0.0 lz=-1.0

// カメラの XZ 位置
x=0.0  z=5.0

// キーの状態
// キーを押していない時の変数は 0 です。
deltaAngle = 0.0
deltaMove = 0
xOrigin = -1

// メニューを定義するための定数
C_RED  = 1
C_GREEN = 2
C_BLUE = 3
C_ORANGE = 4

C_FILL = 5
C_LINE = 6

// ポップアップメニューの定義
fillMenu=NULL
fontMenu=NULL
mainMenu=NULL
colorMenu=NULL

// 鼻の配色
red = 1.0
blue=0.5
green=0.5

// 雪だるまの大きさ
scale = 1.0

// メニューの状態
menuFlag = 0

// デフォルトのフォント
font = GLUT_BITMAP_TIMES_ROMAN_24

C_INT_GLUT_BITMAP_8_BY_13 = 7
C_INT_GLUT_BITMAP_9_BY_15 = 8
C_INT_GLUT_BITMAP_TIMES_ROMAN_10  = 9
C_INT_GLUT_BITMAP_TIMES_ROMAN_24  = 10
C_INT_GLUT_BITMAP_HELVETICA_10  = 11
C_INT_GLUT_BITMAP_HELVETICA_12  = 12
C_INT_GLUT_BITMAP_HELVETICA_18  = 13

// ウィンドウの幅と高さ
h = 0
w = 0

// 一秒あたりのフレーム数を計算するための変数
frame=0
time=0
timebase=0
s = ""

func changeSize
        w = glutEventWidth()
        h = glutEventHeight()

        // ウィンドウの大きさが小さすぎる場合に、ゼロ除算エラーになるのを防ぎます。
        // (幅 0 のウィンドウは作成できません)
        if h = 0
                h = 1
        ok

        ratio =  w * 1.0 / h

        // 投射行列の使用
        glMatrixMode(GL_PROJECTION)

        // 行列のリセット
        glLoadIdentity()

        // ウィンドウ全体のビューポートを設定します。
        glViewport(0, 0, w, h)

        // 正しい遠近法の設定。
        gluPerspective(45.0, ratio, 0.1, 100.0)

        // Modelview の復帰
        glMatrixMode(GL_MODELVIEW)

func drawSnowMan

        glScalef(scale, scale, scale)
        glColor3f(1.0, 1.0, 1.0)

// 体の描画
        glTranslatef(0.0 ,0.75, 0.0)
        glutSolidSphere(0.75,20,20)

// 頭の描画
        glTranslatef(0.0, 1.0, 0.0)
        glutSolidSphere(0.25,20,20)

// 目の描画
        glPushMatrix()
        glColor3f(0.0,0.0,0.0)
        glTranslatef(0.05, 0.10, 0.18)
        glutSolidSphere(0.05,10,10)
        glTranslatef(-0.1, 0.0, 0.0)
        glutSolidSphere(0.05,10,10)
        glPopMatrix()

// 鼻の描画
        glColor3f(red, green, blue)
        glRotatef(0.0,1.0, 0.0, 0.0)
        glutSolidCone(0.08,0.5,10,2)

        glColor3f(1.0, 1.0, 1.0)

func renderBitmapString x,y,z,font,string
        glRasterPos3f(x, y,z)
        for c in string
                glutBitmapCharacter(font,ascii(c))
        next

func renderStrokeFontString x,y,z,font,string
        glPushMatrix()
        glTranslatef(x, y,z)
        glScalef(0.002, 0.002, 0.002)
        for c in string
                glutStrokeCharacter(font, Ascii(c));
        next
        glPopMatrix()


func restorePerspectiveProjection

        glMatrixMode(GL_PROJECTION)
        // 以前の投射行列へ復帰
        glPopMatrix()

        // modelview モードへ復帰
        glMatrixMode(GL_MODELVIEW)


func setOrthographicProjection

        // 投射モードの切り替え
        glMatrixMode(GL_PROJECTION)

        // 透視図に対する設定を有する
        // 以前の行列を保存します。
        glPushMatrix()

        // 行列のリセット
        glLoadIdentity()

        // 2D 正投射の設定
        gluOrtho2D(0, w, h, 0)

        // modelview モードへ復帰切り替え
        glMatrixMode(GL_MODELVIEW)



func computePos deltaMove

        x += deltaMove * lx * 0.1
        z += deltaMove * lz * 0.1


func renderScene

        if  deltaMove
                computePos(deltaMove)
        ok

        // 配色と深度バッファの消去
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        // 変換のリセット
        glLoadIdentity()

        // カメラの設定
        gluLookAt(      x, 1.0, z,
                        x+lx, 1.0,  z+lz,
                        0.0, 1.0,  0.0)

        // 地面の描画

        glColor3f(0.9, 0.9, 0.9)
        glBegin(GL_QUADS)
                glVertex3f(-100.0, 0.0, -100.0)
                glVertex3f(-100.0, 0.0,  100.0)
                glVertex3f( 100.0, 0.0,  100.0)
                glVertex3f( 100.0, 0.0, -100.0)
        glEnd()

// 9 体の雪だるまを描画
        for i = -3 to -1
                for j = -3 to -1
                        glPushMatrix()
                        glTranslatef(i*10.0, 0.0, j * 10.0)
                        drawSnowMan()
                        number = (i+3)*3+(j+3)
                        renderBitmapString(0.0, 0.5, 0.0,font ,""+number)
                        glPopMatrix()
                next
        next

        // 一秒あたりのフレーム数を計算するためのコード
        frame++

        time=glutGet(GLUT_ELAPSED_TIME)
        if time - timebase > 1000
                s = "RingFreeGLUT - FPS: " + (frame*1000.0/(time-timebase))
                timebase = time
                frame = 0
        ok

        // ビットマップフォントで文字列 (fps) を表示するためのコード
        setOrthographicProjection()

        glPushMatrix()
        glLoadIdentity()
        renderBitmapString(5,30,0,GLUT_BITMAP_HELVETICA_18,s)
        glPopMatrix()

        restorePerspectiveProjection()

        glutSwapBuffers()


// -----------------------------------
//             キーボード
// -----------------------------------

func processNormalKeys
        key = glutEventKey()
        xx = glutEventX()
        yy = glutEventY()

        switch key
                on 27
                        glutDestroyMenu(mainMenu)
                        glutDestroyMenu(fillMenu)
                        glutDestroyMenu(colorMenu)
                        glutDestroyMenu(fontMenu)
                        Shutdown()
        off


func pressKey

        key = glutEventKey()
        xx = glutEventX()
        yy = glutEventY()

        switch key
                on GLUT_KEY_UP
                         deltaMove = 0.5
                on GLUT_KEY_DOWN
                        deltaMove = -0.5
        off


func releaseKey

        key = glutEventKey()

        switch key
                on GLUT_KEY_UP
                        deltaMove = 0
                on GLUT_KEY_DOWN
                        deltaMove = 0
        off


// -----------------------------------
//             マウス
// -----------------------------------

func mouseMove
        xx = glutEventX()
        yy = glutEventY()

        // これは左ボタンを押したときのみ true になります。
        if xOrigin >= 0

                // deltaAngle の更新
                deltaAngle = (xx - xOrigin) * 0.001

                // カメラの方向を更新
                lx = sin(angle + deltaAngle)
                lz = -cos(angle + deltaAngle)
        ok


func mouseButton

        button = glutEventButton()
        state = glutEventState()
        xx = glutEventX()
        yy = glutEventY()

        // これは左ボタンを押したときのみ true になります。
        if button = GLUT_LEFT_BUTTON
                // ボタンを離したとき
                if state = GLUT_UP
                        angle += deltaAngle
                        xOrigin = -1
                else
                        // state = GLUT_DOWN
                        xOrigin = xx
                ok
        ok


// -----------------------------------
//             メニュー
// -----------------------------------

func processMenuStatus

        status = glutEventStatus()

        if status = GLUT_MENU_IN_USE
                menuFlag = 1
        else
                menuFlag = 0
        ok


func processMainMenu

        // ここにはなにもありません。
        // 動作は全てサブメニューから行います。


func processFillMenu

        option = glutEventValue()

        switch option

                on C_FILL
                        glPolygonMode(GL_FRONT, GL_FILL)
                on C_LINE
                         glPolygonMode(GL_FRONT, GL_LINE)
        off


func processFontMenu

        option = glutEventValue()

        switch (option) {
                on C_INT_GLUT_BITMAP_8_BY_13
                        font = GLUT_BITMAP_8_BY_13
                on C_INT_GLUT_BITMAP_9_BY_15
                        font = GLUT_BITMAP_9_BY_15
                on C_INT_GLUT_BITMAP_TIMES_ROMAN_10
                        font = GLUT_BITMAP_TIMES_ROMAN_10
                on C_INT_GLUT_BITMAP_TIMES_ROMAN_24
                        font = GLUT_BITMAP_TIMES_ROMAN_24
                on C_INT_GLUT_BITMAP_HELVETICA_10
                        font = GLUT_BITMAP_HELVETICA_10
                on C_INT_GLUT_BITMAP_HELVETICA_12
                        font = GLUT_BITMAP_HELVETICA_12
                on C_INT_GLUT_BITMAP_HELVETICA_18
                        font = GLUT_BITMAP_HELVETICA_18
        off

func processColorMenu

        option = glutEventValue()

        switch option
                on C_RED
                        red = 1.0
                        green = 0.0
                        blue = 0.0
                on C_GREEN
                        red = 0.0
                        green = 1.0
                        blue = 0.0
                on C_BLUE
                        red = 0.0
                        green = 0.0
                        blue = 1.0
                on C_ORANGE
                        red = 1.0
                        green = 0.5
                        blue = 0.5
        off


func createPopupMenus

        fontMenu = glutCreateMenu(:processFontMenu)

        glutAddMenuEntry("BITMAP_8_BY_13 ",C_INT_GLUT_BITMAP_8_BY_13 )
        glutAddMenuEntry("BITMAP_9_BY_15",C_INT_GLUT_BITMAP_9_BY_15 )
        glutAddMenuEntry("BITMAP_TIMES_ROMAN_10 ",C_INT_GLUT_BITMAP_TIMES_ROMAN_10  )
        glutAddMenuEntry("BITMAP_TIMES_ROMAN_24",C_INT_GLUT_BITMAP_TIMES_ROMAN_24  )
        glutAddMenuEntry("BITMAP_HELVETICA_10 ",C_INT_GLUT_BITMAP_HELVETICA_10  )
        glutAddMenuEntry("BITMAP_HELVETICA_12",C_INT_GLUT_BITMAP_HELVETICA_12  )
        glutAddMenuEntry("BITMAP_HELVETICA_18",C_INT_GLUT_BITMAP_HELVETICA_18  )

        fillMenu = glutCreateMenu(:processFillMenu)

        glutAddMenuEntry("Fill",C_FILL)
        glutAddMenuEntry("Line",C_LINE)

        colorMenu = glutCreateMenu(:processColorMenu)
        glutAddMenuEntry("Red",C_RED);
        glutAddMenuEntry("Blue",C_BLUE);
        glutAddMenuEntry("Green",C_GREEN);
        glutAddMenuEntry("Orange",C_ORANGE);

        mainMenu = glutCreateMenu(:processMainMenu)

        glutAddSubMenu("Polygon Mode", fillMenu)
        glutAddSubMenu("Color", colorMenu)
        glutAddSubMenu("Font",fontMenu)
         // 右ボタンでメニューへ接続
        glutAttachMenu(GLUT_RIGHT_BUTTON)

        // これでアクティブなメニューであるかどうか検知できるようにします。
        glutMenuStatusFunc(:processMenuStatus)


// -----------------------------------
//             メイン
// -----------------------------------

func main

        // GLUT の初期化とウィンドウの作成
        glutInit()
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA)
        glutInitWindowPosition(100,100)
        glutInitWindowSize(320,320)
        glutCreateWindow("RingFreeGLUT - Test - 9 SnowMan")

        // コールバックの登録
        glutDisplayFunc(:renderScene)
        glutReshapeFunc(:changeSize)
        glutIdleFunc(:renderScene)

        glutIgnoreKeyRepeat(1)
        glutKeyboardFunc(:processNormalKeys)
        glutSpecialFunc(:pressKey)
        glutSpecialUpFunc(:releaseKey)

         // ここには二つの新しい関数があります。
        glutMouseFunc(:mouseButton)
        glutMotionFunc(:mouseMove)

        // OpenGL の初期化
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_CULL_FACE)

        // メニューの初期化
        createPopupMenus()

        // GLUT のイベント処理サイクルへ入ります。
        glutMainLoop()

スクリーンショット:

RingFreeGLUT RingFreeGLUT

RingOpenGL 拡張機能

Ring 1.5 の RingOpenGL は下記のバージョンに対応しています。

  • OpenGL 1.1
  • OpenGL 1.2
  • OpenGL 1.3
  • OpenGL 1.4
  • OpenGL 1.5
  • OpenGL 2.0
  • OpenGL 2.1
  • OpenGL 3.0
  • OpenGL 3.2
  • OpenGL 3.3
  • OpenGL 4.0
  • OpenGL 4.1
  • OpenGL 4.2
  • OpenGL 4.3
  • OpenGL 4.4
  • OpenGL 4.5
  • OpenGL 4.6

用例:

/*
        このサンプルは C チュートリアルを元にしています。
        出典元 :
                http://www.wikihow.com/Make-a-Cube-in-OpenGL
*/

load "freeglut.ring"
load "opengl21lib.ring"

// ----------------------------------------------------------
// グローバル変数
// ----------------------------------------------------------
rotate_y=0
rotate_x=0

// ----------------------------------------------------------
// display() コールバック関数
// ----------------------------------------------------------
func display

  //  画面と Z バッファの消去
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

  // 変換のリセット
  glLoadIdentity()

  // rotate_x および rotate_y のユーザによる変更をリセットします。
  glRotatef( rotate_x, 1.0, 0.0, 0.0 )
  glRotatef( rotate_y, 0.0, 1.0, 0.0 )

  // 多色面 - 前
  glBegin(GL_POLYGON)

  glColor3f( 1.0, 0.0, 0.0 )     glVertex3f(  0.5, -0.5, -0.5 )      # P1 は赤
  glColor3f( 0.0, 1.0, 0.0 )     glVertex3f(  0.5,  0.5, -0.5 )      # P2 は緑
  glColor3f( 0.0, 0.0, 1.0 )     glVertex3f( -0.5,  0.5, -0.5 )      # P3 は青
  glColor3f( 1.0, 0.0, 1.0 )     glVertex3f( -0.5, -0.5, -0.5 )      # P4 は紫

  glEnd()

  // 白面 - 後
  glBegin(GL_POLYGON)
  glColor3f(   1.0,  1.0, 1.0 )
  glVertex3f(  0.5, -0.5, 0.5 )
  glVertex3f(  0.5,  0.5, 0.5 )
  glVertex3f( -0.5,  0.5, 0.5 )
  glVertex3f( -0.5, -0.5, 0.5 )
  glEnd()

  // 紫面 - 右
  glBegin(GL_POLYGON)
  glColor3f(  1.0,  0.0,  1.0 )
  glVertex3f( 0.5, -0.5, -0.5 )
  glVertex3f( 0.5,  0.5, -0.5 )
  glVertex3f( 0.5,  0.5,  0.5 )
  glVertex3f( 0.5, -0.5,  0.5 )
  glEnd()

  // 緑面 - 左
  glBegin(GL_POLYGON)
  glColor3f(   0.0,  1.0,  0.0 )
  glVertex3f( -0.5, -0.5,  0.5 )
  glVertex3f( -0.5,  0.5,  0.5 )
  glVertex3f( -0.5,  0.5, -0.5 )
  glVertex3f( -0.5, -0.5, -0.5 )
  glEnd()

  // 青面 - 上
  glBegin(GL_POLYGON)
  glColor3f(   0.0,  0.0,  1.0 )
  glVertex3f(  0.5,  0.5,  0.5 )
  glVertex3f(  0.5,  0.5, -0.5 )
  glVertex3f( -0.5,  0.5, -0.5 )
  glVertex3f( -0.5,  0.5,  0.5 )
  glEnd()

  // 赤面 - 下
  glBegin(GL_POLYGON)
  glColor3f(   1.0,  0.0,  0.0 )
  glVertex3f(  0.5, -0.5, -0.5 )
  glVertex3f(  0.5, -0.5,  0.5 )
  glVertex3f( -0.5, -0.5,  0.5 )
  glVertex3f( -0.5, -0.5, -0.5 )
  glEnd()

  glFlush()
  glutSwapBuffers()


// ----------------------------------------------------------
// specialKeys() コールバック関数
// ----------------------------------------------------------
func specialKeys

        key = glutEventKey()

  //  右矢印 - 回転を五度増分します。
        switch Key

        on GLUT_KEY_RIGHT
                rotate_y += 5

        //  左矢印 - 回転を五度減分します。
        on GLUT_KEY_LEFT
                rotate_y -= 5

        on GLUT_KEY_UP
                rotate_x += 5

        on GLUT_KEY_DOWN
                rotate_x -= 5

        off

  //  更新の要求
  glutPostRedisplay()



// ----------------------------------------------------------
// main() 関数
// ----------------------------------------------------------
func main

  //  GLUT の初期化とユーザ仮引数の処理
  glutInit()

  //  トゥルーカラーのウィンドウのためにZ-バッファによるダブルバッファを要求します。
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)

  // ウィンドウの作成
  glutCreateWindow("Awesome Cube")

  //  Z-バッファの深度テストを有効にします。
  glEnable(GL_DEPTH_TEST)

  // コールバック関数
  glutDisplayFunc(:display)
  glutSpecialFunc(:specialKeys)

  // GLUT へイベントの制御を渡します。
  glutMainLoop()

  // OS へ戻ります。

スクリーンショット:

RingOpenGL

拡張機能用のコード生成器の改善

<constant> 型へ対応しました。 また、数値以外にも定数を扱うことができます。例えば: 文字列とポインタです。

ポインタのときはポインタ型を決定できます。 この機能は <constant> ~ </constant> の前に使用できます。

$nDefaultConstantType = C_CONSTANT_TYPE_POINTER
$cDefaultConstantPointerType = "void *"

この用例は RingFreeGLUT 拡張機能からの引用です。

<runcode>
        $nDefaultConstantType = C_CONSTANT_TYPE_POINTER
        $cDefaultConstantPointerType = "void"
</runcode>
<constant>
        GLUT_STROKE_ROMAN
        GLUT_STROKE_MONO_ROMAN
        GLUT_BITMAP_9_BY_15
        GLUT_BITMAP_8_BY_13
        GLUT_BITMAP_TIMES_ROMAN_10
        GLUT_BITMAP_TIMES_ROMAN_24
        GLUT_BITMAP_HELVETICA_10
        GLUT_BITMAP_HELVETICA_12
        GLUT_BITMAP_HELVETICA_18
</constant>

拡張機能用のドキュメント生成器の改善

生成した定数のリストをドキュメントへ出力できるようになりました。

以前の公開版では関数プロトタイプのみありましたが、 今回は定数のリストもあります。

Ring VM - トレース関数

Ring 1.5 では、このような関数を Ring VM へ追加しました。

  • RingVM_SetTrace(cCode)
  • RingVM_TraceData() –> aDataList
  • RingVM_TraceEvent() –> nTraceEvent
  • RingVM_TraceFunc() –> cCode
  • RingVM_ScopesCount() –> nScopes
  • RingVM_EvalInScope(nScope,cCode)
  • RingVM_PassError()
  • RingVM_HideErrorMsg(lStatus)
  • RingVM_CallFunc(cFuncName)

用例:

load "tracelib.ring"

ringvm_settrace("mytrace()")

see "Hello, world!" + nl
see "Welcome" + nl
see "How are you?" +nl
mytest()
new myclass { mymethod() }

func mytest
        see "Message from mytest" + nl

func mytrace
        see "====== The Trace function is Active ======" + nl +
                "Trace Function Name : " + ringvm_TraceFunc() + nl +
                "Trace Event : "
        switch ringvm_TraceEvent()
                on TRACEEVENT_NEWLINE           see "New Line"
                on TRACEEVENT_NEWFUNC           see "New Function"
                on TRACEEVENT_RETURN            see "Return"
                on TRACEEVENT_ERROR             see "Error"
                on TRACEEVENT_BEFORECFUNC       see "Before C Function"
                on TRACEEVENT_AFTERCFUNC        see "After C Function"
        off
        see nl +
                "Line Number : " + ringvm_tracedata()[TRACEDATA_LINENUMBER] + nl +
                "File Name   : " + ringvm_tracedata()[TRACEDATA_FILENAME] + nl +
                "Function Name : " + ringvm_tracedata()[TRACEDATA_FUNCNAME] + nl +
                "Method or Function : "
                if ringvm_tracedata()[TRACEDATA_METHODORFUNC] =
                                 TRACEDATA_METHODORFUNC_METHOD
                        see "Method"
                else
                        if ringvm_tracedata()[TRACEDATA_FUNCNAME] = NULL
                                see "Command"
                        else
                                see "Function"
                        ok
                ok
                see nl + Copy("=",42) + nl

class myclass
        func mymethod
                see "Message from mymethod" + nl

実行結果:

====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 3
File Name   : test1.ring
Function Name : ringvm_settrace
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 5
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
Hello, world!
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 6
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
Welcome
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 7
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
How are you?
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 8
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Function
Line Number : 8
File Name   : test1.ring
Function Name : mytest
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 12
File Name   : test1.ring
Function Name : mytest
Method or Function : Function
==========================================
Message from mytest
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 14
File Name   : test1.ring
Function Name : mytest
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Return
Line Number : 8
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 9
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 43
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Before C Function
Line Number : 9
File Name   : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 9
File Name   : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Function
Line Number : 9
File Name   : test1.ring
Function Name : mymethod
Method or Function : Method
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 44
File Name   : test1.ring
Function Name : mymethod
Method or Function : Method
==========================================
Message from mymethod
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Return
Line Number : 9
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Before C Function
Line Number : 9
File Name   : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 9
File Name   : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Before C Function
Line Number : 9
File Name   : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 9
File Name   : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 11
File Name   : test1.ring
Function Name :
Method or Function : Command
==========================================

トレースライブラリとインタラクティブデバッガ

Ring 1.5 にはトレースライブラリとインタラクティブデバッガがあります。

このライブラリはイベントのトレース、プログラムを一行ずつ実行、 エラー発生またはブレークポイントに到達したときインタラクティブデバッガを開くことができます。

用例:

この用例はブレークポイントをインタラクティブデバッガで開きます!

load "tracelib.ring"

test1()

func test1
        x = 10
        see :test1 + nl
        t = 12
        BreakPoint()
        see "After breakpoint!" +nl
        see "t = " + t + nl
        see "End of program!" + nl

スクリーンショット:

ブレークポイントに関してはインタラクティブデバッガがあります!

インタラクティブデバッガ

変数の値を表示できます。

インタラクティブデバッガ

変数の値を変更後に実行を継続できます。

インタラクティブデバッガ

実行結果ウィンドウでもインタラクティブデバッガを実行できます。

インタラクティブデバッガ

シンタックスの柔軟性を向上

クラス、パッケージ、関数で括弧 { } を使用するには

用例:

load "stdlib.ring"

import mypackage

new myclass {
        myfunc()
}

package mypackage
{
        class myclass
        {
                func myfunc
                {
                        print("Hello, World!\n")
                }
        }
}

クラス、パッケージ、関数の後に‘end’キーワードを使用するには

用例:

import mypackage

new myclass {
        myfunc()
}

package mypackage
        class myclass
                def myfunc
                        put "Hello, World!"
                end
        end
end

クラス、パッケージ、関数の後に‘endpackage’/’endclass’/’endfunc’キーワードを使用するには

用例:

import mypackage

new myclass { myfunc() }

package mypackage
        class myclass
                func myfunc
                        see "welcome"  + nl
                endfunc
        endclass
endpackage

型ヒントライブラリ

Ring 1.5 から型ヒントライブラリがあります。

このライブラリにより、ソースコードへ型情報を追加できます。 このようなツールで非常に便利です。

  • コードエディタ
  • 静的解析

用例:

load "typehints.ring"

see sum(3,4) + nl ;
see sayHello("Mahmoud");

int func sum(int x,int y) {
        return x+y ;
}

string func sayHello(string name) {
        return "Hello " + name ;
}

ライブラリは非常に強力であり、自動的にユーザ型 (クラス) へ対応します!

用例:

load "typehints.ring"

import mypackage

test()  { main([:one,:two,:three]) }

myclass func test() {
        see "Testing User Types!" + nl
        return new myclass
}

package mypackage {
        public class myclass {
                public static void func main(list args) {
                        see "welcome" + nl
                        see args
                }
        }
}

また、コードの内側で型を使用することもできます (関数プロトタイプだけに限定されません)。

用例:

load "typehints.ring"

int     sum = sum(3,4)
string  msg = sayHello("Mahmoud")

see "Sum = " + sum + nl + msg + nl


int func sum(int x,int y) {
        return x+y ;
}

string func sayHello(string name) {
        return "Hello " + name ;
}

規則:

  • 関数プロトタイプ : 型を使用するには、引数の前後を ‘(‘ と ‘)’ で必ず囲んでください。
  • 関数のコード : 型を使用するには、必ず変数の値を設定してください (代入)。

注釈

Ring は動的言語であり、コンパイラによる型検査は行われません。

品質の改善

日々の実務プロジェクトで Ring を利用した成果により

Ring 1.5 では、安定性と生産性も向上しました!

明確な目標と実用性で求められるものを機能を追加していきます。

また、取扱説明書の改訂も行いました。

Ring 1.5.1 での変更点は?

  • 取扱説明書の改訂
  • StdLib - Factorial() 関数の更新
  • Ring 仮想計算機 - クラス範囲でスタックの消去処理に関するコードの改善。
  • サンプル : 3D Cube (OpenGL) + GameLib (RingAllegro) を使用したテクスチャ画像

ソースコード:

load "gamelib.ring"
load "opengl21lib.ring"

func main

        new GraphicsApp {
                start()
        }


class GraphicsApp from GraphicsAppBase

        TITLE = "Ring Cube"

        bitmap texture

        xrot = 0.0
        yrot = 0.0
        zrot = 0.0

        func loadresources

                bitmap = al_load_bitmap("ring.bmp")
                texture = al_get_opengl_texture(bitmap)

        func destroyResources

                al_destroy_bitmap(bitmap)

        func drawScene

                w = 800 h = 600
                ratio =  w / h

                glViewport(0, 0, w, h)
                glMatrixMode(GL_PROJECTION)
                glLoadIdentity()

                gluPerspective(45,ratio,1,100)
                glMatrixMode(GL_MODELVIEW)
                glLoadIdentity()

                glEnable(GL_TEXTURE_2D)
                glShadeModel(GL_SMOOTH)
                glClearColor(0.0, 0.0, 0.0, 0.5)
                glClearDepth(1.0)
                glEnable(GL_DEPTH_TEST)
                glEnable(GL_CULL_FACE)
                glDepthFunc(GL_LEQUAL)
                glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
                glLoadIdentity();
                glTranslatef(0.0,0.0,-5.0);

                glRotatef(xrot,1.0,0.0,0.0);
                glRotatef(yrot,0.0,1.0,0.0);
                glRotatef(zrot,0.0,0.0,1.0);

                glBindTexture(GL_TEXTURE_2D, texture)

                glBegin(GL_QUADS)
                        // 前面
                        glTexCoord2f(0.0, 0.0) glVertex3f(-1.0, -1.0,  1.0)
                        glTexCoord2f(1.0, 0.0) glVertex3f( 1.0, -1.0,  1.0)
                        glTexCoord2f(1.0, 1.0) glVertex3f( 1.0,  1.0,  1.0)
                        glTexCoord2f(0.0, 1.0) glVertex3f(-1.0,  1.0,  1.0)
                        // 背面
                        glTexCoord2f(1.0, 0.0) glVertex3f(-1.0, -1.0, -1.0)
                        glTexCoord2f(1.0, 1.0) glVertex3f(-1.0,  1.0, -1.0)
                        glTexCoord2f(0.0, 1.0) glVertex3f( 1.0,  1.0, -1.0)
                        glTexCoord2f(0.0, 0.0) glVertex3f( 1.0, -1.0, -1.0)
                        // 上面
                        glTexCoord2f(0.0, 1.0) glVertex3f(-1.0,  1.0, -1.0)
                        glTexCoord2f(0.0, 0.0) glVertex3f(-1.0,  1.0,  1.0)
                        glTexCoord2f(1.0, 0.0) glVertex3f( 1.0,  1.0,  1.0)
                        glTexCoord2f(1.0, 1.0) glVertex3f( 1.0,  1.0, -1.0)
                        // 下面
                        glTexCoord2f(1.0, 1.0) glVertex3f(-1.0, -1.0, -1.0)
                        glTexCoord2f(0.0, 1.0) glVertex3f( 1.0, -1.0, -1.0)
                        glTexCoord2f(0.0, 0.0) glVertex3f( 1.0, -1.0,  1.0)
                        glTexCoord2f(1.0, 0.0) glVertex3f(-1.0, -1.0,  1.0)
                        // 右面
                        glTexCoord2f(1.0, 0.0) glVertex3f( 1.0, -1.0, -1.0)
                        glTexCoord2f(1.0, 1.0) glVertex3f( 1.0,  1.0, -1.0)
                        glTexCoord2f(0.0, 1.0) glVertex3f( 1.0,  1.0,  1.0)
                        glTexCoord2f(0.0, 0.0) glVertex3f( 1.0, -1.0,  1.0)
                        // 左面
                        glTexCoord2f(0.0, 0.0) glVertex3f(-1.0, -1.0, -1.0)
                        glTexCoord2f(1.0, 0.0) glVertex3f(-1.0, -1.0,  1.0)
                        glTexCoord2f(1.0, 1.0) glVertex3f(-1.0,  1.0,  1.0)
                        glTexCoord2f(0.0, 1.0) glVertex3f(-1.0,  1.0, -1.0)
                glEnd()

                xrot += 0.3
                yrot += 0.2
                zrot += 0.4


class GraphicsAppBase

        display event_queue ev timeout
        timer  redraw   = true

        FPS             = 60

        SCREEN_W        = 800
        SCREEN_H        = 600

        KEY_UP          = 1
        KEY_DOWN        = 2
        KEY_LEFT        = 3
        KEY_RIGHT       = 4

        Key = [false,false,false,false]

        TITLE = "Graphics Application"

        func start

                SetUp()
                loadResources()
                eventsLoop()
                destroy()

        func setup

                al_init()
                al_init_image_addon()
                al_set_new_display_flags(ALLEGRO_OPENGL)
                display = al_create_display(SCREEN_W,SCREEN_H)
                al_set_Window_title(display,TITLE)
                al_clear_to_color(al_map_rgb(0,0,0))
                event_queue = al_create_event_queue()
                al_register_event_source(event_queue,
                        al_get_display_event_source(display))
                ev = al_new_allegro_event()
                timeout = al_new_allegro_timeout()
                al_init_timeout(timeout, 0.06)
                timer = al_create_timer(1.0 / FPS)
                al_register_event_source(event_queue,
                        al_get_timer_event_source(timer))
                al_start_timer(timer)
                al_install_mouse()
                al_register_event_source(event_queue,
                        al_get_mouse_event_source())
                al_install_keyboard()
                al_register_event_source(event_queue,
                        al_get_keyboard_event_source())

        func eventsLoop

                while true
                        al_wait_for_event_until(event_queue, ev, timeout)
                        switch al_get_allegro_event_type(ev)
                        on ALLEGRO_EVENT_DISPLAY_CLOSE
                                exit
                        on ALLEGRO_EVENT_TIMER
                                redraw = true
                        on ALLEGRO_EVENT_MOUSE_AXES
                                mouse_x = al_get_allegro_event_mouse_x(ev)
                                mouse_y = al_get_allegro_event_mouse_y(ev)
                        on ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY
                                mouse_x = al_get_allegro_event_mouse_x(ev)
                                mouse_y = al_get_allegro_event_mouse_y(ev)
                        on ALLEGRO_EVENT_MOUSE_BUTTON_UP
                                exit
                        on ALLEGRO_EVENT_KEY_DOWN
                                switch al_get_allegro_event_keyboard_keycode(ev)
                                        on ALLEGRO_KEY_UP
                                                key[KEY_UP] = true
                                        on ALLEGRO_KEY_DOWN
                                                key[KEY_DOWN] = true
                                        on ALLEGRO_KEY_LEFT
                                                key[KEY_LEFT] = true
                                        on ALLEGRO_KEY_RIGHT
                                                key[KEY_RIGHT] = true
                                off
                        on ALLEGRO_EVENT_KEY_UP
                                switch al_get_allegro_event_keyboard_keycode(ev)
                                        on ALLEGRO_KEY_UP
                                                key[KEY_UP] = false
                                        on ALLEGRO_KEY_DOWN
                                                key[KEY_DOWN] = false
                                        on ALLEGRO_KEY_LEFT
                                                key[KEY_LEFT] = false
                                        on ALLEGRO_KEY_RIGHT
                                                key[KEY_RIGHT] = false
                                        on ALLEGRO_KEY_ESCAPE
                                                exit
                                off
                        off
                        if redraw and al_is_event_queue_empty(event_queue)
                                redraw = false
                                drawScene()
                                al_flip_display()
                        ok
                        callgc()
                end

        func destroy

                destroyResources()
                al_destroy_timer(timer)
                al_destroy_allegro_event(ev)
                al_destroy_allegro_timeout(timeout)
                al_destroy_event_queue(event_queue)
                al_destroy_display(display)

        func loadresources

        func drawScene

        func destroyResources

スクリーンショット:

Ring Cube

Ring 1.5.2 での変更点は?

  • 取扱説明書 - “アプリケーション開発期間の短縮” の章を更新しました。
  • Ring ノートパッド - 全てのプラットフォームで実行結果ウィンドウへプログラムの実行結果を表示するようになりました。
  • フォームデザイナー - Help メニュー - コンソールウィンドウを表示せずに CHM/PDF ファイルを開けるようになりました。
  • フォームデザイナー - マウスをすばやく動かしたときに Resize/Move イベントの応答性を改善
  • フォームデザイナー - New/Open/Save As で Controller クラスを Ring ノートパッドで開くようにしました。
  • フォームデザイナー - ファイルメニューへ “フォームを閉じる” オプションを追加。
  • Ring ノートパッド - 実行に、現在のファイル (開いているフォームも) 自動的に保存するようになりました。
  • GetQuotesHistory アプリケーション - MacOS X および Qt 5.2 で動作するために更新
  • Calculator アプリケーション - 様々な機能を搭載するために更新しました!
  • Ring VM - 環境エラーの分類 (この章をご確認ください : 言語リファレンス)
  • RingQt - イベント実行の高速化のために QAllEvents へ新しいメソッドを追加
  • RingQt - スタイル「フュージョン : 黒」 - 無効なコントロールに最適な配色
  • スクリプト - Fedora Linux での Ring ビルド用 (この章をご確認ください : ソースコードからのビルド方法)

スクリーンショット:

Ring (Fedora 1 で実行)

Ring 1.5.3 での変更点は?

  • フォームデザイナー : 再びフォームを開くことを可能にするために、アクションが閉じられると Ring ノートパッドへ通知するようになりました。
  • フォームデザイナー : Ring ノートパッドで Controller クラスを開くときにアクションを保存するようになりました。
  • フォームデザイナー : CTRL キーを使用して複数のコントロールを選択時に現在のコントロールを保持するようになりました。
  • フォームデザイナー : Ring ノートパッドでの使用時に素敵な背景色に対応しました (スタイル - モダン : 黒)
  • RingOpenSSL : OpenSSL 1.1 など新しいバージョンへ対応するために更新しました。
  • ビルドスクリプト : Fedora 26 (64bit) での動作に対応するために更新
  • OpenGL : 新しいサンプル - 複数の立方体 (samples/3D/manycubes)

スクリーンショット:

複数の立方体
  • RingQt : QDateTime クラスの追加
  • RingQt : QMenu および QCursor クラスへ新しいメソッドを追加

用例:

load "guilib.ring"

new qApp {
        win = new qwidget() {
                setwindowtitle("Context Menu")
                resize(400,400)
                myfilter = new qAllEvents(win) {
                        setContextmenuEvent("mymenu()")
                }
                installeventfilter(myfilter)
                show()
        }
        exec()
}


func mymenu

        new qMenu(win) {
                oAction = new qAction(win) {
                        settext("new")
                        SetCLickevent("See :New")
                }
                addaction(oAction)
                oAction = new qAction(win) {
                        settext("open")
                        SetCLickevent("See :Open")
                }
                addaction(oAction)
                oAction = new qAction(win) {
                        settext("save")
                        SetCLickevent("See :Save")
                }
                addaction(oAction)
                oAction = new qAction(win) {
                        settext("close")
                        SetCLickevent("See :Close")
                }
                addaction(oAction)
                oCursor  = new qCursor()
                exec(oCursor.pos())
        }

コンパイラ : 数値内で _ の使用に対応

用例:

x = 1_000_000
see type(x)+nl
see x+1+nl

実行結果:

NUMBER
100000001

コンパイラ : 数値の後に f の使用に対応

用例:

x = 19.99f
see type(x) + nl

実行結果:

NUMBER

Google API Shortener アプリケーション

スクリーンショット:

URLShortener - スクリーンショット 1

TicTacToe 3D ゲーム

スクリーンショット:

TicTacToe 3D ゲーム

Ring 1.5.4 での変更点は?

  • CalmoSoft Fifteen Puzzle ゲーム 3D

  • Ring ノートパッド - 新しいスタイル

  • Ring ノートパッド - ツールバーのスタイルを改善

  • Ring ノートパッド - View モード

  • Ring ノートパッド - QPlainTextEdit - スクロールバーの背景色の設定を行わないようにしました。

  • Ring ノートパッド - スタイル - フュージョン (白) - コメントに銀色を使用

  • Ring ノートパッド - Tab と Shift-Tab - 複数行インデント

  • フォームデザイナー - ツールバーのスタイルを改善

  • フォームデザイナー - ウィンドウフラグとメニュバーデザイナー用の素敵な背景色

  • フォームデザイナー - コントロールのデフォルト背景色

  • RingQt - QWidget クラスへgrab() および windowHandle() メソッドを追加

  • RingQt - QPixmap クラスへ新しいメソッドを追加

  • RingQt - クラスの追加:
    • QScreen
    • QWindow
    • QGuiApplication
    • QTextBrowser
  • 拡張機能用のコード生成器 - Nonew オプション - 親クラスへの対応

  • Ring VM - 内部実装 - 文字列とリストオブジェクトをステートへ渡せるようになりました。

  • Ring VM - ガベージコレクター - 小規模オブジェクトをメモリへプールできるようになりました。

  • Ring VM - ステートの保存と復元に関するコードの改善