2015-11-12 5 views
9

मैं क्लिक-एंड-ड्रैग कार्यक्षमता के साथ एक हास्केल प्रोग्राम लिख रहा हूं, इसलिए प्रत्येक माउस आंदोलन ईवेंट के साथ एक अद्यतन विंडो पर चित्रित हो जाता है। फिलहाल मैंGtk2hs में काहिरा अपडेट प्रस्तुत करने का सही तरीका क्या है?

renderWithDrawable myCanvas update 

का उपयोग कर रहा हूं हालांकि यह बहुत झटकेदार है। मेरी समझ यह है कि मुझे एक अलग ड्रॉबल (एक "सतह"?) बनाने की ज़रूरत है, उसे प्रस्तुत करें, और उसके बाद इसे एक ही ऑपरेशन में स्क्रीन विंडो पर फिसल दें। हालांकि मैं ऐसा करने के सही तरीके से उलझन में हूं।

मुझे drawWindowBeginPaintRegion मिला है, जो झिलमिलाहट को खत्म करने के बारे में बात करता है। हालांकि यह हैडॉक डॉक्स के अनुसार Gtk3 में हटा दिया गया है। तो मुझे यकीन नहीं है कि मुझे इसका उपयोग करना चाहिए, क्योंकि ऐसा लगता है कि इसे बहिष्कृत किया गया है।

मुझे कैरो में renderWithSimilarSurface भी मिला है, जो ऐसा कुछ लगता है।

मुझे यह भी सुनिश्चित नहीं है कि ये फ़ंक्शन renderWithDrawable से संबंधित हैं: क्या मुझे उन्हें उस फ़ंक्शन के अंदर उपयोग करना होगा, या क्या?

ऐसा करने का सही तरीका क्या है?

संपादित

इस काहिरा में एक ज्ञात बात लगती है। मैं यह पता लगाने की कोशिश कर रहा हूं कि हास्केल में इसे कैसे संभाला जाए।

+0

क्या आप एक न्यूनतम आत्मनिर्भर उदाहरण पोस्ट कर सकते हैं? – Cactus

+0

@ कैक्टस, आसानी से नहीं। झिलमिलाहट की समस्या के एक डेमो को फिर से दोहराने के लिए कुछ प्रकार की एनीमेशन या माउस इवेंट हैंडलर की आवश्यकता होगी, इसलिए यह छोटा नहीं होगा। प्लेटफार्म के साथ झिलमिलाहट की डिग्री भी भिन्न होती है। इसके बजाय मैं अन्य भाषाओं में इस मुद्दे पर चर्चा के लिए पॉइंटर्स के साथ पोस्ट अपडेट करूंगा।एक पिक्समैप पर आरेखण और फिर स्क्रीन पर इसे मारना अन्य भाषाओं में एक मानक बात प्रतीत होता है, इसलिए मैं उम्मीद कर रहा था कि हास्केल में ऐसा करने का एक कैननिक तरीका था। –

+2

आप 'क्लिप' फ़ंक्शन को देखना चाहते हैं। यह आपको केवल वही चीज़ों को दोबारा करने की अनुमति देगा जो आपको चाहिए (आपके मामले में, आपके ड्रैग किए गए ऑब्जेक्ट की प्रारंभिक आयताकार (पुरानी स्थिति) और इसकी नई आयताकार (नई स्थिति))। – antoyo

उत्तर

4

यह करने के लिए सही तरीके से सुनिश्चित करें कि आपके सभी ड्राइंग आता भीतर घटनाओं का पर्दाफाश से बनाने के लिए है, और ड्रा खिड़की घटना द्वारा प्रदान की पर चल रही है । आप एक क्षेत्र को "गंदा" के रूप में चिह्नित कर सकते हैं और drawWindowInvalidateRect, drawWindowInvalidateRegion, या widgetQueueDraw का उपयोग करके सिंथेटिक एक्सपोज़ ईवेंट ट्रिगर कर सकते हैं।

ड्राइंग पाइपलाइन को स्थापित करने का एक त्वरित काम उदाहरण निम्नानुसार है। इसे कस्टम Viewport प्रकार से उद्धृत किया गया है, जो ड्रैग-एंड-रिलीज ऑपरेशंस पर चिकनी गति के साथ Google-मानचित्र शैली पैनिंग करता है, जिसे मैंने कुछ समय पहले एक साइड-प्रोजेक्ट के लिए बनाया था। इसका समर्थन करने के लिए, इसे माउस गति घटनाओं पर फिर से निकालना होगा, इसलिए यह आपकी वर्णित समस्या के समान उपयोग केस को संबोधित करता है। मैंने महत्वपूर्ण बिट्स को हाइलाइट करने के लिए ... के साथ अप्रासंगिक सामग्री को elided किया है। मैंने अभी पूरी परियोजना को जिथब पर अपलोड कर लिया है, इसलिए आप Viewport के पूर्ण विवरण देखने के लिए रेपो ब्राउज़ कर सकते हैं। (यह साल हालांकि हो गया है, इसलिए वहाँ शायद bitrot का एक उचित सा है - परियोजना सिर्फ निर्माण और आधुनिक GHCs/संकुल के साथ चलने की उम्मीद नहीं है।)

viewportNew :: Viewport -> IO DrawingArea 
viewportNew v = do 
    da <- drawingAreaNew 
    -- ... 
    on da exposeEvent $ exposeViewport posRef (draw v) 
    -- ... 

exposeViewport :: IORef Position -> RegionRenderer -> EventM EExpose Bool 
exposeViewport posRef draw = do 
    dw  <- eventWindow 
    region <- eventRegion >>= liftIO . regionGetRectangles 
    -- ... 
    liftIO . renderWithDrawable dw $ do 
     -- Cairo() action goes here 
     -- can reference region to decide which things to draw 
     draw region 
    return True -- see documentation of exposeEvent for what this means 

इस टेम्पलेट जीटीके के अंतर्निहित का लाभ उठाना चाहिए डबल-बफरिंग में और gtk और gtk3 पैकेज दोनों के साथ काम करें।

+0

धन्यवाद। मैं इसे आज़मा दूंगा, और यदि यह काम करता है तो मैं इसे स्वीकार के रूप में चिह्नित करूंगा। –

संबंधित मुद्दे